diff options
Diffstat (limited to 'fs/gfs2/locking/dlm')
-rw-r--r-- | fs/gfs2/locking/dlm/Makefile | 2 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/lock.c | 104 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/lock_dlm.h | 191 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/main.c | 34 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/mount.c | 189 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/plock.c | 297 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/sysfs.c | 203 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/thread.c | 65 |
8 files changed, 740 insertions, 345 deletions
diff --git a/fs/gfs2/locking/dlm/Makefile b/fs/gfs2/locking/dlm/Makefile index d3bca02f7b3e..a9733ff80371 100644 --- a/fs/gfs2/locking/dlm/Makefile +++ b/fs/gfs2/locking/dlm/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_GFS2_FS) += lock_dlm.o | 1 | obj-$(CONFIG_GFS2_FS) += lock_dlm.o |
2 | lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o | 2 | lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o |
3 | 3 | ||
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c index daf59d504e29..d799865b64a4 100644 --- a/fs/gfs2/locking/dlm/lock.c +++ b/fs/gfs2/locking/dlm/lock.c | |||
@@ -1,15 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | ******************************************************************************* | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | ** | 3 | * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | * |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | ** | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | * of the GNU General Public License v.2. |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | */ |
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | 9 | ||
14 | #include "lock_dlm.h" | 10 | #include "lock_dlm.h" |
15 | 11 | ||
@@ -38,7 +34,7 @@ static inline void gdlm_bast(void *astarg, int mode) | |||
38 | struct gdlm_ls *ls = lp->ls; | 34 | struct gdlm_ls *ls = lp->ls; |
39 | 35 | ||
40 | if (!mode) { | 36 | if (!mode) { |
41 | printk("lock_dlm: bast mode zero %x,%"PRIx64"\n", | 37 | printk("lock_dlm: bast mode zero %x,%llx\n", |
42 | lp->lockname.ln_type, lp->lockname.ln_number); | 38 | lp->lockname.ln_type, lp->lockname.ln_number); |
43 | return; | 39 | return; |
44 | } | 40 | } |
@@ -75,9 +71,9 @@ static int16_t make_mode(int16_t lmstate) | |||
75 | return DLM_LOCK_CW; | 71 | return DLM_LOCK_CW; |
76 | case LM_ST_SHARED: | 72 | case LM_ST_SHARED: |
77 | return DLM_LOCK_PR; | 73 | return DLM_LOCK_PR; |
78 | default: | ||
79 | GDLM_ASSERT(0, printk("unknown LM state %d\n", lmstate);); | ||
80 | } | 74 | } |
75 | gdlm_assert(0, "unknown LM state %d", lmstate); | ||
76 | return -1; | ||
81 | } | 77 | } |
82 | 78 | ||
83 | /* convert dlm lock-mode to gfs lock-state */ | 79 | /* convert dlm lock-mode to gfs lock-state */ |
@@ -94,9 +90,9 @@ int16_t gdlm_make_lmstate(int16_t dlmmode) | |||
94 | return LM_ST_DEFERRED; | 90 | return LM_ST_DEFERRED; |
95 | case DLM_LOCK_PR: | 91 | case DLM_LOCK_PR: |
96 | return LM_ST_SHARED; | 92 | return LM_ST_SHARED; |
97 | default: | ||
98 | GDLM_ASSERT(0, printk("unknown DLM mode %d\n", dlmmode);); | ||
99 | } | 93 | } |
94 | gdlm_assert(0, "unknown DLM mode %d", dlmmode); | ||
95 | return -1; | ||
100 | } | 96 | } |
101 | 97 | ||
102 | /* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and | 98 | /* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and |
@@ -106,7 +102,7 @@ static void check_cur_state(struct gdlm_lock *lp, unsigned int cur_state) | |||
106 | { | 102 | { |
107 | int16_t cur = make_mode(cur_state); | 103 | int16_t cur = make_mode(cur_state); |
108 | if (lp->cur != DLM_LOCK_IV) | 104 | if (lp->cur != DLM_LOCK_IV) |
109 | GDLM_ASSERT(lp->cur == cur, printk("%d, %d\n", lp->cur, cur);); | 105 | gdlm_assert(lp->cur == cur, "%d, %d", lp->cur, cur); |
110 | } | 106 | } |
111 | 107 | ||
112 | static inline unsigned int make_flags(struct gdlm_lock *lp, | 108 | static inline unsigned int make_flags(struct gdlm_lock *lp, |
@@ -157,7 +153,7 @@ static inline unsigned int make_flags(struct gdlm_lock *lp, | |||
157 | static inline void make_strname(struct lm_lockname *lockname, | 153 | static inline void make_strname(struct lm_lockname *lockname, |
158 | struct gdlm_strname *str) | 154 | struct gdlm_strname *str) |
159 | { | 155 | { |
160 | sprintf(str->name, "%8x%16"PRIx64, lockname->ln_type, | 156 | sprintf(str->name, "%8x%16llx", lockname->ln_type, |
161 | lockname->ln_number); | 157 | lockname->ln_number); |
162 | str->namelen = GDLM_STRNAME_BYTES; | 158 | str->namelen = GDLM_STRNAME_BYTES; |
163 | } | 159 | } |
@@ -167,11 +163,10 @@ int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, | |||
167 | { | 163 | { |
168 | struct gdlm_lock *lp; | 164 | struct gdlm_lock *lp; |
169 | 165 | ||
170 | lp = kmalloc(sizeof(struct gdlm_lock), GFP_KERNEL); | 166 | lp = kzalloc(sizeof(struct gdlm_lock), GFP_KERNEL); |
171 | if (!lp) | 167 | if (!lp) |
172 | return -ENOMEM; | 168 | return -ENOMEM; |
173 | 169 | ||
174 | memset(lp, 0, sizeof(struct gdlm_lock)); | ||
175 | lp->lockname = *name; | 170 | lp->lockname = *name; |
176 | lp->ls = ls; | 171 | lp->ls = ls; |
177 | lp->cur = DLM_LOCK_IV; | 172 | lp->cur = DLM_LOCK_IV; |
@@ -202,7 +197,8 @@ void gdlm_delete_lp(struct gdlm_lock *lp) | |||
202 | list_del_init(&lp->blist); | 197 | list_del_init(&lp->blist); |
203 | if (!list_empty(&lp->delay_list)) | 198 | if (!list_empty(&lp->delay_list)) |
204 | list_del_init(&lp->delay_list); | 199 | list_del_init(&lp->delay_list); |
205 | GDLM_ASSERT(!list_empty(&lp->all_list),); | 200 | gdlm_assert(!list_empty(&lp->all_list), |
201 | "%x,%llx", lp->lockname.ln_type, lp->lockname.ln_number); | ||
206 | list_del_init(&lp->all_list); | 202 | list_del_init(&lp->all_list); |
207 | ls->all_locks_count--; | 203 | ls->all_locks_count--; |
208 | spin_unlock(&ls->async_lock); | 204 | spin_unlock(&ls->async_lock); |
@@ -227,7 +223,7 @@ void gdlm_put_lock(lm_lock_t *lock) | |||
227 | gdlm_delete_lp((struct gdlm_lock *) lock); | 223 | gdlm_delete_lp((struct gdlm_lock *) lock); |
228 | } | 224 | } |
229 | 225 | ||
230 | void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range) | 226 | unsigned int gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range) |
231 | { | 227 | { |
232 | struct gdlm_ls *ls = lp->ls; | 228 | struct gdlm_ls *ls = lp->ls; |
233 | struct gdlm_strname str; | 229 | struct gdlm_strname str; |
@@ -242,7 +238,7 @@ void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range) | |||
242 | if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && | 238 | if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && |
243 | !test_bit(LFL_NOBLOCK, &lp->flags) && lp->req != DLM_LOCK_NL) { | 239 | !test_bit(LFL_NOBLOCK, &lp->flags) && lp->req != DLM_LOCK_NL) { |
244 | gdlm_queue_delayed(lp); | 240 | gdlm_queue_delayed(lp); |
245 | return; | 241 | return LM_OUT_ASYNC; |
246 | } | 242 | } |
247 | 243 | ||
248 | /* | 244 | /* |
@@ -256,7 +252,7 @@ void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range) | |||
256 | 252 | ||
257 | set_bit(LFL_ACTIVE, &lp->flags); | 253 | set_bit(LFL_ACTIVE, &lp->flags); |
258 | 254 | ||
259 | log_debug("lk %x,%"PRIx64" id %x %d,%d %x", lp->lockname.ln_type, | 255 | log_debug("lk %x,%llx id %x %d,%d %x", lp->lockname.ln_type, |
260 | lp->lockname.ln_number, lp->lksb.sb_lkid, | 256 | lp->lockname.ln_number, lp->lksb.sb_lkid, |
261 | lp->cur, lp->req, lp->lkf); | 257 | lp->cur, lp->req, lp->lkf); |
262 | 258 | ||
@@ -270,15 +266,19 @@ void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range) | |||
270 | error = 0; | 266 | error = 0; |
271 | } | 267 | } |
272 | 268 | ||
273 | GDLM_ASSERT(!error, | 269 | if (error) { |
274 | printk("%s: num=%x,%"PRIx64" err=%d cur=%d req=%d lkf=%x\n", | 270 | log_debug("%s: gdlm_lock %x,%llx err=%d cur=%d req=%d lkf=%x " |
275 | ls->fsname, lp->lockname.ln_type, | 271 | "flags=%lx", ls->fsname, lp->lockname.ln_type, |
276 | lp->lockname.ln_number, error, lp->cur, lp->req, | 272 | lp->lockname.ln_number, error, lp->cur, lp->req, |
277 | lp->lkf);); | 273 | lp->lkf, lp->flags); |
274 | return LM_OUT_ERROR; | ||
275 | } | ||
276 | return LM_OUT_ASYNC; | ||
278 | } | 277 | } |
279 | 278 | ||
280 | void gdlm_do_unlock(struct gdlm_lock *lp) | 279 | unsigned int gdlm_do_unlock(struct gdlm_lock *lp) |
281 | { | 280 | { |
281 | struct gdlm_ls *ls = lp->ls; | ||
282 | unsigned int lkf = 0; | 282 | unsigned int lkf = 0; |
283 | int error; | 283 | int error; |
284 | 284 | ||
@@ -288,16 +288,19 @@ void gdlm_do_unlock(struct gdlm_lock *lp) | |||
288 | if (lp->lvb) | 288 | if (lp->lvb) |
289 | lkf = DLM_LKF_VALBLK; | 289 | lkf = DLM_LKF_VALBLK; |
290 | 290 | ||
291 | log_debug("un %x,%"PRIx64" %x %d %x", lp->lockname.ln_type, | 291 | log_debug("un %x,%llx %x %d %x", lp->lockname.ln_type, |
292 | lp->lockname.ln_number, lp->lksb.sb_lkid, lp->cur, lkf); | 292 | lp->lockname.ln_number, lp->lksb.sb_lkid, lp->cur, lkf); |
293 | 293 | ||
294 | error = dlm_unlock(lp->ls->dlm_lockspace, lp->lksb.sb_lkid, lkf, | 294 | error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, lkf, NULL, lp); |
295 | NULL, lp); | ||
296 | 295 | ||
297 | GDLM_ASSERT(!error, | 296 | if (error) { |
298 | printk("%s: error=%d num=%x,%"PRIx64" lkf=%x flags=%lx\n", | 297 | log_debug("%s: gdlm_unlock %x,%llx err=%d cur=%d req=%d lkf=%x " |
299 | lp->ls->fsname, error, lp->lockname.ln_type, | 298 | "flags=%lx", ls->fsname, lp->lockname.ln_type, |
300 | lp->lockname.ln_number, lkf, lp->flags);); | 299 | lp->lockname.ln_number, error, lp->cur, lp->req, |
300 | lp->lkf, lp->flags); | ||
301 | return LM_OUT_ERROR; | ||
302 | } | ||
303 | return LM_OUT_ASYNC; | ||
301 | } | 304 | } |
302 | 305 | ||
303 | unsigned int gdlm_lock(lm_lock_t *lock, unsigned int cur_state, | 306 | unsigned int gdlm_lock(lm_lock_t *lock, unsigned int cur_state, |
@@ -313,8 +316,7 @@ unsigned int gdlm_lock(lm_lock_t *lock, unsigned int cur_state, | |||
313 | lp->req = make_mode(req_state); | 316 | lp->req = make_mode(req_state); |
314 | lp->lkf = make_flags(lp, flags, lp->cur, lp->req); | 317 | lp->lkf = make_flags(lp, flags, lp->cur, lp->req); |
315 | 318 | ||
316 | gdlm_do_lock(lp, NULL); | 319 | return gdlm_do_lock(lp, NULL); |
317 | return LM_OUT_ASYNC; | ||
318 | } | 320 | } |
319 | 321 | ||
320 | unsigned int gdlm_unlock(lm_lock_t *lock, unsigned int cur_state) | 322 | unsigned int gdlm_unlock(lm_lock_t *lock, unsigned int cur_state) |
@@ -324,8 +326,7 @@ unsigned int gdlm_unlock(lm_lock_t *lock, unsigned int cur_state) | |||
324 | clear_bit(LFL_DLM_CANCEL, &lp->flags); | 326 | clear_bit(LFL_DLM_CANCEL, &lp->flags); |
325 | if (lp->cur == DLM_LOCK_IV) | 327 | if (lp->cur == DLM_LOCK_IV) |
326 | return 0; | 328 | return 0; |
327 | gdlm_do_unlock(lp); | 329 | return gdlm_do_unlock(lp); |
328 | return LM_OUT_ASYNC; | ||
329 | } | 330 | } |
330 | 331 | ||
331 | void gdlm_cancel(lm_lock_t *lock) | 332 | void gdlm_cancel(lm_lock_t *lock) |
@@ -337,8 +338,8 @@ void gdlm_cancel(lm_lock_t *lock) | |||
337 | if (test_bit(LFL_DLM_CANCEL, &lp->flags)) | 338 | if (test_bit(LFL_DLM_CANCEL, &lp->flags)) |
338 | return; | 339 | return; |
339 | 340 | ||
340 | log_all("gdlm_cancel %x,%"PRIx64" flags %lx", | 341 | log_info("gdlm_cancel %x,%llx flags %lx", |
341 | lp->lockname.ln_type, lp->lockname.ln_number, lp->flags); | 342 | lp->lockname.ln_type, lp->lockname.ln_number, lp->flags); |
342 | 343 | ||
343 | spin_lock(&ls->async_lock); | 344 | spin_lock(&ls->async_lock); |
344 | if (!list_empty(&lp->delay_list)) { | 345 | if (!list_empty(&lp->delay_list)) { |
@@ -356,9 +357,9 @@ void gdlm_cancel(lm_lock_t *lock) | |||
356 | 357 | ||
357 | if (!test_bit(LFL_ACTIVE, &lp->flags) || | 358 | if (!test_bit(LFL_ACTIVE, &lp->flags) || |
358 | test_bit(LFL_DLM_UNLOCK, &lp->flags)) { | 359 | test_bit(LFL_DLM_UNLOCK, &lp->flags)) { |
359 | log_all("gdlm_cancel skip %x,%"PRIx64" flags %lx", | 360 | log_info("gdlm_cancel skip %x,%llx flags %lx", |
360 | lp->lockname.ln_type, lp->lockname.ln_number, | 361 | lp->lockname.ln_type, lp->lockname.ln_number, |
361 | lp->flags); | 362 | lp->flags); |
362 | return; | 363 | return; |
363 | } | 364 | } |
364 | 365 | ||
@@ -370,8 +371,8 @@ void gdlm_cancel(lm_lock_t *lock) | |||
370 | error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, DLM_LKF_CANCEL, | 371 | error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, DLM_LKF_CANCEL, |
371 | NULL, lp); | 372 | NULL, lp); |
372 | 373 | ||
373 | log_all("gdlm_cancel rv %d %x,%"PRIx64" flags %lx", error, | 374 | log_info("gdlm_cancel rv %d %x,%llx flags %lx", error, |
374 | lp->lockname.ln_type, lp->lockname.ln_number, lp->flags); | 375 | lp->lockname.ln_type, lp->lockname.ln_number, lp->flags); |
375 | 376 | ||
376 | if (error == -EBUSY) | 377 | if (error == -EBUSY) |
377 | clear_bit(LFL_DLM_CANCEL, &lp->flags); | 378 | clear_bit(LFL_DLM_CANCEL, &lp->flags); |
@@ -381,12 +382,10 @@ int gdlm_add_lvb(struct gdlm_lock *lp) | |||
381 | { | 382 | { |
382 | char *lvb; | 383 | char *lvb; |
383 | 384 | ||
384 | lvb = kmalloc(GDLM_LVB_SIZE, GFP_KERNEL); | 385 | lvb = kzalloc(GDLM_LVB_SIZE, GFP_KERNEL); |
385 | if (!lvb) | 386 | if (!lvb) |
386 | return -ENOMEM; | 387 | return -ENOMEM; |
387 | 388 | ||
388 | memset(lvb, 0, GDLM_LVB_SIZE); | ||
389 | |||
390 | lp->lksb.sb_lvbptr = lvb; | 389 | lp->lksb.sb_lvbptr = lvb; |
391 | lp->lvb = lvb; | 390 | lp->lvb = lvb; |
392 | return 0; | 391 | return 0; |
@@ -448,7 +447,8 @@ static void unhold_null_lock(struct gdlm_lock *lp) | |||
448 | { | 447 | { |
449 | struct gdlm_lock *lpn = lp->hold_null; | 448 | struct gdlm_lock *lpn = lp->hold_null; |
450 | 449 | ||
451 | GDLM_ASSERT(lpn,); | 450 | gdlm_assert(lpn, "%x,%llx", |
451 | lp->lockname.ln_type, lp->lockname.ln_number); | ||
452 | lpn->lksb.sb_lvbptr = NULL; | 452 | lpn->lksb.sb_lvbptr = NULL; |
453 | lpn->lvb = NULL; | 453 | lpn->lvb = NULL; |
454 | set_bit(LFL_UNLOCK_DELETE, &lpn->flags); | 454 | set_bit(LFL_UNLOCK_DELETE, &lpn->flags); |
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h new file mode 100644 index 000000000000..fa545f7872e8 --- /dev/null +++ b/fs/gfs2/locking/dlm/lock_dlm.h | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License v.2. | ||
8 | */ | ||
9 | |||
10 | #ifndef LOCK_DLM_DOT_H | ||
11 | #define LOCK_DLM_DOT_H | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/socket.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/kthread.h> | ||
23 | #include <linux/kobject.h> | ||
24 | #include <linux/fcntl.h> | ||
25 | #include <linux/wait.h> | ||
26 | #include <net/sock.h> | ||
27 | |||
28 | #include <linux/dlm.h> | ||
29 | #include "../../lm_interface.h" | ||
30 | |||
31 | /* | ||
32 | * Internally, we prefix things with gdlm_ and GDLM_ (for gfs-dlm) since a | ||
33 | * prefix of lock_dlm_ gets awkward. Externally, GFS refers to this module | ||
34 | * as "lock_dlm". | ||
35 | */ | ||
36 | |||
37 | #define GDLM_STRNAME_BYTES 24 | ||
38 | #define GDLM_LVB_SIZE 32 | ||
39 | #define GDLM_DROP_COUNT 50000 | ||
40 | #define GDLM_DROP_PERIOD 60 | ||
41 | #define GDLM_NAME_LEN 128 | ||
42 | |||
43 | /* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number). | ||
44 | We sprintf these numbers into a 24 byte string of hex values to make them | ||
45 | human-readable (to make debugging simpler.) */ | ||
46 | |||
47 | struct gdlm_strname { | ||
48 | unsigned char name[GDLM_STRNAME_BYTES]; | ||
49 | unsigned short namelen; | ||
50 | }; | ||
51 | |||
52 | enum { | ||
53 | DFL_BLOCK_LOCKS = 0, | ||
54 | DFL_SPECTATOR = 1, | ||
55 | DFL_WITHDRAW = 2, | ||
56 | }; | ||
57 | |||
58 | struct gdlm_ls { | ||
59 | uint32_t id; | ||
60 | int jid; | ||
61 | int first; | ||
62 | int first_done; | ||
63 | unsigned long flags; | ||
64 | struct kobject kobj; | ||
65 | char clustername[GDLM_NAME_LEN]; | ||
66 | char fsname[GDLM_NAME_LEN]; | ||
67 | int fsflags; | ||
68 | dlm_lockspace_t *dlm_lockspace; | ||
69 | lm_callback_t fscb; | ||
70 | lm_fsdata_t *fsdata; | ||
71 | int recover_jid; | ||
72 | int recover_jid_done; | ||
73 | spinlock_t async_lock; | ||
74 | struct list_head complete; | ||
75 | struct list_head blocking; | ||
76 | struct list_head delayed; | ||
77 | struct list_head submit; | ||
78 | struct list_head all_locks; | ||
79 | uint32_t all_locks_count; | ||
80 | wait_queue_head_t wait_control; | ||
81 | struct task_struct *thread1; | ||
82 | struct task_struct *thread2; | ||
83 | wait_queue_head_t thread_wait; | ||
84 | unsigned long drop_time; | ||
85 | int drop_locks_count; | ||
86 | int drop_locks_period; | ||
87 | }; | ||
88 | |||
89 | enum { | ||
90 | LFL_NOBLOCK = 0, | ||
91 | LFL_NOCACHE = 1, | ||
92 | LFL_DLM_UNLOCK = 2, | ||
93 | LFL_DLM_CANCEL = 3, | ||
94 | LFL_SYNC_LVB = 4, | ||
95 | LFL_FORCE_PROMOTE = 5, | ||
96 | LFL_REREQUEST = 6, | ||
97 | LFL_ACTIVE = 7, | ||
98 | LFL_INLOCK = 8, | ||
99 | LFL_CANCEL = 9, | ||
100 | LFL_NOBAST = 10, | ||
101 | LFL_HEADQUE = 11, | ||
102 | LFL_UNLOCK_DELETE = 12, | ||
103 | }; | ||
104 | |||
105 | struct gdlm_lock { | ||
106 | struct gdlm_ls *ls; | ||
107 | struct lm_lockname lockname; | ||
108 | char *lvb; | ||
109 | struct dlm_lksb lksb; | ||
110 | |||
111 | int16_t cur; | ||
112 | int16_t req; | ||
113 | int16_t prev_req; | ||
114 | uint32_t lkf; /* dlm flags DLM_LKF_ */ | ||
115 | unsigned long flags; /* lock_dlm flags LFL_ */ | ||
116 | |||
117 | int bast_mode; /* protected by async_lock */ | ||
118 | struct completion ast_wait; | ||
119 | |||
120 | struct list_head clist; /* complete */ | ||
121 | struct list_head blist; /* blocking */ | ||
122 | struct list_head delay_list; /* delayed */ | ||
123 | struct list_head all_list; /* all locks for the fs */ | ||
124 | struct gdlm_lock *hold_null; /* NL lock for hold_lvb */ | ||
125 | }; | ||
126 | |||
127 | #define gdlm_assert(assertion, fmt, args...) \ | ||
128 | do { \ | ||
129 | if (unlikely(!(assertion))) { \ | ||
130 | printk(KERN_EMERG "lock_dlm: fatal assertion failed \"%s\"\n" \ | ||
131 | "lock_dlm: " fmt "\n", \ | ||
132 | #assertion, ##args); \ | ||
133 | BUG(); \ | ||
134 | } \ | ||
135 | } while (0) | ||
136 | |||
137 | #define log_print(lev, fmt, arg...) printk(lev "lock_dlm: " fmt "\n" , ## arg) | ||
138 | #define log_info(fmt, arg...) log_print(KERN_INFO , fmt , ## arg) | ||
139 | #define log_error(fmt, arg...) log_print(KERN_ERR , fmt , ## arg) | ||
140 | #ifdef LOCK_DLM_LOG_DEBUG | ||
141 | #define log_debug(fmt, arg...) log_print(KERN_DEBUG , fmt , ## arg) | ||
142 | #else | ||
143 | #define log_debug(fmt, arg...) | ||
144 | #endif | ||
145 | |||
146 | /* sysfs.c */ | ||
147 | |||
148 | int gdlm_sysfs_init(void); | ||
149 | void gdlm_sysfs_exit(void); | ||
150 | int gdlm_kobject_setup(struct gdlm_ls *, struct kobject *); | ||
151 | void gdlm_kobject_release(struct gdlm_ls *); | ||
152 | |||
153 | /* thread.c */ | ||
154 | |||
155 | int gdlm_init_threads(struct gdlm_ls *); | ||
156 | void gdlm_release_threads(struct gdlm_ls *); | ||
157 | |||
158 | /* lock.c */ | ||
159 | |||
160 | int16_t gdlm_make_lmstate(int16_t); | ||
161 | void gdlm_queue_delayed(struct gdlm_lock *); | ||
162 | void gdlm_submit_delayed(struct gdlm_ls *); | ||
163 | int gdlm_release_all_locks(struct gdlm_ls *); | ||
164 | int gdlm_create_lp(struct gdlm_ls *, struct lm_lockname *, struct gdlm_lock **); | ||
165 | void gdlm_delete_lp(struct gdlm_lock *); | ||
166 | int gdlm_add_lvb(struct gdlm_lock *); | ||
167 | void gdlm_del_lvb(struct gdlm_lock *); | ||
168 | unsigned int gdlm_do_lock(struct gdlm_lock *, struct dlm_range *); | ||
169 | unsigned int gdlm_do_unlock(struct gdlm_lock *); | ||
170 | |||
171 | int gdlm_get_lock(lm_lockspace_t *, struct lm_lockname *, lm_lock_t **); | ||
172 | void gdlm_put_lock(lm_lock_t *); | ||
173 | unsigned int gdlm_lock(lm_lock_t *, unsigned int, unsigned int, unsigned int); | ||
174 | unsigned int gdlm_unlock(lm_lock_t *, unsigned int); | ||
175 | void gdlm_cancel(lm_lock_t *); | ||
176 | int gdlm_hold_lvb(lm_lock_t *, char **); | ||
177 | void gdlm_unhold_lvb(lm_lock_t *, char *); | ||
178 | void gdlm_sync_lvb(lm_lock_t *, char *); | ||
179 | |||
180 | /* plock.c */ | ||
181 | |||
182 | int gdlm_plock_init(void); | ||
183 | void gdlm_plock_exit(void); | ||
184 | int gdlm_plock(lm_lockspace_t *, struct lm_lockname *, struct file *, int, | ||
185 | struct file_lock *); | ||
186 | int gdlm_plock_get(lm_lockspace_t *, struct lm_lockname *, struct file *, | ||
187 | struct file_lock *); | ||
188 | int gdlm_punlock(lm_lockspace_t *, struct lm_lockname *, struct file *, | ||
189 | struct file_lock *); | ||
190 | #endif | ||
191 | |||
diff --git a/fs/gfs2/locking/dlm/main.c b/fs/gfs2/locking/dlm/main.c index 3ced92ef1b19..2c13c916a352 100644 --- a/fs/gfs2/locking/dlm/main.c +++ b/fs/gfs2/locking/dlm/main.c | |||
@@ -1,15 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | ******************************************************************************* | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | ** | 3 | * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | * |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | ** | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | * of the GNU General Public License v.2. |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | */ |
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | 9 | ||
14 | #include <linux/init.h> | 10 | #include <linux/init.h> |
15 | 11 | ||
@@ -24,7 +20,7 @@ int __init init_lock_dlm(void) | |||
24 | { | 20 | { |
25 | int error; | 21 | int error; |
26 | 22 | ||
27 | error = lm_register_proto(&gdlm_ops); | 23 | error = gfs_register_lockproto(&gdlm_ops); |
28 | if (error) { | 24 | if (error) { |
29 | printk("lock_dlm: can't register protocol: %d\n", error); | 25 | printk("lock_dlm: can't register protocol: %d\n", error); |
30 | return error; | 26 | return error; |
@@ -32,7 +28,14 @@ int __init init_lock_dlm(void) | |||
32 | 28 | ||
33 | error = gdlm_sysfs_init(); | 29 | error = gdlm_sysfs_init(); |
34 | if (error) { | 30 | if (error) { |
35 | lm_unregister_proto(&gdlm_ops); | 31 | gfs_unregister_lockproto(&gdlm_ops); |
32 | return error; | ||
33 | } | ||
34 | |||
35 | error = gdlm_plock_init(); | ||
36 | if (error) { | ||
37 | gdlm_sysfs_exit(); | ||
38 | gfs_unregister_lockproto(&gdlm_ops); | ||
36 | return error; | 39 | return error; |
37 | } | 40 | } |
38 | 41 | ||
@@ -45,8 +48,9 @@ int __init init_lock_dlm(void) | |||
45 | 48 | ||
46 | void __exit exit_lock_dlm(void) | 49 | void __exit exit_lock_dlm(void) |
47 | { | 50 | { |
48 | lm_unregister_proto(&gdlm_ops); | 51 | gdlm_plock_exit(); |
49 | gdlm_sysfs_exit(); | 52 | gdlm_sysfs_exit(); |
53 | gfs_unregister_lockproto(&gdlm_ops); | ||
50 | } | 54 | } |
51 | 55 | ||
52 | module_init(init_lock_dlm); | 56 | module_init(init_lock_dlm); |
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index 92b1789deb89..bfb224638f2d 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c | |||
@@ -1,15 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | ******************************************************************************* | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | ** | 3 | * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | * |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | ** | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | * of the GNU General Public License v.2. |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | */ |
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | 9 | ||
14 | #include "lock_dlm.h" | 10 | #include "lock_dlm.h" |
15 | 11 | ||
@@ -24,27 +20,21 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata, | |||
24 | struct gdlm_ls *ls; | 20 | struct gdlm_ls *ls; |
25 | char buf[256], *p; | 21 | char buf[256], *p; |
26 | 22 | ||
27 | ls = kmalloc(sizeof(struct gdlm_ls), GFP_KERNEL); | 23 | ls = kzalloc(sizeof(struct gdlm_ls), GFP_KERNEL); |
28 | if (!ls) | 24 | if (!ls) |
29 | return NULL; | 25 | return NULL; |
30 | 26 | ||
31 | memset(ls, 0, sizeof(struct gdlm_ls)); | ||
32 | |||
33 | ls->drop_locks_count = gdlm_drop_count; | 27 | ls->drop_locks_count = gdlm_drop_count; |
34 | ls->drop_locks_period = gdlm_drop_period; | 28 | ls->drop_locks_period = gdlm_drop_period; |
35 | |||
36 | ls->fscb = cb; | 29 | ls->fscb = cb; |
37 | ls->fsdata = fsdata; | 30 | ls->fsdata = fsdata; |
38 | ls->fsflags = flags; | 31 | ls->fsflags = flags; |
39 | |||
40 | spin_lock_init(&ls->async_lock); | 32 | spin_lock_init(&ls->async_lock); |
41 | |||
42 | INIT_LIST_HEAD(&ls->complete); | 33 | INIT_LIST_HEAD(&ls->complete); |
43 | INIT_LIST_HEAD(&ls->blocking); | 34 | INIT_LIST_HEAD(&ls->blocking); |
44 | INIT_LIST_HEAD(&ls->delayed); | 35 | INIT_LIST_HEAD(&ls->delayed); |
45 | INIT_LIST_HEAD(&ls->submit); | 36 | INIT_LIST_HEAD(&ls->submit); |
46 | INIT_LIST_HEAD(&ls->all_locks); | 37 | INIT_LIST_HEAD(&ls->all_locks); |
47 | |||
48 | init_waitqueue_head(&ls->thread_wait); | 38 | init_waitqueue_head(&ls->thread_wait); |
49 | init_waitqueue_head(&ls->wait_control); | 39 | init_waitqueue_head(&ls->wait_control); |
50 | ls->thread1 = NULL; | 40 | ls->thread1 = NULL; |
@@ -57,23 +47,75 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata, | |||
57 | 47 | ||
58 | p = strstr(buf, ":"); | 48 | p = strstr(buf, ":"); |
59 | if (!p) { | 49 | if (!p) { |
60 | printk("lock_dlm: invalid table_name \"%s\"\n", table_name); | 50 | log_info("invalid table_name \"%s\"", table_name); |
61 | kfree(ls); | 51 | kfree(ls); |
62 | return NULL; | 52 | return NULL; |
63 | } | 53 | } |
64 | *p = '\0'; | 54 | *p = '\0'; |
65 | p++; | 55 | p++; |
66 | 56 | ||
67 | strncpy(ls->clustername, buf, 128); | 57 | strncpy(ls->clustername, buf, GDLM_NAME_LEN); |
68 | strncpy(ls->fsname, p, 128); | 58 | strncpy(ls->fsname, p, GDLM_NAME_LEN); |
69 | 59 | ||
70 | return ls; | 60 | return ls; |
71 | } | 61 | } |
72 | 62 | ||
63 | static int make_args(struct gdlm_ls *ls, char *data_arg) | ||
64 | { | ||
65 | char data[256]; | ||
66 | char *options, *x, *y; | ||
67 | int error = 0; | ||
68 | |||
69 | memset(data, 0, 256); | ||
70 | strncpy(data, data_arg, 255); | ||
71 | |||
72 | for (options = data; (x = strsep(&options, ":")); ) { | ||
73 | if (!*x) | ||
74 | continue; | ||
75 | |||
76 | y = strchr(x, '='); | ||
77 | if (y) | ||
78 | *y++ = 0; | ||
79 | |||
80 | if (!strcmp(x, "jid")) { | ||
81 | if (!y) { | ||
82 | log_error("need argument to jid"); | ||
83 | error = -EINVAL; | ||
84 | break; | ||
85 | } | ||
86 | sscanf(y, "%u", &ls->jid); | ||
87 | |||
88 | } else if (!strcmp(x, "first")) { | ||
89 | if (!y) { | ||
90 | log_error("need argument to first"); | ||
91 | error = -EINVAL; | ||
92 | break; | ||
93 | } | ||
94 | sscanf(y, "%u", &ls->first); | ||
95 | |||
96 | } else if (!strcmp(x, "id")) { | ||
97 | if (!y) { | ||
98 | log_error("need argument to id"); | ||
99 | error = -EINVAL; | ||
100 | break; | ||
101 | } | ||
102 | sscanf(y, "%u", &ls->id); | ||
103 | |||
104 | } else { | ||
105 | log_error("unkonwn option: %s", x); | ||
106 | error = -EINVAL; | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | return error; | ||
112 | } | ||
113 | |||
73 | static int gdlm_mount(char *table_name, char *host_data, | 114 | static int gdlm_mount(char *table_name, char *host_data, |
74 | lm_callback_t cb, lm_fsdata_t *fsdata, | 115 | lm_callback_t cb, lm_fsdata_t *fsdata, |
75 | unsigned int min_lvb_size, int flags, | 116 | unsigned int min_lvb_size, int flags, |
76 | struct lm_lockstruct *lockstruct) | 117 | struct lm_lockstruct *lockstruct, |
118 | struct kobject *fskobj) | ||
77 | { | 119 | { |
78 | struct gdlm_ls *ls; | 120 | struct gdlm_ls *ls; |
79 | int error = -ENOMEM; | 121 | int error = -ENOMEM; |
@@ -92,30 +134,18 @@ static int gdlm_mount(char *table_name, char *host_data, | |||
92 | error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), | 134 | error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), |
93 | &ls->dlm_lockspace, 0, GDLM_LVB_SIZE); | 135 | &ls->dlm_lockspace, 0, GDLM_LVB_SIZE); |
94 | if (error) { | 136 | if (error) { |
95 | printk("lock_dlm: dlm_new_lockspace error %d\n", error); | 137 | log_error("dlm_new_lockspace error %d", error); |
96 | goto out_thread; | 138 | goto out_thread; |
97 | } | 139 | } |
98 | 140 | ||
99 | error = gdlm_kobject_setup(ls); | 141 | error = gdlm_kobject_setup(ls, fskobj); |
100 | if (error) | 142 | if (error) |
101 | goto out_dlm; | 143 | goto out_dlm; |
102 | kobject_uevent(&ls->kobj, KOBJ_MOUNT, NULL); | ||
103 | 144 | ||
104 | /* Now we depend on userspace to notice the new mount, | 145 | error = make_args(ls, host_data); |
105 | join the appropriate group, and do a write to our sysfs | ||
106 | "mounted" or "terminate" file. Before the start, userspace | ||
107 | must set "jid" and "first". */ | ||
108 | |||
109 | error = wait_event_interruptible(ls->wait_control, | ||
110 | test_bit(DFL_JOIN_DONE, &ls->flags)); | ||
111 | if (error) | 146 | if (error) |
112 | goto out_sysfs; | 147 | goto out_sysfs; |
113 | 148 | ||
114 | if (test_bit(DFL_TERMINATE, &ls->flags)) { | ||
115 | error = -ERESTARTSYS; | ||
116 | goto out_sysfs; | ||
117 | } | ||
118 | |||
119 | lockstruct->ls_jid = ls->jid; | 149 | lockstruct->ls_jid = ls->jid; |
120 | lockstruct->ls_first = ls->first; | 150 | lockstruct->ls_first = ls->first; |
121 | lockstruct->ls_lockspace = ls; | 151 | lockstruct->ls_lockspace = ls; |
@@ -143,22 +173,19 @@ static void gdlm_unmount(lm_lockspace_t *lockspace) | |||
143 | 173 | ||
144 | log_debug("unmount flags %lx", ls->flags); | 174 | log_debug("unmount flags %lx", ls->flags); |
145 | 175 | ||
146 | if (test_bit(DFL_WITHDRAW, &ls->flags)) { | 176 | /* FIXME: serialize unmount and withdraw in case they |
147 | gdlm_kobject_release(ls); | 177 | happen at once. Also, if unmount follows withdraw, |
148 | goto out; | 178 | wait for withdraw to finish. */ |
149 | } | ||
150 | |||
151 | kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL); | ||
152 | 179 | ||
153 | wait_event_interruptible(ls->wait_control, | 180 | if (test_bit(DFL_WITHDRAW, &ls->flags)) |
154 | test_bit(DFL_LEAVE_DONE, &ls->flags)); | 181 | goto out; |
155 | 182 | ||
156 | gdlm_kobject_release(ls); | 183 | gdlm_kobject_release(ls); |
157 | dlm_release_lockspace(ls->dlm_lockspace, 2); | 184 | dlm_release_lockspace(ls->dlm_lockspace, 2); |
158 | gdlm_release_threads(ls); | 185 | gdlm_release_threads(ls); |
159 | rv = gdlm_release_all_locks(ls); | 186 | rv = gdlm_release_all_locks(ls); |
160 | if (rv) | 187 | if (rv) |
161 | log_all("lm_dlm_unmount: %d stray locks freed", rv); | 188 | log_info("gdlm_unmount: %d stray locks freed", rv); |
162 | out: | 189 | out: |
163 | kfree(ls); | 190 | kfree(ls); |
164 | } | 191 | } |
@@ -167,7 +194,7 @@ static void gdlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid, | |||
167 | unsigned int message) | 194 | unsigned int message) |
168 | { | 195 | { |
169 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; | 196 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; |
170 | ls->recover_done = jid; | 197 | ls->recover_jid_done = jid; |
171 | kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL); | 198 | kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL); |
172 | } | 199 | } |
173 | 200 | ||
@@ -178,12 +205,14 @@ static void gdlm_others_may_mount(lm_lockspace_t *lockspace) | |||
178 | kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL); | 205 | kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL); |
179 | } | 206 | } |
180 | 207 | ||
208 | /* Userspace gets the offline uevent, blocks new gfs locks on | ||
209 | other mounters, and lets us know (sets WITHDRAW flag). Then, | ||
210 | userspace leaves the mount group while we leave the lockspace. */ | ||
211 | |||
181 | static void gdlm_withdraw(lm_lockspace_t *lockspace) | 212 | static void gdlm_withdraw(lm_lockspace_t *lockspace) |
182 | { | 213 | { |
183 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; | 214 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; |
184 | 215 | ||
185 | /* userspace suspends locking on all other members */ | ||
186 | |||
187 | kobject_uevent(&ls->kobj, KOBJ_OFFLINE, NULL); | 216 | kobject_uevent(&ls->kobj, KOBJ_OFFLINE, NULL); |
188 | 217 | ||
189 | wait_event_interruptible(ls->wait_control, | 218 | wait_event_interruptible(ls->wait_control, |
@@ -192,49 +221,27 @@ static void gdlm_withdraw(lm_lockspace_t *lockspace) | |||
192 | dlm_release_lockspace(ls->dlm_lockspace, 2); | 221 | dlm_release_lockspace(ls->dlm_lockspace, 2); |
193 | gdlm_release_threads(ls); | 222 | gdlm_release_threads(ls); |
194 | gdlm_release_all_locks(ls); | 223 | gdlm_release_all_locks(ls); |
195 | 224 | gdlm_kobject_release(ls); | |
196 | kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL); | ||
197 | |||
198 | /* userspace leaves the mount group, we don't need to wait for | ||
199 | that to complete */ | ||
200 | } | ||
201 | |||
202 | int gdlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name, | ||
203 | struct file *file, struct file_lock *fl) | ||
204 | { | ||
205 | return -ENOSYS; | ||
206 | } | ||
207 | |||
208 | int gdlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name, | ||
209 | struct file *file, struct file_lock *fl) | ||
210 | { | ||
211 | return -ENOSYS; | ||
212 | } | ||
213 | |||
214 | int gdlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name, | ||
215 | struct file *file, int cmd, struct file_lock *fl) | ||
216 | { | ||
217 | return -ENOSYS; | ||
218 | } | 225 | } |
219 | 226 | ||
220 | struct lm_lockops gdlm_ops = { | 227 | struct lm_lockops gdlm_ops = { |
221 | lm_proto_name:"lock_dlm", | 228 | .lm_proto_name = "lock_dlm", |
222 | lm_mount:gdlm_mount, | 229 | .lm_mount = gdlm_mount, |
223 | lm_others_may_mount:gdlm_others_may_mount, | 230 | .lm_others_may_mount = gdlm_others_may_mount, |
224 | lm_unmount:gdlm_unmount, | 231 | .lm_unmount = gdlm_unmount, |
225 | lm_withdraw:gdlm_withdraw, | 232 | .lm_withdraw = gdlm_withdraw, |
226 | lm_get_lock:gdlm_get_lock, | 233 | .lm_get_lock = gdlm_get_lock, |
227 | lm_put_lock:gdlm_put_lock, | 234 | .lm_put_lock = gdlm_put_lock, |
228 | lm_lock:gdlm_lock, | 235 | .lm_lock = gdlm_lock, |
229 | lm_unlock:gdlm_unlock, | 236 | .lm_unlock = gdlm_unlock, |
230 | lm_plock:gdlm_plock, | 237 | .lm_plock = gdlm_plock, |
231 | lm_punlock:gdlm_punlock, | 238 | .lm_punlock = gdlm_punlock, |
232 | lm_plock_get:gdlm_plock_get, | 239 | .lm_plock_get = gdlm_plock_get, |
233 | lm_cancel:gdlm_cancel, | 240 | .lm_cancel = gdlm_cancel, |
234 | lm_hold_lvb:gdlm_hold_lvb, | 241 | .lm_hold_lvb = gdlm_hold_lvb, |
235 | lm_unhold_lvb:gdlm_unhold_lvb, | 242 | .lm_unhold_lvb = gdlm_unhold_lvb, |
236 | lm_sync_lvb:gdlm_sync_lvb, | 243 | .lm_sync_lvb = gdlm_sync_lvb, |
237 | lm_recovery_done:gdlm_recovery_done, | 244 | .lm_recovery_done = gdlm_recovery_done, |
238 | lm_owner:THIS_MODULE, | 245 | .lm_owner = THIS_MODULE, |
239 | }; | 246 | }; |
240 | 247 | ||
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c new file mode 100644 index 000000000000..382847205bc1 --- /dev/null +++ b/fs/gfs2/locking/dlm/plock.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Red Hat, Inc. All rights reserved. | ||
3 | * | ||
4 | * This copyrighted material is made available to anyone wishing to use, | ||
5 | * modify, copy, or redistribute it subject to the terms and conditions | ||
6 | * of the GNU General Public License v.2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/miscdevice.h> | ||
10 | #include <linux/lock_dlm_plock.h> | ||
11 | |||
12 | #include "lock_dlm.h" | ||
13 | |||
14 | |||
15 | static spinlock_t ops_lock; | ||
16 | static struct list_head send_list; | ||
17 | static struct list_head recv_list; | ||
18 | static wait_queue_head_t send_wq; | ||
19 | static wait_queue_head_t recv_wq; | ||
20 | |||
21 | struct plock_op { | ||
22 | struct list_head list; | ||
23 | int done; | ||
24 | struct gdlm_plock_info info; | ||
25 | }; | ||
26 | |||
27 | static inline void set_version(struct gdlm_plock_info *info) | ||
28 | { | ||
29 | info->version[0] = GDLM_PLOCK_VERSION_MAJOR; | ||
30 | info->version[1] = GDLM_PLOCK_VERSION_MINOR; | ||
31 | info->version[2] = GDLM_PLOCK_VERSION_PATCH; | ||
32 | } | ||
33 | |||
34 | static int check_version(struct gdlm_plock_info *info) | ||
35 | { | ||
36 | if ((GDLM_PLOCK_VERSION_MAJOR != info->version[0]) || | ||
37 | (GDLM_PLOCK_VERSION_MINOR < info->version[1])) { | ||
38 | log_error("plock device version mismatch: " | ||
39 | "kernel (%u.%u.%u), user (%u.%u.%u)", | ||
40 | GDLM_PLOCK_VERSION_MAJOR, | ||
41 | GDLM_PLOCK_VERSION_MINOR, | ||
42 | GDLM_PLOCK_VERSION_PATCH, | ||
43 | info->version[0], | ||
44 | info->version[1], | ||
45 | info->version[2]); | ||
46 | return -EINVAL; | ||
47 | } | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static void send_op(struct plock_op *op) | ||
52 | { | ||
53 | set_version(&op->info); | ||
54 | INIT_LIST_HEAD(&op->list); | ||
55 | spin_lock(&ops_lock); | ||
56 | list_add_tail(&op->list, &send_list); | ||
57 | spin_unlock(&ops_lock); | ||
58 | wake_up(&send_wq); | ||
59 | } | ||
60 | |||
61 | int gdlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name, | ||
62 | struct file *file, int cmd, struct file_lock *fl) | ||
63 | { | ||
64 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; | ||
65 | struct plock_op *op; | ||
66 | int rv; | ||
67 | |||
68 | op = kzalloc(sizeof(*op), GFP_KERNEL); | ||
69 | if (!op) | ||
70 | return -ENOMEM; | ||
71 | |||
72 | op->info.optype = GDLM_PLOCK_OP_LOCK; | ||
73 | op->info.pid = (uint32_t) fl->fl_owner; | ||
74 | op->info.ex = (fl->fl_type == F_WRLCK); | ||
75 | op->info.wait = IS_SETLKW(cmd); | ||
76 | op->info.fsid = ls->id; | ||
77 | op->info.number = name->ln_number; | ||
78 | op->info.start = fl->fl_start; | ||
79 | op->info.end = fl->fl_end; | ||
80 | |||
81 | send_op(op); | ||
82 | wait_event(recv_wq, (op->done != 0)); | ||
83 | |||
84 | spin_lock(&ops_lock); | ||
85 | if (!list_empty(&op->list)) { | ||
86 | printk("plock op on list\n"); | ||
87 | list_del(&op->list); | ||
88 | } | ||
89 | spin_unlock(&ops_lock); | ||
90 | |||
91 | rv = op->info.rv; | ||
92 | |||
93 | if (!rv) { | ||
94 | if (posix_lock_file_wait(file, fl) < 0) | ||
95 | log_error("gdlm_plock: vfs lock error %x,%llx", | ||
96 | name->ln_type, name->ln_number); | ||
97 | } | ||
98 | |||
99 | kfree(op); | ||
100 | return rv; | ||
101 | } | ||
102 | |||
103 | int gdlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name, | ||
104 | struct file *file, struct file_lock *fl) | ||
105 | { | ||
106 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; | ||
107 | struct plock_op *op; | ||
108 | int rv; | ||
109 | |||
110 | op = kzalloc(sizeof(*op), GFP_KERNEL); | ||
111 | if (!op) | ||
112 | return -ENOMEM; | ||
113 | |||
114 | if (posix_lock_file_wait(file, fl) < 0) | ||
115 | log_error("gdlm_punlock: vfs unlock error %x,%llx", | ||
116 | name->ln_type, name->ln_number); | ||
117 | |||
118 | op->info.optype = GDLM_PLOCK_OP_UNLOCK; | ||
119 | op->info.pid = (uint32_t) fl->fl_owner; | ||
120 | op->info.fsid = ls->id; | ||
121 | op->info.number = name->ln_number; | ||
122 | op->info.start = fl->fl_start; | ||
123 | op->info.end = fl->fl_end; | ||
124 | |||
125 | send_op(op); | ||
126 | wait_event(recv_wq, (op->done != 0)); | ||
127 | |||
128 | spin_lock(&ops_lock); | ||
129 | if (!list_empty(&op->list)) { | ||
130 | printk("punlock op on list\n"); | ||
131 | list_del(&op->list); | ||
132 | } | ||
133 | spin_unlock(&ops_lock); | ||
134 | |||
135 | rv = op->info.rv; | ||
136 | |||
137 | kfree(op); | ||
138 | return rv; | ||
139 | } | ||
140 | |||
141 | int gdlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name, | ||
142 | struct file *file, struct file_lock *fl) | ||
143 | { | ||
144 | struct gdlm_ls *ls = (struct gdlm_ls *) lockspace; | ||
145 | struct plock_op *op; | ||
146 | int rv; | ||
147 | |||
148 | op = kzalloc(sizeof(*op), GFP_KERNEL); | ||
149 | if (!op) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | op->info.optype = GDLM_PLOCK_OP_GET; | ||
153 | op->info.pid = (uint32_t) fl->fl_owner; | ||
154 | op->info.ex = (fl->fl_type == F_WRLCK); | ||
155 | op->info.fsid = ls->id; | ||
156 | op->info.number = name->ln_number; | ||
157 | op->info.start = fl->fl_start; | ||
158 | op->info.end = fl->fl_end; | ||
159 | |||
160 | send_op(op); | ||
161 | wait_event(recv_wq, (op->done != 0)); | ||
162 | |||
163 | spin_lock(&ops_lock); | ||
164 | if (!list_empty(&op->list)) { | ||
165 | printk("plock_get op on list\n"); | ||
166 | list_del(&op->list); | ||
167 | } | ||
168 | spin_unlock(&ops_lock); | ||
169 | |||
170 | rv = op->info.rv; | ||
171 | |||
172 | if (rv == 0) | ||
173 | fl->fl_type = F_UNLCK; | ||
174 | else if (rv > 0) { | ||
175 | fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; | ||
176 | fl->fl_pid = op->info.pid; | ||
177 | fl->fl_start = op->info.start; | ||
178 | fl->fl_end = op->info.end; | ||
179 | } | ||
180 | |||
181 | kfree(op); | ||
182 | return rv; | ||
183 | } | ||
184 | |||
185 | /* a read copies out one plock request from the send list */ | ||
186 | static ssize_t dev_read(struct file *file, char __user *u, size_t count, | ||
187 | loff_t *ppos) | ||
188 | { | ||
189 | struct gdlm_plock_info info; | ||
190 | struct plock_op *op = NULL; | ||
191 | |||
192 | if (count < sizeof(info)) | ||
193 | return -EINVAL; | ||
194 | |||
195 | spin_lock(&ops_lock); | ||
196 | if (!list_empty(&send_list)) { | ||
197 | op = list_entry(send_list.next, struct plock_op, list); | ||
198 | list_move(&op->list, &recv_list); | ||
199 | memcpy(&info, &op->info, sizeof(info)); | ||
200 | } | ||
201 | spin_unlock(&ops_lock); | ||
202 | |||
203 | if (!op) | ||
204 | return -EAGAIN; | ||
205 | |||
206 | if (copy_to_user(u, &info, sizeof(info))) | ||
207 | return -EFAULT; | ||
208 | return sizeof(info); | ||
209 | } | ||
210 | |||
211 | /* a write copies in one plock result that should match a plock_op | ||
212 | on the recv list */ | ||
213 | static ssize_t dev_write(struct file *file, const char __user *u, size_t count, | ||
214 | loff_t *ppos) | ||
215 | { | ||
216 | struct gdlm_plock_info info; | ||
217 | struct plock_op *op; | ||
218 | int found = 0; | ||
219 | |||
220 | if (count != sizeof(info)) | ||
221 | return -EINVAL; | ||
222 | |||
223 | if (copy_from_user(&info, u, sizeof(info))) | ||
224 | return -EFAULT; | ||
225 | |||
226 | if (check_version(&info)) | ||
227 | return -EINVAL; | ||
228 | |||
229 | spin_lock(&ops_lock); | ||
230 | list_for_each_entry(op, &recv_list, list) { | ||
231 | if (op->info.fsid == info.fsid && | ||
232 | op->info.number == info.number) { | ||
233 | list_del_init(&op->list); | ||
234 | found = 1; | ||
235 | op->done = 1; | ||
236 | memcpy(&op->info, &info, sizeof(info)); | ||
237 | break; | ||
238 | } | ||
239 | } | ||
240 | spin_unlock(&ops_lock); | ||
241 | |||
242 | if (found) | ||
243 | wake_up(&recv_wq); | ||
244 | else | ||
245 | printk("gdlm dev_write no op %x %llx\n", info.fsid, | ||
246 | info.number); | ||
247 | return count; | ||
248 | } | ||
249 | |||
250 | static unsigned int dev_poll(struct file *file, poll_table *wait) | ||
251 | { | ||
252 | poll_wait(file, &send_wq, wait); | ||
253 | |||
254 | spin_lock(&ops_lock); | ||
255 | if (!list_empty(&send_list)) { | ||
256 | spin_unlock(&ops_lock); | ||
257 | return POLLIN | POLLRDNORM; | ||
258 | } | ||
259 | spin_unlock(&ops_lock); | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static struct file_operations dev_fops = { | ||
264 | .read = dev_read, | ||
265 | .write = dev_write, | ||
266 | .poll = dev_poll, | ||
267 | .owner = THIS_MODULE | ||
268 | }; | ||
269 | |||
270 | static struct miscdevice plock_dev_misc = { | ||
271 | .minor = MISC_DYNAMIC_MINOR, | ||
272 | .name = GDLM_PLOCK_MISC_NAME, | ||
273 | .fops = &dev_fops | ||
274 | }; | ||
275 | |||
276 | int gdlm_plock_init(void) | ||
277 | { | ||
278 | int rv; | ||
279 | |||
280 | spin_lock_init(&ops_lock); | ||
281 | INIT_LIST_HEAD(&send_list); | ||
282 | INIT_LIST_HEAD(&recv_list); | ||
283 | init_waitqueue_head(&send_wq); | ||
284 | init_waitqueue_head(&recv_wq); | ||
285 | |||
286 | rv = misc_register(&plock_dev_misc); | ||
287 | if (rv) | ||
288 | printk("gdlm_plock_init: misc_register failed %d", rv); | ||
289 | return rv; | ||
290 | } | ||
291 | |||
292 | void gdlm_plock_exit(void) | ||
293 | { | ||
294 | if (misc_deregister(&plock_dev_misc) < 0) | ||
295 | printk("gdlm_plock_exit: misc_deregister failed"); | ||
296 | } | ||
297 | |||
diff --git a/fs/gfs2/locking/dlm/sysfs.c b/fs/gfs2/locking/dlm/sysfs.c index 8964733f55e4..e1e5186c97c9 100644 --- a/fs/gfs2/locking/dlm/sysfs.c +++ b/fs/gfs2/locking/dlm/sysfs.c | |||
@@ -1,21 +1,25 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | ******************************************************************************* | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | ** | 3 | * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. |
4 | ** Copyright (C) 2005 Red Hat, Inc. All rights reserved. | 4 | * |
5 | ** | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | ** This copyrighted material is made available to anyone wishing to use, | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | ** modify, copy, or redistribute it subject to the terms and conditions | 7 | * of the GNU General Public License v.2. |
8 | ** of the GNU General Public License v.2. | 8 | */ |
9 | ** | ||
10 | ******************************************************************************* | ||
11 | ******************************************************************************/ | ||
12 | 9 | ||
13 | #include <linux/ctype.h> | 10 | #include <linux/ctype.h> |
14 | #include <linux/stat.h> | 11 | #include <linux/stat.h> |
15 | 12 | ||
16 | #include "lock_dlm.h" | 13 | #include "lock_dlm.h" |
17 | 14 | ||
18 | static ssize_t gdlm_block_show(struct gdlm_ls *ls, char *buf) | 15 | extern struct lm_lockops gdlm_ops; |
16 | |||
17 | static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf) | ||
18 | { | ||
19 | return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name); | ||
20 | } | ||
21 | |||
22 | static ssize_t block_show(struct gdlm_ls *ls, char *buf) | ||
19 | { | 23 | { |
20 | ssize_t ret; | 24 | ssize_t ret; |
21 | int val = 0; | 25 | int val = 0; |
@@ -26,7 +30,7 @@ static ssize_t gdlm_block_show(struct gdlm_ls *ls, char *buf) | |||
26 | return ret; | 30 | return ret; |
27 | } | 31 | } |
28 | 32 | ||
29 | static ssize_t gdlm_block_store(struct gdlm_ls *ls, const char *buf, size_t len) | 33 | static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len) |
30 | { | 34 | { |
31 | ssize_t ret = len; | 35 | ssize_t ret = len; |
32 | int val; | 36 | int val; |
@@ -43,43 +47,7 @@ static ssize_t gdlm_block_store(struct gdlm_ls *ls, const char *buf, size_t len) | |||
43 | return ret; | 47 | return ret; |
44 | } | 48 | } |
45 | 49 | ||
46 | static ssize_t gdlm_mounted_show(struct gdlm_ls *ls, char *buf) | 50 | static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf) |
47 | { | ||
48 | ssize_t ret; | ||
49 | int val = -2; | ||
50 | |||
51 | if (test_bit(DFL_TERMINATE, &ls->flags)) | ||
52 | val = -1; | ||
53 | else if (test_bit(DFL_LEAVE_DONE, &ls->flags)) | ||
54 | val = 0; | ||
55 | else if (test_bit(DFL_JOIN_DONE, &ls->flags)) | ||
56 | val = 1; | ||
57 | ret = sprintf(buf, "%d\n", val); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | static ssize_t gdlm_mounted_store(struct gdlm_ls *ls, const char *buf, size_t len) | ||
62 | { | ||
63 | ssize_t ret = len; | ||
64 | int val; | ||
65 | |||
66 | val = simple_strtol(buf, NULL, 0); | ||
67 | |||
68 | if (val == 1) | ||
69 | set_bit(DFL_JOIN_DONE, &ls->flags); | ||
70 | else if (val == 0) | ||
71 | set_bit(DFL_LEAVE_DONE, &ls->flags); | ||
72 | else if (val == -1) { | ||
73 | set_bit(DFL_TERMINATE, &ls->flags); | ||
74 | set_bit(DFL_JOIN_DONE, &ls->flags); | ||
75 | set_bit(DFL_LEAVE_DONE, &ls->flags); | ||
76 | } else | ||
77 | ret = -EINVAL; | ||
78 | wake_up(&ls->wait_control); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static ssize_t gdlm_withdraw_show(struct gdlm_ls *ls, char *buf) | ||
83 | { | 51 | { |
84 | ssize_t ret; | 52 | ssize_t ret; |
85 | int val = 0; | 53 | int val = 0; |
@@ -90,7 +58,7 @@ static ssize_t gdlm_withdraw_show(struct gdlm_ls *ls, char *buf) | |||
90 | return ret; | 58 | return ret; |
91 | } | 59 | } |
92 | 60 | ||
93 | static ssize_t gdlm_withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len) | 61 | static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len) |
94 | { | 62 | { |
95 | ssize_t ret = len; | 63 | ssize_t ret = len; |
96 | int val; | 64 | int val; |
@@ -105,67 +73,41 @@ static ssize_t gdlm_withdraw_store(struct gdlm_ls *ls, const char *buf, size_t l | |||
105 | return ret; | 73 | return ret; |
106 | } | 74 | } |
107 | 75 | ||
108 | static ssize_t gdlm_jid_show(struct gdlm_ls *ls, char *buf) | 76 | static ssize_t id_show(struct gdlm_ls *ls, char *buf) |
109 | { | ||
110 | return sprintf(buf, "%u\n", ls->jid); | ||
111 | } | ||
112 | |||
113 | static ssize_t gdlm_jid_store(struct gdlm_ls *ls, const char *buf, size_t len) | ||
114 | { | 77 | { |
115 | ls->jid = simple_strtol(buf, NULL, 0); | 78 | return sprintf(buf, "%u\n", ls->id); |
116 | return len; | ||
117 | } | 79 | } |
118 | 80 | ||
119 | static ssize_t gdlm_first_show(struct gdlm_ls *ls, char *buf) | 81 | static ssize_t jid_show(struct gdlm_ls *ls, char *buf) |
120 | { | 82 | { |
121 | return sprintf(buf, "%u\n", ls->first); | 83 | return sprintf(buf, "%d\n", ls->jid); |
122 | } | 84 | } |
123 | 85 | ||
124 | static ssize_t gdlm_first_store(struct gdlm_ls *ls, const char *buf, size_t len) | 86 | static ssize_t first_show(struct gdlm_ls *ls, char *buf) |
125 | { | 87 | { |
126 | ls->first = simple_strtol(buf, NULL, 0); | 88 | return sprintf(buf, "%d\n", ls->first); |
127 | return len; | ||
128 | } | 89 | } |
129 | 90 | ||
130 | static ssize_t gdlm_first_done_show(struct gdlm_ls *ls, char *buf) | 91 | static ssize_t first_done_show(struct gdlm_ls *ls, char *buf) |
131 | { | 92 | { |
132 | return sprintf(buf, "%d\n", ls->first_done); | 93 | return sprintf(buf, "%d\n", ls->first_done); |
133 | } | 94 | } |
134 | 95 | ||
135 | static ssize_t gdlm_recover_show(struct gdlm_ls *ls, char *buf) | 96 | static ssize_t recover_show(struct gdlm_ls *ls, char *buf) |
136 | { | 97 | { |
137 | return sprintf(buf, "%u\n", ls->recover_jid); | 98 | return sprintf(buf, "%d\n", ls->recover_jid); |
138 | } | 99 | } |
139 | 100 | ||
140 | static ssize_t gdlm_recover_store(struct gdlm_ls *ls, const char *buf, size_t len) | 101 | static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len) |
141 | { | 102 | { |
142 | ls->recover_jid = simple_strtol(buf, NULL, 0); | 103 | ls->recover_jid = simple_strtol(buf, NULL, 0); |
143 | ls->fscb(ls->fsdata, LM_CB_NEED_RECOVERY, &ls->recover_jid); | 104 | ls->fscb(ls->fsdata, LM_CB_NEED_RECOVERY, &ls->recover_jid); |
144 | return len; | 105 | return len; |
145 | } | 106 | } |
146 | 107 | ||
147 | static ssize_t gdlm_recover_done_show(struct gdlm_ls *ls, char *buf) | 108 | static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf) |
148 | { | ||
149 | ssize_t ret; | ||
150 | ret = sprintf(buf, "%d\n", ls->recover_done); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | static ssize_t gdlm_cluster_show(struct gdlm_ls *ls, char *buf) | ||
155 | { | ||
156 | ssize_t ret; | ||
157 | ret = sprintf(buf, "%s\n", ls->clustername); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static ssize_t gdlm_options_show(struct gdlm_ls *ls, char *buf) | ||
162 | { | 109 | { |
163 | ssize_t ret = 0; | 110 | return sprintf(buf, "%d\n", ls->recover_jid_done); |
164 | |||
165 | if (ls->fsflags & LM_MFLAG_SPECTATOR) | ||
166 | ret += sprintf(buf, "spectator "); | ||
167 | |||
168 | return ret; | ||
169 | } | 111 | } |
170 | 112 | ||
171 | struct gdlm_attr { | 113 | struct gdlm_attr { |
@@ -174,73 +116,29 @@ struct gdlm_attr { | |||
174 | ssize_t (*store)(struct gdlm_ls *, const char *, size_t); | 116 | ssize_t (*store)(struct gdlm_ls *, const char *, size_t); |
175 | }; | 117 | }; |
176 | 118 | ||
177 | static struct gdlm_attr gdlm_attr_block = { | 119 | #define GDLM_ATTR(_name,_mode,_show,_store) \ |
178 | .attr = {.name = "block", .mode = S_IRUGO | S_IWUSR}, | 120 | static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) |
179 | .show = gdlm_block_show, | ||
180 | .store = gdlm_block_store | ||
181 | }; | ||
182 | |||
183 | static struct gdlm_attr gdlm_attr_mounted = { | ||
184 | .attr = {.name = "mounted", .mode = S_IRUGO | S_IWUSR}, | ||
185 | .show = gdlm_mounted_show, | ||
186 | .store = gdlm_mounted_store | ||
187 | }; | ||
188 | |||
189 | static struct gdlm_attr gdlm_attr_withdraw = { | ||
190 | .attr = {.name = "withdraw", .mode = S_IRUGO | S_IWUSR}, | ||
191 | .show = gdlm_withdraw_show, | ||
192 | .store = gdlm_withdraw_store | ||
193 | }; | ||
194 | |||
195 | static struct gdlm_attr gdlm_attr_jid = { | ||
196 | .attr = {.name = "jid", .mode = S_IRUGO | S_IWUSR}, | ||
197 | .show = gdlm_jid_show, | ||
198 | .store = gdlm_jid_store | ||
199 | }; | ||
200 | |||
201 | static struct gdlm_attr gdlm_attr_first = { | ||
202 | .attr = {.name = "first", .mode = S_IRUGO | S_IWUSR}, | ||
203 | .show = gdlm_first_show, | ||
204 | .store = gdlm_first_store | ||
205 | }; | ||
206 | |||
207 | static struct gdlm_attr gdlm_attr_first_done = { | ||
208 | .attr = {.name = "first_done", .mode = S_IRUGO}, | ||
209 | .show = gdlm_first_done_show, | ||
210 | }; | ||
211 | |||
212 | static struct gdlm_attr gdlm_attr_recover = { | ||
213 | .attr = {.name = "recover", .mode = S_IRUGO | S_IWUSR}, | ||
214 | .show = gdlm_recover_show, | ||
215 | .store = gdlm_recover_store | ||
216 | }; | ||
217 | |||
218 | static struct gdlm_attr gdlm_attr_recover_done = { | ||
219 | .attr = {.name = "recover_done", .mode = S_IRUGO | S_IWUSR}, | ||
220 | .show = gdlm_recover_done_show, | ||
221 | }; | ||
222 | |||
223 | static struct gdlm_attr gdlm_attr_cluster = { | ||
224 | .attr = {.name = "cluster", .mode = S_IRUGO | S_IWUSR}, | ||
225 | .show = gdlm_cluster_show, | ||
226 | }; | ||
227 | 121 | ||
228 | static struct gdlm_attr gdlm_attr_options = { | 122 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); |
229 | .attr = {.name = "options", .mode = S_IRUGO | S_IWUSR}, | 123 | GDLM_ATTR(block, 0644, block_show, block_store); |
230 | .show = gdlm_options_show, | 124 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); |
231 | }; | 125 | GDLM_ATTR(id, 0444, id_show, NULL); |
126 | GDLM_ATTR(jid, 0444, jid_show, NULL); | ||
127 | GDLM_ATTR(first, 0444, first_show, NULL); | ||
128 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); | ||
129 | GDLM_ATTR(recover, 0644, recover_show, recover_store); | ||
130 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); | ||
232 | 131 | ||
233 | static struct attribute *gdlm_attrs[] = { | 132 | static struct attribute *gdlm_attrs[] = { |
133 | &gdlm_attr_proto_name.attr, | ||
234 | &gdlm_attr_block.attr, | 134 | &gdlm_attr_block.attr, |
235 | &gdlm_attr_mounted.attr, | ||
236 | &gdlm_attr_withdraw.attr, | 135 | &gdlm_attr_withdraw.attr, |
136 | &gdlm_attr_id.attr, | ||
237 | &gdlm_attr_jid.attr, | 137 | &gdlm_attr_jid.attr, |
238 | &gdlm_attr_first.attr, | 138 | &gdlm_attr_first.attr, |
239 | &gdlm_attr_first_done.attr, | 139 | &gdlm_attr_first_done.attr, |
240 | &gdlm_attr_recover.attr, | 140 | &gdlm_attr_recover.attr, |
241 | &gdlm_attr_recover_done.attr, | 141 | &gdlm_attr_recover_done.attr, |
242 | &gdlm_attr_cluster.attr, | ||
243 | &gdlm_attr_options.attr, | ||
244 | NULL, | 142 | NULL, |
245 | }; | 143 | }; |
246 | 144 | ||
@@ -276,20 +174,25 @@ static struct kset gdlm_kset = { | |||
276 | .ktype = &gdlm_ktype, | 174 | .ktype = &gdlm_ktype, |
277 | }; | 175 | }; |
278 | 176 | ||
279 | int gdlm_kobject_setup(struct gdlm_ls *ls) | 177 | int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj) |
280 | { | 178 | { |
281 | int error; | 179 | int error; |
282 | 180 | ||
283 | error = kobject_set_name(&ls->kobj, "%s", ls->fsname); | 181 | error = kobject_set_name(&ls->kobj, "%s", "lock_module"); |
284 | if (error) | 182 | if (error) { |
183 | log_error("can't set kobj name %d", error); | ||
285 | return error; | 184 | return error; |
185 | } | ||
286 | 186 | ||
287 | ls->kobj.kset = &gdlm_kset; | 187 | ls->kobj.kset = &gdlm_kset; |
288 | ls->kobj.ktype = &gdlm_ktype; | 188 | ls->kobj.ktype = &gdlm_ktype; |
189 | ls->kobj.parent = fskobj; | ||
289 | 190 | ||
290 | error = kobject_register(&ls->kobj); | 191 | error = kobject_register(&ls->kobj); |
192 | if (error) | ||
193 | log_error("can't register kobj %d", error); | ||
291 | 194 | ||
292 | return 0; | 195 | return error; |
293 | } | 196 | } |
294 | 197 | ||
295 | void gdlm_kobject_release(struct gdlm_ls *ls) | 198 | void gdlm_kobject_release(struct gdlm_ls *ls) |
diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c index 22bbe6d3a5ae..6fe669cd334b 100644 --- a/fs/gfs2/locking/dlm/thread.c +++ b/fs/gfs2/locking/dlm/thread.c | |||
@@ -1,15 +1,11 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | ******************************************************************************* | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | ** | 3 | * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | * |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | ** | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | * of the GNU General Public License v.2. |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | */ |
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | 9 | ||
14 | #include "lock_dlm.h" | 10 | #include "lock_dlm.h" |
15 | 11 | ||
@@ -26,15 +22,10 @@ static void queue_submit(struct gdlm_lock *lp) | |||
26 | wake_up(&ls->thread_wait); | 22 | wake_up(&ls->thread_wait); |
27 | } | 23 | } |
28 | 24 | ||
29 | static void process_submit(struct gdlm_lock *lp) | ||
30 | { | ||
31 | gdlm_do_lock(lp, NULL); | ||
32 | } | ||
33 | |||
34 | static void process_blocking(struct gdlm_lock *lp, int bast_mode) | 25 | static void process_blocking(struct gdlm_lock *lp, int bast_mode) |
35 | { | 26 | { |
36 | struct gdlm_ls *ls = lp->ls; | 27 | struct gdlm_ls *ls = lp->ls; |
37 | unsigned int cb; | 28 | unsigned int cb = 0; |
38 | 29 | ||
39 | switch (gdlm_make_lmstate(bast_mode)) { | 30 | switch (gdlm_make_lmstate(bast_mode)) { |
40 | case LM_ST_EXCLUSIVE: | 31 | case LM_ST_EXCLUSIVE: |
@@ -47,7 +38,7 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode) | |||
47 | cb = LM_CB_NEED_S; | 38 | cb = LM_CB_NEED_S; |
48 | break; | 39 | break; |
49 | default: | 40 | default: |
50 | GDLM_ASSERT(0, printk("unknown bast mode %u\n",lp->bast_mode);); | 41 | gdlm_assert(0, "unknown bast mode %u", lp->bast_mode); |
51 | } | 42 | } |
52 | 43 | ||
53 | ls->fscb(ls->fsdata, cb, &lp->lockname); | 44 | ls->fscb(ls->fsdata, cb, &lp->lockname); |
@@ -62,9 +53,9 @@ static void process_complete(struct gdlm_lock *lp) | |||
62 | memset(&acb, 0, sizeof(acb)); | 53 | memset(&acb, 0, sizeof(acb)); |
63 | 54 | ||
64 | if (lp->lksb.sb_status == -DLM_ECANCEL) { | 55 | if (lp->lksb.sb_status == -DLM_ECANCEL) { |
65 | log_all("complete dlm cancel %x,%"PRIx64" flags %lx", | 56 | log_info("complete dlm cancel %x,%llx flags %lx", |
66 | lp->lockname.ln_type, lp->lockname.ln_number, | 57 | lp->lockname.ln_type, lp->lockname.ln_number, |
67 | lp->flags); | 58 | lp->flags); |
68 | 59 | ||
69 | lp->req = lp->cur; | 60 | lp->req = lp->cur; |
70 | acb.lc_ret |= LM_OUT_CANCELED; | 61 | acb.lc_ret |= LM_OUT_CANCELED; |
@@ -75,9 +66,9 @@ static void process_complete(struct gdlm_lock *lp) | |||
75 | 66 | ||
76 | if (test_and_clear_bit(LFL_DLM_UNLOCK, &lp->flags)) { | 67 | if (test_and_clear_bit(LFL_DLM_UNLOCK, &lp->flags)) { |
77 | if (lp->lksb.sb_status != -DLM_EUNLOCK) { | 68 | if (lp->lksb.sb_status != -DLM_EUNLOCK) { |
78 | log_all("unlock sb_status %d %x,%"PRIx64" flags %lx", | 69 | log_info("unlock sb_status %d %x,%llx flags %lx", |
79 | lp->lksb.sb_status, lp->lockname.ln_type, | 70 | lp->lksb.sb_status, lp->lockname.ln_type, |
80 | lp->lockname.ln_number, lp->flags); | 71 | lp->lockname.ln_number, lp->flags); |
81 | return; | 72 | return; |
82 | } | 73 | } |
83 | 74 | ||
@@ -108,8 +99,8 @@ static void process_complete(struct gdlm_lock *lp) | |||
108 | */ | 99 | */ |
109 | 100 | ||
110 | if (test_and_clear_bit(LFL_CANCEL, &lp->flags)) { | 101 | if (test_and_clear_bit(LFL_CANCEL, &lp->flags)) { |
111 | log_all("complete internal cancel %x,%"PRIx64"", | 102 | log_info("complete internal cancel %x,%llx", |
112 | lp->lockname.ln_type, lp->lockname.ln_number); | 103 | lp->lockname.ln_type, lp->lockname.ln_number); |
113 | lp->req = lp->cur; | 104 | lp->req = lp->cur; |
114 | acb.lc_ret |= LM_OUT_CANCELED; | 105 | acb.lc_ret |= LM_OUT_CANCELED; |
115 | goto out; | 106 | goto out; |
@@ -130,9 +121,9 @@ static void process_complete(struct gdlm_lock *lp) | |||
130 | } | 121 | } |
131 | 122 | ||
132 | /* this could only happen with cancels I think */ | 123 | /* this could only happen with cancels I think */ |
133 | log_all("ast sb_status %d %x,%"PRIx64" flags %lx", | 124 | log_info("ast sb_status %d %x,%llx flags %lx", |
134 | lp->lksb.sb_status, lp->lockname.ln_type, | 125 | lp->lksb.sb_status, lp->lockname.ln_type, |
135 | lp->lockname.ln_number, lp->flags); | 126 | lp->lockname.ln_number, lp->flags); |
136 | return; | 127 | return; |
137 | } | 128 | } |
138 | 129 | ||
@@ -152,8 +143,10 @@ static void process_complete(struct gdlm_lock *lp) | |||
152 | */ | 143 | */ |
153 | 144 | ||
154 | if (test_and_clear_bit(LFL_REREQUEST, &lp->flags)) { | 145 | if (test_and_clear_bit(LFL_REREQUEST, &lp->flags)) { |
155 | GDLM_ASSERT(lp->req == DLM_LOCK_NL,); | 146 | gdlm_assert(lp->req == DLM_LOCK_NL, "%x,%llx", |
156 | GDLM_ASSERT(lp->prev_req > DLM_LOCK_NL,); | 147 | lp->lockname.ln_type, lp->lockname.ln_number); |
148 | gdlm_assert(lp->prev_req > DLM_LOCK_NL, "%x,%llx", | ||
149 | lp->lockname.ln_type, lp->lockname.ln_number); | ||
157 | 150 | ||
158 | lp->cur = DLM_LOCK_NL; | 151 | lp->cur = DLM_LOCK_NL; |
159 | lp->req = lp->prev_req; | 152 | lp->req = lp->prev_req; |
@@ -189,7 +182,7 @@ static void process_complete(struct gdlm_lock *lp) | |||
189 | lp->lkf |= DLM_LKF_CONVERT; | 182 | lp->lkf |= DLM_LKF_CONVERT; |
190 | lp->lkf &= ~DLM_LKF_CONVDEADLK; | 183 | lp->lkf &= ~DLM_LKF_CONVDEADLK; |
191 | 184 | ||
192 | log_debug("rereq %x,%"PRIx64" id %x %d,%d", | 185 | log_debug("rereq %x,%llx id %x %d,%d", |
193 | lp->lockname.ln_type, lp->lockname.ln_number, | 186 | lp->lockname.ln_type, lp->lockname.ln_number, |
194 | lp->lksb.sb_lkid, lp->cur, lp->req); | 187 | lp->lksb.sb_lkid, lp->cur, lp->req); |
195 | 188 | ||
@@ -315,7 +308,7 @@ static int gdlm_thread(void *data) | |||
315 | process_blocking(lp, blocking); | 308 | process_blocking(lp, blocking); |
316 | 309 | ||
317 | else if (submit) | 310 | else if (submit) |
318 | process_submit(lp); | 311 | gdlm_do_lock(lp, NULL); |
319 | 312 | ||
320 | if (drop) | 313 | if (drop) |
321 | ls->fscb(ls->fsdata, LM_CB_DROPLOCKS, NULL); | 314 | ls->fscb(ls->fsdata, LM_CB_DROPLOCKS, NULL); |
@@ -334,7 +327,7 @@ int gdlm_init_threads(struct gdlm_ls *ls) | |||
334 | p = kthread_run(gdlm_thread, ls, "lock_dlm1"); | 327 | p = kthread_run(gdlm_thread, ls, "lock_dlm1"); |
335 | error = IS_ERR(p); | 328 | error = IS_ERR(p); |
336 | if (error) { | 329 | if (error) { |
337 | log_all("can't start lock_dlm1 thread %d", error); | 330 | log_error("can't start lock_dlm1 thread %d", error); |
338 | return error; | 331 | return error; |
339 | } | 332 | } |
340 | ls->thread1 = p; | 333 | ls->thread1 = p; |
@@ -342,7 +335,7 @@ int gdlm_init_threads(struct gdlm_ls *ls) | |||
342 | p = kthread_run(gdlm_thread, ls, "lock_dlm2"); | 335 | p = kthread_run(gdlm_thread, ls, "lock_dlm2"); |
343 | error = IS_ERR(p); | 336 | error = IS_ERR(p); |
344 | if (error) { | 337 | if (error) { |
345 | log_all("can't start lock_dlm2 thread %d", error); | 338 | log_error("can't start lock_dlm2 thread %d", error); |
346 | kthread_stop(ls->thread1); | 339 | kthread_stop(ls->thread1); |
347 | return error; | 340 | return error; |
348 | } | 341 | } |