Blame view
fs/gfs2/locking.c
5.41 KB
b3b94faa5 [GFS2] The core o... |
1 2 |
/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3a8a9a103 [GFS2] Update cop... |
3 |
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
b3b94faa5 [GFS2] The core o... |
4 5 6 |
* * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions |
e9fc2aa09 [GFS2] Update cop... |
7 |
* of the GNU General Public License version 2. |
b3b94faa5 [GFS2] The core o... |
8 9 10 11 12 13 14 15 16 17 18 |
*/ #include <linux/module.h> #include <linux/init.h> #include <linux/string.h> #include <linux/slab.h> #include <linux/wait.h> #include <linux/sched.h> #include <linux/kmod.h> #include <linux/fs.h> #include <linux/delay.h> |
7d308590a [GFS2] Export lm_... |
19 |
#include <linux/lm_interface.h> |
b3b94faa5 [GFS2] The core o... |
20 21 22 |
struct lmh_wrapper { struct list_head lw_list; |
9b47c11d1 [GFS2] Use void *... |
23 |
const struct lm_lockops *lw_ops; |
b3b94faa5 [GFS2] The core o... |
24 |
}; |
048bca223 [GFS2] No lock_no... |
25 26 27 28 29 |
static int nolock_mount(char *table_name, char *host_data, lm_callback_t cb, void *cb_data, unsigned int min_lvb_size, int flags, struct lm_lockstruct *lockstruct, struct kobject *fskobj); |
b3b94faa5 [GFS2] The core o... |
30 31 |
/* List of registered low-level locking protocols. A file system selects one of them by name at mount time, e.g. lock_nolock, lock_dlm. */ |
048bca223 [GFS2] No lock_no... |
32 33 34 35 36 37 38 39 40 |
static const struct lm_lockops nolock_ops = { .lm_proto_name = "lock_nolock", .lm_mount = nolock_mount, }; static struct lmh_wrapper nolock_proto = { .lw_list = LIST_HEAD_INIT(nolock_proto.lw_list), .lw_ops = &nolock_ops, }; |
502999654 [GFS2] Tidy up lo... |
41 42 |
static LIST_HEAD(lmh_list); static DEFINE_MUTEX(lmh_lock); |
b3b94faa5 [GFS2] The core o... |
43 |
|
048bca223 [GFS2] No lock_no... |
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
static int nolock_mount(char *table_name, char *host_data, lm_callback_t cb, void *cb_data, unsigned int min_lvb_size, int flags, struct lm_lockstruct *lockstruct, struct kobject *fskobj) { char *c; unsigned int jid; c = strstr(host_data, "jid="); if (!c) jid = 0; else { c += 4; sscanf(c, "%u", &jid); } lockstruct->ls_jid = jid; lockstruct->ls_first = 1; lockstruct->ls_lvb_size = min_lvb_size; lockstruct->ls_ops = &nolock_ops; lockstruct->ls_flags = LM_LSFLAG_LOCAL; return 0; } |
b3b94faa5 [GFS2] The core o... |
69 |
/** |
2b557f6dc [GFS2] Fix gfs_ p... |
70 |
* gfs2_register_lockproto - Register a low-level locking protocol |
b3b94faa5 [GFS2] The core o... |
71 72 73 74 |
* @proto: the protocol definition * * Returns: 0 on success, -EXXX on failure */ |
9b47c11d1 [GFS2] Use void *... |
75 |
int gfs2_register_lockproto(const struct lm_lockops *proto) |
b3b94faa5 [GFS2] The core o... |
76 77 |
{ struct lmh_wrapper *lw; |
a74604bee [GFS2] sem -> mut... |
78 |
mutex_lock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
79 80 81 |
list_for_each_entry(lw, &lmh_list, lw_list) { if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) { |
a74604bee [GFS2] sem -> mut... |
82 |
mutex_unlock(&lmh_lock); |
d92a8d480 [GFS2] Audit prin... |
83 84 |
printk(KERN_INFO "GFS2: protocol %s already exists ", |
b3b94faa5 [GFS2] The core o... |
85 86 87 88 |
proto->lm_proto_name); return -EEXIST; } } |
d92a8d480 [GFS2] Audit prin... |
89 |
lw = kzalloc(sizeof(struct lmh_wrapper), GFP_KERNEL); |
b3b94faa5 [GFS2] The core o... |
90 |
if (!lw) { |
a74604bee [GFS2] sem -> mut... |
91 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
92 93 |
return -ENOMEM; } |
b3b94faa5 [GFS2] The core o... |
94 95 96 |
lw->lw_ops = proto; list_add(&lw->lw_list, &lmh_list); |
a74604bee [GFS2] sem -> mut... |
97 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
98 99 100 101 102 |
return 0; } /** |
2b557f6dc [GFS2] Fix gfs_ p... |
103 |
* gfs2_unregister_lockproto - Unregister a low-level locking protocol |
b3b94faa5 [GFS2] The core o... |
104 105 106 |
* @proto: the protocol definition * */ |
9b47c11d1 [GFS2] Use void *... |
107 |
void gfs2_unregister_lockproto(const struct lm_lockops *proto) |
b3b94faa5 [GFS2] The core o... |
108 109 |
{ struct lmh_wrapper *lw; |
a74604bee [GFS2] sem -> mut... |
110 |
mutex_lock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
111 112 113 114 |
list_for_each_entry(lw, &lmh_list, lw_list) { if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) { list_del(&lw->lw_list); |
a74604bee [GFS2] sem -> mut... |
115 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
116 117 118 119 |
kfree(lw); return; } } |
a74604bee [GFS2] sem -> mut... |
120 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
121 |
|
d92a8d480 [GFS2] Audit prin... |
122 123 |
printk(KERN_WARNING "GFS2: can't unregister lock protocol %s ", |
b3b94faa5 [GFS2] The core o... |
124 125 126 127 128 129 130 131 132 |
proto->lm_proto_name); } /** * gfs2_mount_lockproto - Mount a lock protocol * @proto_name - the name of the protocol * @table_name - the name of the lock space * @host_data - data specific to this host * @cb - the callback to the code using the lock module |
1c089c325 [GFS2] Remove one... |
133 |
* @sdp - The GFS2 superblock |
b3b94faa5 [GFS2] The core o... |
134 135 136 137 138 139 140 141 |
* @min_lvb_size - the mininum LVB size that the caller can deal with * @flags - LM_MFLAG_* * @lockstruct - a structure returned describing the mount * * Returns: 0 on success, -EXXX on failure */ int gfs2_mount_lockproto(char *proto_name, char *table_name, char *host_data, |
9b47c11d1 [GFS2] Use void *... |
142 |
lm_callback_t cb, void *cb_data, |
b3b94faa5 [GFS2] The core o... |
143 144 145 146 147 148 149 |
unsigned int min_lvb_size, int flags, struct lm_lockstruct *lockstruct, struct kobject *fskobj) { struct lmh_wrapper *lw = NULL; int try = 0; int error, found; |
048bca223 [GFS2] No lock_no... |
150 |
|
2b557f6dc [GFS2] Fix gfs_ p... |
151 |
retry: |
a74604bee [GFS2] sem -> mut... |
152 |
mutex_lock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
153 |
|
048bca223 [GFS2] No lock_no... |
154 |
if (list_empty(&nolock_proto.lw_list)) |
802747372 [GFS2] Fix orderi... |
155 |
list_add(&nolock_proto.lw_list, &lmh_list); |
048bca223 [GFS2] No lock_no... |
156 |
|
b3b94faa5 [GFS2] The core o... |
157 158 159 160 161 162 163 164 165 166 167 |
found = 0; list_for_each_entry(lw, &lmh_list, lw_list) { if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) { found = 1; break; } } if (!found) { if (!try && capable(CAP_SYS_MODULE)) { try = 1; |
a74604bee [GFS2] sem -> mut... |
168 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
169 170 171 |
request_module(proto_name); goto retry; } |
d92a8d480 [GFS2] Audit prin... |
172 173 |
printk(KERN_INFO "GFS2: can't find protocol %s ", proto_name); |
b3b94faa5 [GFS2] The core o... |
174 175 176 |
error = -ENOENT; goto out; } |
048bca223 [GFS2] No lock_no... |
177 178 |
if (lw->lw_ops->lm_owner && !try_module_get(lw->lw_ops->lm_owner)) { |
b3b94faa5 [GFS2] The core o... |
179 |
try = 0; |
a74604bee [GFS2] sem -> mut... |
180 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
181 182 183 |
msleep(1000); goto retry; } |
9b47c11d1 [GFS2] Use void *... |
184 |
error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data, |
b3b94faa5 [GFS2] The core o... |
185 186 187 |
min_lvb_size, flags, lockstruct, fskobj); if (error) module_put(lw->lw_ops->lm_owner); |
2b557f6dc [GFS2] Fix gfs_ p... |
188 |
out: |
a74604bee [GFS2] sem -> mut... |
189 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
190 191 192 193 194 |
return error; } void gfs2_unmount_lockproto(struct lm_lockstruct *lockstruct) { |
a74604bee [GFS2] sem -> mut... |
195 |
mutex_lock(&lmh_lock); |
048bca223 [GFS2] No lock_no... |
196 197 |
if (lockstruct->ls_ops->lm_unmount) lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace); |
b3b94faa5 [GFS2] The core o... |
198 199 |
if (lockstruct->ls_ops->lm_owner) module_put(lockstruct->ls_ops->lm_owner); |
a74604bee [GFS2] sem -> mut... |
200 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
201 202 203 204 205 206 207 208 209 210 |
} /** * gfs2_withdraw_lockproto - abnormally unmount a lock module * @lockstruct: the lockstruct passed into mount * */ void gfs2_withdraw_lockproto(struct lm_lockstruct *lockstruct) { |
a74604bee [GFS2] sem -> mut... |
211 |
mutex_lock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
212 213 214 |
lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace); if (lockstruct->ls_ops->lm_owner) module_put(lockstruct->ls_ops->lm_owner); |
a74604bee [GFS2] sem -> mut... |
215 |
mutex_unlock(&lmh_lock); |
b3b94faa5 [GFS2] The core o... |
216 |
} |
2b557f6dc [GFS2] Fix gfs_ p... |
217 218 |
EXPORT_SYMBOL_GPL(gfs2_register_lockproto); EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto); |
b3b94faa5 [GFS2] The core o... |
219 |