diff options
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/ast.c | 74 | ||||
-rw-r--r-- | fs/dlm/ast.h | 4 | ||||
-rw-r--r-- | fs/dlm/config.c | 1 | ||||
-rw-r--r-- | fs/dlm/debug_fs.c | 3 | ||||
-rw-r--r-- | fs/dlm/dlm_internal.h | 10 | ||||
-rw-r--r-- | fs/dlm/lock.c | 126 | ||||
-rw-r--r-- | fs/dlm/lockspace.c | 16 | ||||
-rw-r--r-- | fs/dlm/lowcomms.c | 1 | ||||
-rw-r--r-- | fs/dlm/member.c | 2 | ||||
-rw-r--r-- | fs/dlm/netlink.c | 1 | ||||
-rw-r--r-- | fs/dlm/plock.c | 1 | ||||
-rw-r--r-- | fs/dlm/user.c | 99 | ||||
-rw-r--r-- | fs/dlm/user.h | 4 |
13 files changed, 264 insertions, 78 deletions
diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index dc2ad6008b2d..4314f0d48d85 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c | |||
@@ -2,7 +2,7 @@ | |||
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. |
6 | ** | 6 | ** |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -33,10 +33,10 @@ void dlm_del_ast(struct dlm_lkb *lkb) | |||
33 | spin_unlock(&ast_queue_lock); | 33 | spin_unlock(&ast_queue_lock); |
34 | } | 34 | } |
35 | 35 | ||
36 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | 36 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int mode) |
37 | { | 37 | { |
38 | if (lkb->lkb_flags & DLM_IFL_USER) { | 38 | if (lkb->lkb_flags & DLM_IFL_USER) { |
39 | dlm_user_add_ast(lkb, type, bastmode); | 39 | dlm_user_add_ast(lkb, type, mode); |
40 | return; | 40 | return; |
41 | } | 41 | } |
42 | 42 | ||
@@ -44,10 +44,21 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | |||
44 | if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { | 44 | if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) { |
45 | kref_get(&lkb->lkb_ref); | 45 | kref_get(&lkb->lkb_ref); |
46 | list_add_tail(&lkb->lkb_astqueue, &ast_queue); | 46 | list_add_tail(&lkb->lkb_astqueue, &ast_queue); |
47 | lkb->lkb_ast_first = type; | ||
47 | } | 48 | } |
49 | |||
50 | /* sanity check, this should not happen */ | ||
51 | |||
52 | if ((type == AST_COMP) && (lkb->lkb_ast_type & AST_COMP)) | ||
53 | log_print("repeat cast %d castmode %d lock %x %s", | ||
54 | mode, lkb->lkb_castmode, | ||
55 | lkb->lkb_id, lkb->lkb_resource->res_name); | ||
56 | |||
48 | lkb->lkb_ast_type |= type; | 57 | lkb->lkb_ast_type |= type; |
49 | if (bastmode) | 58 | if (type == AST_BAST) |
50 | lkb->lkb_bastmode = bastmode; | 59 | lkb->lkb_bastmode = mode; |
60 | else | ||
61 | lkb->lkb_castmode = mode; | ||
51 | spin_unlock(&ast_queue_lock); | 62 | spin_unlock(&ast_queue_lock); |
52 | 63 | ||
53 | set_bit(WAKE_ASTS, &astd_wakeflags); | 64 | set_bit(WAKE_ASTS, &astd_wakeflags); |
@@ -59,9 +70,9 @@ static void process_asts(void) | |||
59 | struct dlm_ls *ls = NULL; | 70 | struct dlm_ls *ls = NULL; |
60 | struct dlm_rsb *r = NULL; | 71 | struct dlm_rsb *r = NULL; |
61 | struct dlm_lkb *lkb; | 72 | struct dlm_lkb *lkb; |
62 | void (*cast) (void *astparam); | 73 | void (*castfn) (void *astparam); |
63 | void (*bast) (void *astparam, int mode); | 74 | void (*bastfn) (void *astparam, int mode); |
64 | int type = 0, bastmode; | 75 | int type, first, bastmode, castmode, do_bast, do_cast, last_castmode; |
65 | 76 | ||
66 | repeat: | 77 | repeat: |
67 | spin_lock(&ast_queue_lock); | 78 | spin_lock(&ast_queue_lock); |
@@ -75,17 +86,48 @@ repeat: | |||
75 | list_del(&lkb->lkb_astqueue); | 86 | list_del(&lkb->lkb_astqueue); |
76 | type = lkb->lkb_ast_type; | 87 | type = lkb->lkb_ast_type; |
77 | lkb->lkb_ast_type = 0; | 88 | lkb->lkb_ast_type = 0; |
89 | first = lkb->lkb_ast_first; | ||
90 | lkb->lkb_ast_first = 0; | ||
78 | bastmode = lkb->lkb_bastmode; | 91 | bastmode = lkb->lkb_bastmode; |
79 | 92 | castmode = lkb->lkb_castmode; | |
93 | castfn = lkb->lkb_astfn; | ||
94 | bastfn = lkb->lkb_bastfn; | ||
80 | spin_unlock(&ast_queue_lock); | 95 | spin_unlock(&ast_queue_lock); |
81 | cast = lkb->lkb_astfn; | ||
82 | bast = lkb->lkb_bastfn; | ||
83 | |||
84 | if ((type & AST_COMP) && cast) | ||
85 | cast(lkb->lkb_astparam); | ||
86 | 96 | ||
87 | if ((type & AST_BAST) && bast) | 97 | do_cast = (type & AST_COMP) && castfn; |
88 | bast(lkb->lkb_astparam, bastmode); | 98 | do_bast = (type & AST_BAST) && bastfn; |
99 | |||
100 | /* Skip a bast if its blocking mode is compatible with the | ||
101 | granted mode of the preceding cast. */ | ||
102 | |||
103 | if (do_bast) { | ||
104 | if (first == AST_COMP) | ||
105 | last_castmode = castmode; | ||
106 | else | ||
107 | last_castmode = lkb->lkb_castmode_done; | ||
108 | if (dlm_modes_compat(bastmode, last_castmode)) | ||
109 | do_bast = 0; | ||
110 | } | ||
111 | |||
112 | if (first == AST_COMP) { | ||
113 | if (do_cast) | ||
114 | castfn(lkb->lkb_astparam); | ||
115 | if (do_bast) | ||
116 | bastfn(lkb->lkb_astparam, bastmode); | ||
117 | } else if (first == AST_BAST) { | ||
118 | if (do_bast) | ||
119 | bastfn(lkb->lkb_astparam, bastmode); | ||
120 | if (do_cast) | ||
121 | castfn(lkb->lkb_astparam); | ||
122 | } else { | ||
123 | log_error(ls, "bad ast_first %d ast_type %d", | ||
124 | first, type); | ||
125 | } | ||
126 | |||
127 | if (do_cast) | ||
128 | lkb->lkb_castmode_done = castmode; | ||
129 | if (do_bast) | ||
130 | lkb->lkb_bastmode_done = bastmode; | ||
89 | 131 | ||
90 | /* this removes the reference added by dlm_add_ast | 132 | /* this removes the reference added by dlm_add_ast |
91 | and may result in the lkb being freed */ | 133 | and may result in the lkb being freed */ |
diff --git a/fs/dlm/ast.h b/fs/dlm/ast.h index 1b5fc5f428fd..bcb1aaba519d 100644 --- a/fs/dlm/ast.h +++ b/fs/dlm/ast.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. | 4 | ** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved. |
5 | ** | 5 | ** |
6 | ** This copyrighted material is made available to anyone wishing to use, | 6 | ** This copyrighted material is made available to anyone wishing to use, |
7 | ** modify, copy, or redistribute it subject to the terms and conditions | 7 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __ASTD_DOT_H__ | 13 | #ifndef __ASTD_DOT_H__ |
14 | #define __ASTD_DOT_H__ | 14 | #define __ASTD_DOT_H__ |
15 | 15 | ||
16 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode); | 16 | void dlm_add_ast(struct dlm_lkb *lkb, int type, int mode); |
17 | void dlm_del_ast(struct dlm_lkb *lkb); | 17 | void dlm_del_ast(struct dlm_lkb *lkb); |
18 | 18 | ||
19 | void dlm_astd_wake(void); | 19 | void dlm_astd_wake(void); |
diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 0df243850818..b54bca03d92f 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/configfs.h> | 16 | #include <linux/configfs.h> |
17 | #include <linux/slab.h> | ||
17 | #include <linux/in.h> | 18 | #include <linux/in.h> |
18 | #include <linux/in6.h> | 19 | #include <linux/in6.h> |
19 | #include <net/ipv6.h> | 20 | #include <net/ipv6.h> |
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 375a2359b3bf..c6cf25158746 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
17 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
18 | #include <linux/slab.h> | ||
18 | 19 | ||
19 | #include "dlm_internal.h" | 20 | #include "dlm_internal.h" |
20 | #include "lock.h" | 21 | #include "lock.h" |
@@ -256,7 +257,7 @@ static int print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb, | |||
256 | lkb->lkb_status, | 257 | lkb->lkb_status, |
257 | lkb->lkb_grmode, | 258 | lkb->lkb_grmode, |
258 | lkb->lkb_rqmode, | 259 | lkb->lkb_rqmode, |
259 | lkb->lkb_highbast, | 260 | lkb->lkb_bastmode, |
260 | rsb_lookup, | 261 | rsb_lookup, |
261 | lkb->lkb_wait_type, | 262 | lkb->lkb_wait_type, |
262 | lkb->lkb_lvbseq, | 263 | lkb->lkb_lvbseq, |
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 826d3dc6e0ab..f632b58cd222 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -2,7 +2,7 @@ | |||
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
5 | ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. |
6 | ** | 6 | ** |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -232,11 +232,17 @@ struct dlm_lkb { | |||
232 | int8_t lkb_status; /* granted, waiting, convert */ | 232 | int8_t lkb_status; /* granted, waiting, convert */ |
233 | int8_t lkb_rqmode; /* requested lock mode */ | 233 | int8_t lkb_rqmode; /* requested lock mode */ |
234 | int8_t lkb_grmode; /* granted lock mode */ | 234 | int8_t lkb_grmode; /* granted lock mode */ |
235 | int8_t lkb_bastmode; /* requested mode */ | ||
236 | int8_t lkb_highbast; /* highest mode bast sent for */ | 235 | int8_t lkb_highbast; /* highest mode bast sent for */ |
236 | |||
237 | int8_t lkb_wait_type; /* type of reply waiting for */ | 237 | int8_t lkb_wait_type; /* type of reply waiting for */ |
238 | int8_t lkb_wait_count; | 238 | int8_t lkb_wait_count; |
239 | int8_t lkb_ast_type; /* type of ast queued for */ | 239 | int8_t lkb_ast_type; /* type of ast queued for */ |
240 | int8_t lkb_ast_first; /* type of first ast queued */ | ||
241 | |||
242 | int8_t lkb_bastmode; /* req mode of queued bast */ | ||
243 | int8_t lkb_castmode; /* gr mode of queued cast */ | ||
244 | int8_t lkb_bastmode_done; /* last delivered bastmode */ | ||
245 | int8_t lkb_castmode_done; /* last delivered castmode */ | ||
240 | 246 | ||
241 | struct list_head lkb_idtbl_list; /* lockspace lkbtbl */ | 247 | struct list_head lkb_idtbl_list; /* lockspace lkbtbl */ |
242 | struct list_head lkb_statequeue; /* rsb g/c/w list */ | 248 | struct list_head lkb_statequeue; /* rsb g/c/w list */ |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 9c0c1db1e105..031dbe3a15ca 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. | 4 | ** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved. |
5 | ** | 5 | ** |
6 | ** This copyrighted material is made available to anyone wishing to use, | 6 | ** This copyrighted material is made available to anyone wishing to use, |
7 | ** modify, copy, or redistribute it subject to the terms and conditions | 7 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -56,6 +56,7 @@ | |||
56 | L: receive_xxxx_reply() <- R: send_xxxx_reply() | 56 | L: receive_xxxx_reply() <- R: send_xxxx_reply() |
57 | */ | 57 | */ |
58 | #include <linux/types.h> | 58 | #include <linux/types.h> |
59 | #include <linux/slab.h> | ||
59 | #include "dlm_internal.h" | 60 | #include "dlm_internal.h" |
60 | #include <linux/dlm_device.h> | 61 | #include <linux/dlm_device.h> |
61 | #include "memory.h" | 62 | #include "memory.h" |
@@ -307,7 +308,7 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv) | |||
307 | lkb->lkb_lksb->sb_status = rv; | 308 | lkb->lkb_lksb->sb_status = rv; |
308 | lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; | 309 | lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; |
309 | 310 | ||
310 | dlm_add_ast(lkb, AST_COMP, 0); | 311 | dlm_add_ast(lkb, AST_COMP, lkb->lkb_grmode); |
311 | } | 312 | } |
312 | 313 | ||
313 | static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) | 314 | static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) |
@@ -320,10 +321,12 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode) | |||
320 | { | 321 | { |
321 | lkb->lkb_time_bast = ktime_get(); | 322 | lkb->lkb_time_bast = ktime_get(); |
322 | 323 | ||
323 | if (is_master_copy(lkb)) | 324 | if (is_master_copy(lkb)) { |
325 | lkb->lkb_bastmode = rqmode; /* printed by debugfs */ | ||
324 | send_bast(r, lkb, rqmode); | 326 | send_bast(r, lkb, rqmode); |
325 | else | 327 | } else { |
326 | dlm_add_ast(lkb, AST_BAST, rqmode); | 328 | dlm_add_ast(lkb, AST_BAST, rqmode); |
329 | } | ||
327 | } | 330 | } |
328 | 331 | ||
329 | /* | 332 | /* |
@@ -730,10 +733,7 @@ static void lkb_add_ordered(struct list_head *new, struct list_head *head, | |||
730 | if (lkb->lkb_rqmode < mode) | 733 | if (lkb->lkb_rqmode < mode) |
731 | break; | 734 | break; |
732 | 735 | ||
733 | if (!lkb) | 736 | __list_add(new, lkb->lkb_statequeue.prev, &lkb->lkb_statequeue); |
734 | list_add_tail(new, head); | ||
735 | else | ||
736 | __list_add(new, lkb->lkb_statequeue.prev, &lkb->lkb_statequeue); | ||
737 | } | 737 | } |
738 | 738 | ||
739 | /* add/remove lkb to rsb's grant/convert/wait queue */ | 739 | /* add/remove lkb to rsb's grant/convert/wait queue */ |
@@ -2280,20 +2280,30 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2280 | if (can_be_queued(lkb)) { | 2280 | if (can_be_queued(lkb)) { |
2281 | error = -EINPROGRESS; | 2281 | error = -EINPROGRESS; |
2282 | add_lkb(r, lkb, DLM_LKSTS_WAITING); | 2282 | add_lkb(r, lkb, DLM_LKSTS_WAITING); |
2283 | send_blocking_asts(r, lkb); | ||
2284 | add_timeout(lkb); | 2283 | add_timeout(lkb); |
2285 | goto out; | 2284 | goto out; |
2286 | } | 2285 | } |
2287 | 2286 | ||
2288 | error = -EAGAIN; | 2287 | error = -EAGAIN; |
2289 | if (force_blocking_asts(lkb)) | ||
2290 | send_blocking_asts_all(r, lkb); | ||
2291 | queue_cast(r, lkb, -EAGAIN); | 2288 | queue_cast(r, lkb, -EAGAIN); |
2292 | |||
2293 | out: | 2289 | out: |
2294 | return error; | 2290 | return error; |
2295 | } | 2291 | } |
2296 | 2292 | ||
2293 | static void do_request_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2294 | int error) | ||
2295 | { | ||
2296 | switch (error) { | ||
2297 | case -EAGAIN: | ||
2298 | if (force_blocking_asts(lkb)) | ||
2299 | send_blocking_asts_all(r, lkb); | ||
2300 | break; | ||
2301 | case -EINPROGRESS: | ||
2302 | send_blocking_asts(r, lkb); | ||
2303 | break; | ||
2304 | } | ||
2305 | } | ||
2306 | |||
2297 | static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2307 | static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) |
2298 | { | 2308 | { |
2299 | int error = 0; | 2309 | int error = 0; |
@@ -2304,7 +2314,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2304 | if (can_be_granted(r, lkb, 1, &deadlk)) { | 2314 | if (can_be_granted(r, lkb, 1, &deadlk)) { |
2305 | grant_lock(r, lkb); | 2315 | grant_lock(r, lkb); |
2306 | queue_cast(r, lkb, 0); | 2316 | queue_cast(r, lkb, 0); |
2307 | grant_pending_locks(r); | ||
2308 | goto out; | 2317 | goto out; |
2309 | } | 2318 | } |
2310 | 2319 | ||
@@ -2334,7 +2343,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2334 | if (_can_be_granted(r, lkb, 1)) { | 2343 | if (_can_be_granted(r, lkb, 1)) { |
2335 | grant_lock(r, lkb); | 2344 | grant_lock(r, lkb); |
2336 | queue_cast(r, lkb, 0); | 2345 | queue_cast(r, lkb, 0); |
2337 | grant_pending_locks(r); | ||
2338 | goto out; | 2346 | goto out; |
2339 | } | 2347 | } |
2340 | /* else fall through and move to convert queue */ | 2348 | /* else fall through and move to convert queue */ |
@@ -2344,28 +2352,47 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2344 | error = -EINPROGRESS; | 2352 | error = -EINPROGRESS; |
2345 | del_lkb(r, lkb); | 2353 | del_lkb(r, lkb); |
2346 | add_lkb(r, lkb, DLM_LKSTS_CONVERT); | 2354 | add_lkb(r, lkb, DLM_LKSTS_CONVERT); |
2347 | send_blocking_asts(r, lkb); | ||
2348 | add_timeout(lkb); | 2355 | add_timeout(lkb); |
2349 | goto out; | 2356 | goto out; |
2350 | } | 2357 | } |
2351 | 2358 | ||
2352 | error = -EAGAIN; | 2359 | error = -EAGAIN; |
2353 | if (force_blocking_asts(lkb)) | ||
2354 | send_blocking_asts_all(r, lkb); | ||
2355 | queue_cast(r, lkb, -EAGAIN); | 2360 | queue_cast(r, lkb, -EAGAIN); |
2356 | |||
2357 | out: | 2361 | out: |
2358 | return error; | 2362 | return error; |
2359 | } | 2363 | } |
2360 | 2364 | ||
2365 | static void do_convert_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2366 | int error) | ||
2367 | { | ||
2368 | switch (error) { | ||
2369 | case 0: | ||
2370 | grant_pending_locks(r); | ||
2371 | /* grant_pending_locks also sends basts */ | ||
2372 | break; | ||
2373 | case -EAGAIN: | ||
2374 | if (force_blocking_asts(lkb)) | ||
2375 | send_blocking_asts_all(r, lkb); | ||
2376 | break; | ||
2377 | case -EINPROGRESS: | ||
2378 | send_blocking_asts(r, lkb); | ||
2379 | break; | ||
2380 | } | ||
2381 | } | ||
2382 | |||
2361 | static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2383 | static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) |
2362 | { | 2384 | { |
2363 | remove_lock(r, lkb); | 2385 | remove_lock(r, lkb); |
2364 | queue_cast(r, lkb, -DLM_EUNLOCK); | 2386 | queue_cast(r, lkb, -DLM_EUNLOCK); |
2365 | grant_pending_locks(r); | ||
2366 | return -DLM_EUNLOCK; | 2387 | return -DLM_EUNLOCK; |
2367 | } | 2388 | } |
2368 | 2389 | ||
2390 | static void do_unlock_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2391 | int error) | ||
2392 | { | ||
2393 | grant_pending_locks(r); | ||
2394 | } | ||
2395 | |||
2369 | /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ | 2396 | /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ |
2370 | 2397 | ||
2371 | static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2398 | static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) |
@@ -2375,12 +2402,18 @@ static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2375 | error = revert_lock(r, lkb); | 2402 | error = revert_lock(r, lkb); |
2376 | if (error) { | 2403 | if (error) { |
2377 | queue_cast(r, lkb, -DLM_ECANCEL); | 2404 | queue_cast(r, lkb, -DLM_ECANCEL); |
2378 | grant_pending_locks(r); | ||
2379 | return -DLM_ECANCEL; | 2405 | return -DLM_ECANCEL; |
2380 | } | 2406 | } |
2381 | return 0; | 2407 | return 0; |
2382 | } | 2408 | } |
2383 | 2409 | ||
2410 | static void do_cancel_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2411 | int error) | ||
2412 | { | ||
2413 | if (error) | ||
2414 | grant_pending_locks(r); | ||
2415 | } | ||
2416 | |||
2384 | /* | 2417 | /* |
2385 | * Four stage 3 varieties: | 2418 | * Four stage 3 varieties: |
2386 | * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() | 2419 | * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() |
@@ -2402,11 +2435,15 @@ static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2402 | goto out; | 2435 | goto out; |
2403 | } | 2436 | } |
2404 | 2437 | ||
2405 | if (is_remote(r)) | 2438 | if (is_remote(r)) { |
2406 | /* receive_request() calls do_request() on remote node */ | 2439 | /* receive_request() calls do_request() on remote node */ |
2407 | error = send_request(r, lkb); | 2440 | error = send_request(r, lkb); |
2408 | else | 2441 | } else { |
2409 | error = do_request(r, lkb); | 2442 | error = do_request(r, lkb); |
2443 | /* for remote locks the request_reply is sent | ||
2444 | between do_request and do_request_effects */ | ||
2445 | do_request_effects(r, lkb, error); | ||
2446 | } | ||
2410 | out: | 2447 | out: |
2411 | return error; | 2448 | return error; |
2412 | } | 2449 | } |
@@ -2417,11 +2454,15 @@ static int _convert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2417 | { | 2454 | { |
2418 | int error; | 2455 | int error; |
2419 | 2456 | ||
2420 | if (is_remote(r)) | 2457 | if (is_remote(r)) { |
2421 | /* receive_convert() calls do_convert() on remote node */ | 2458 | /* receive_convert() calls do_convert() on remote node */ |
2422 | error = send_convert(r, lkb); | 2459 | error = send_convert(r, lkb); |
2423 | else | 2460 | } else { |
2424 | error = do_convert(r, lkb); | 2461 | error = do_convert(r, lkb); |
2462 | /* for remote locks the convert_reply is sent | ||
2463 | between do_convert and do_convert_effects */ | ||
2464 | do_convert_effects(r, lkb, error); | ||
2465 | } | ||
2425 | 2466 | ||
2426 | return error; | 2467 | return error; |
2427 | } | 2468 | } |
@@ -2432,11 +2473,15 @@ static int _unlock_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2432 | { | 2473 | { |
2433 | int error; | 2474 | int error; |
2434 | 2475 | ||
2435 | if (is_remote(r)) | 2476 | if (is_remote(r)) { |
2436 | /* receive_unlock() calls do_unlock() on remote node */ | 2477 | /* receive_unlock() calls do_unlock() on remote node */ |
2437 | error = send_unlock(r, lkb); | 2478 | error = send_unlock(r, lkb); |
2438 | else | 2479 | } else { |
2439 | error = do_unlock(r, lkb); | 2480 | error = do_unlock(r, lkb); |
2481 | /* for remote locks the unlock_reply is sent | ||
2482 | between do_unlock and do_unlock_effects */ | ||
2483 | do_unlock_effects(r, lkb, error); | ||
2484 | } | ||
2440 | 2485 | ||
2441 | return error; | 2486 | return error; |
2442 | } | 2487 | } |
@@ -2447,11 +2492,15 @@ static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2447 | { | 2492 | { |
2448 | int error; | 2493 | int error; |
2449 | 2494 | ||
2450 | if (is_remote(r)) | 2495 | if (is_remote(r)) { |
2451 | /* receive_cancel() calls do_cancel() on remote node */ | 2496 | /* receive_cancel() calls do_cancel() on remote node */ |
2452 | error = send_cancel(r, lkb); | 2497 | error = send_cancel(r, lkb); |
2453 | else | 2498 | } else { |
2454 | error = do_cancel(r, lkb); | 2499 | error = do_cancel(r, lkb); |
2500 | /* for remote locks the cancel_reply is sent | ||
2501 | between do_cancel and do_cancel_effects */ | ||
2502 | do_cancel_effects(r, lkb, error); | ||
2503 | } | ||
2455 | 2504 | ||
2456 | return error; | 2505 | return error; |
2457 | } | 2506 | } |
@@ -3191,6 +3240,7 @@ static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) | |||
3191 | attach_lkb(r, lkb); | 3240 | attach_lkb(r, lkb); |
3192 | error = do_request(r, lkb); | 3241 | error = do_request(r, lkb); |
3193 | send_request_reply(r, lkb, error); | 3242 | send_request_reply(r, lkb, error); |
3243 | do_request_effects(r, lkb, error); | ||
3194 | 3244 | ||
3195 | unlock_rsb(r); | 3245 | unlock_rsb(r); |
3196 | put_rsb(r); | 3246 | put_rsb(r); |
@@ -3226,15 +3276,19 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms) | |||
3226 | goto out; | 3276 | goto out; |
3227 | 3277 | ||
3228 | receive_flags(lkb, ms); | 3278 | receive_flags(lkb, ms); |
3279 | |||
3229 | error = receive_convert_args(ls, lkb, ms); | 3280 | error = receive_convert_args(ls, lkb, ms); |
3230 | if (error) | 3281 | if (error) { |
3231 | goto out_reply; | 3282 | send_convert_reply(r, lkb, error); |
3283 | goto out; | ||
3284 | } | ||
3285 | |||
3232 | reply = !down_conversion(lkb); | 3286 | reply = !down_conversion(lkb); |
3233 | 3287 | ||
3234 | error = do_convert(r, lkb); | 3288 | error = do_convert(r, lkb); |
3235 | out_reply: | ||
3236 | if (reply) | 3289 | if (reply) |
3237 | send_convert_reply(r, lkb, error); | 3290 | send_convert_reply(r, lkb, error); |
3291 | do_convert_effects(r, lkb, error); | ||
3238 | out: | 3292 | out: |
3239 | unlock_rsb(r); | 3293 | unlock_rsb(r); |
3240 | put_rsb(r); | 3294 | put_rsb(r); |
@@ -3266,13 +3320,16 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms) | |||
3266 | goto out; | 3320 | goto out; |
3267 | 3321 | ||
3268 | receive_flags(lkb, ms); | 3322 | receive_flags(lkb, ms); |
3323 | |||
3269 | error = receive_unlock_args(ls, lkb, ms); | 3324 | error = receive_unlock_args(ls, lkb, ms); |
3270 | if (error) | 3325 | if (error) { |
3271 | goto out_reply; | 3326 | send_unlock_reply(r, lkb, error); |
3327 | goto out; | ||
3328 | } | ||
3272 | 3329 | ||
3273 | error = do_unlock(r, lkb); | 3330 | error = do_unlock(r, lkb); |
3274 | out_reply: | ||
3275 | send_unlock_reply(r, lkb, error); | 3331 | send_unlock_reply(r, lkb, error); |
3332 | do_unlock_effects(r, lkb, error); | ||
3276 | out: | 3333 | out: |
3277 | unlock_rsb(r); | 3334 | unlock_rsb(r); |
3278 | put_rsb(r); | 3335 | put_rsb(r); |
@@ -3307,6 +3364,7 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms) | |||
3307 | 3364 | ||
3308 | error = do_cancel(r, lkb); | 3365 | error = do_cancel(r, lkb); |
3309 | send_cancel_reply(r, lkb, error); | 3366 | send_cancel_reply(r, lkb, error); |
3367 | do_cancel_effects(r, lkb, error); | ||
3310 | out: | 3368 | out: |
3311 | unlock_rsb(r); | 3369 | unlock_rsb(r); |
3312 | put_rsb(r); | 3370 | put_rsb(r); |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index c010ecfc0d29..f994a7dfda85 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -148,7 +148,7 @@ static void lockspace_kobj_release(struct kobject *k) | |||
148 | kfree(ls); | 148 | kfree(ls); |
149 | } | 149 | } |
150 | 150 | ||
151 | static struct sysfs_ops dlm_attr_ops = { | 151 | static const struct sysfs_ops dlm_attr_ops = { |
152 | .show = dlm_attr_show, | 152 | .show = dlm_attr_show, |
153 | .store = dlm_attr_store, | 153 | .store = dlm_attr_store, |
154 | }; | 154 | }; |
@@ -191,6 +191,18 @@ static int do_uevent(struct dlm_ls *ls, int in) | |||
191 | return error; | 191 | return error; |
192 | } | 192 | } |
193 | 193 | ||
194 | static int dlm_uevent(struct kset *kset, struct kobject *kobj, | ||
195 | struct kobj_uevent_env *env) | ||
196 | { | ||
197 | struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj); | ||
198 | |||
199 | add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static struct kset_uevent_ops dlm_uevent_ops = { | ||
204 | .uevent = dlm_uevent, | ||
205 | }; | ||
194 | 206 | ||
195 | int __init dlm_lockspace_init(void) | 207 | int __init dlm_lockspace_init(void) |
196 | { | 208 | { |
@@ -199,7 +211,7 @@ int __init dlm_lockspace_init(void) | |||
199 | INIT_LIST_HEAD(&lslist); | 211 | INIT_LIST_HEAD(&lslist); |
200 | spin_lock_init(&lslist_lock); | 212 | spin_lock_init(&lslist_lock); |
201 | 213 | ||
202 | dlm_kset = kset_create_and_add("dlm", NULL, kernel_kobj); | 214 | dlm_kset = kset_create_and_add("dlm", &dlm_uevent_ops, kernel_kobj); |
203 | if (!dlm_kset) { | 215 | if (!dlm_kset) { |
204 | printk(KERN_WARNING "%s: can not create kset\n", __func__); | 216 | printk(KERN_WARNING "%s: can not create kset\n", __func__); |
205 | return -ENOMEM; | 217 | return -ENOMEM; |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 52cab160893c..c0d35c620526 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/file.h> | 51 | #include <linux/file.h> |
52 | #include <linux/mutex.h> | 52 | #include <linux/mutex.h> |
53 | #include <linux/sctp.h> | 53 | #include <linux/sctp.h> |
54 | #include <linux/slab.h> | ||
54 | #include <net/sctp/user.h> | 55 | #include <net/sctp/user.h> |
55 | #include <net/ipv6.h> | 56 | #include <net/ipv6.h> |
56 | 57 | ||
diff --git a/fs/dlm/member.c b/fs/dlm/member.c index 84f70bfb0baf..b12532e553f8 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c | |||
@@ -312,7 +312,7 @@ int dlm_ls_stop(struct dlm_ls *ls) | |||
312 | /* | 312 | /* |
313 | * This in_recovery lock does two things: | 313 | * This in_recovery lock does two things: |
314 | * 1) Keeps this function from returning until all threads are out | 314 | * 1) Keeps this function from returning until all threads are out |
315 | * of locking routines and locking is truely stopped. | 315 | * of locking routines and locking is truly stopped. |
316 | * 2) Keeps any new requests from being processed until it's unlocked | 316 | * 2) Keeps any new requests from being processed until it's unlocked |
317 | * when recovery is complete. | 317 | * when recovery is complete. |
318 | */ | 318 | */ |
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c index 052095cd592f..2c6ad518100d 100644 --- a/fs/dlm/netlink.c +++ b/fs/dlm/netlink.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <net/genetlink.h> | 9 | #include <net/genetlink.h> |
10 | #include <linux/dlm.h> | 10 | #include <linux/dlm.h> |
11 | #include <linux/dlm_netlink.h> | 11 | #include <linux/dlm_netlink.h> |
12 | #include <linux/gfp.h> | ||
12 | 13 | ||
13 | #include "dlm_internal.h" | 14 | #include "dlm_internal.h" |
14 | 15 | ||
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index b5f89aef3b29..d45c02db6943 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/poll.h> | 11 | #include <linux/poll.h> |
12 | #include <linux/dlm.h> | 12 | #include <linux/dlm.h> |
13 | #include <linux/dlm_plock.h> | 13 | #include <linux/dlm_plock.h> |
14 | #include <linux/slab.h> | ||
14 | 15 | ||
15 | #include "dlm_internal.h" | 16 | #include "dlm_internal.h" |
16 | #include "lockspace.h" | 17 | #include "lockspace.h" |
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index e73a4bb572aa..b6272853130c 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/dlm.h> | 18 | #include <linux/dlm.h> |
19 | #include <linux/dlm_device.h> | 19 | #include <linux/dlm_device.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | #include "dlm_internal.h" | 22 | #include "dlm_internal.h" |
22 | #include "lockspace.h" | 23 | #include "lockspace.h" |
@@ -173,7 +174,7 @@ static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type) | |||
173 | /* we could possibly check if the cancel of an orphan has resulted in the lkb | 174 | /* we could possibly check if the cancel of an orphan has resulted in the lkb |
174 | being removed and then remove that lkb from the orphans list and free it */ | 175 | being removed and then remove that lkb from the orphans list and free it */ |
175 | 176 | ||
176 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | 177 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int mode) |
177 | { | 178 | { |
178 | struct dlm_ls *ls; | 179 | struct dlm_ls *ls; |
179 | struct dlm_user_args *ua; | 180 | struct dlm_user_args *ua; |
@@ -206,12 +207,15 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | |||
206 | 207 | ||
207 | ast_type = lkb->lkb_ast_type; | 208 | ast_type = lkb->lkb_ast_type; |
208 | lkb->lkb_ast_type |= type; | 209 | lkb->lkb_ast_type |= type; |
209 | if (bastmode) | 210 | if (type == AST_BAST) |
210 | lkb->lkb_bastmode = bastmode; | 211 | lkb->lkb_bastmode = mode; |
212 | else | ||
213 | lkb->lkb_castmode = mode; | ||
211 | 214 | ||
212 | if (!ast_type) { | 215 | if (!ast_type) { |
213 | kref_get(&lkb->lkb_ref); | 216 | kref_get(&lkb->lkb_ref); |
214 | list_add_tail(&lkb->lkb_astqueue, &proc->asts); | 217 | list_add_tail(&lkb->lkb_astqueue, &proc->asts); |
218 | lkb->lkb_ast_first = type; | ||
215 | wake_up_interruptible(&proc->wait); | 219 | wake_up_interruptible(&proc->wait); |
216 | } | 220 | } |
217 | if (type == AST_COMP && (ast_type & AST_COMP)) | 221 | if (type == AST_COMP && (ast_type & AST_COMP)) |
@@ -220,7 +224,6 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode) | |||
220 | 224 | ||
221 | eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type); | 225 | eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type); |
222 | if (eol) { | 226 | if (eol) { |
223 | lkb->lkb_ast_type &= ~AST_BAST; | ||
224 | lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; | 227 | lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; |
225 | } | 228 | } |
226 | 229 | ||
@@ -703,7 +706,7 @@ static int device_close(struct inode *inode, struct file *file) | |||
703 | } | 706 | } |
704 | 707 | ||
705 | static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type, | 708 | static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type, |
706 | int bmode, char __user *buf, size_t count) | 709 | int mode, char __user *buf, size_t count) |
707 | { | 710 | { |
708 | #ifdef CONFIG_COMPAT | 711 | #ifdef CONFIG_COMPAT |
709 | struct dlm_lock_result32 result32; | 712 | struct dlm_lock_result32 result32; |
@@ -730,7 +733,7 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type, | |||
730 | if (type == AST_BAST) { | 733 | if (type == AST_BAST) { |
731 | result.user_astaddr = ua->bastaddr; | 734 | result.user_astaddr = ua->bastaddr; |
732 | result.user_astparam = ua->bastparam; | 735 | result.user_astparam = ua->bastparam; |
733 | result.bast_mode = bmode; | 736 | result.bast_mode = mode; |
734 | } else { | 737 | } else { |
735 | result.user_astaddr = ua->castaddr; | 738 | result.user_astaddr = ua->castaddr; |
736 | result.user_astparam = ua->castparam; | 739 | result.user_astparam = ua->castparam; |
@@ -798,7 +801,9 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, | |||
798 | struct dlm_user_proc *proc = file->private_data; | 801 | struct dlm_user_proc *proc = file->private_data; |
799 | struct dlm_lkb *lkb; | 802 | struct dlm_lkb *lkb; |
800 | DECLARE_WAITQUEUE(wait, current); | 803 | DECLARE_WAITQUEUE(wait, current); |
801 | int error, type=0, bmode=0, removed = 0; | 804 | int error = 0, removed; |
805 | int ret_type, ret_mode; | ||
806 | int bastmode, castmode, do_bast, do_cast; | ||
802 | 807 | ||
803 | if (count == sizeof(struct dlm_device_version)) { | 808 | if (count == sizeof(struct dlm_device_version)) { |
804 | error = copy_version_to_user(buf, count); | 809 | error = copy_version_to_user(buf, count); |
@@ -817,6 +822,8 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, | |||
817 | #endif | 822 | #endif |
818 | return -EINVAL; | 823 | return -EINVAL; |
819 | 824 | ||
825 | try_another: | ||
826 | |||
820 | /* do we really need this? can a read happen after a close? */ | 827 | /* do we really need this? can a read happen after a close? */ |
821 | if (test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags)) | 828 | if (test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags)) |
822 | return -EINVAL; | 829 | return -EINVAL; |
@@ -852,13 +859,55 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, | |||
852 | 859 | ||
853 | lkb = list_entry(proc->asts.next, struct dlm_lkb, lkb_astqueue); | 860 | lkb = list_entry(proc->asts.next, struct dlm_lkb, lkb_astqueue); |
854 | 861 | ||
855 | if (lkb->lkb_ast_type & AST_COMP) { | 862 | removed = 0; |
856 | lkb->lkb_ast_type &= ~AST_COMP; | 863 | ret_type = 0; |
857 | type = AST_COMP; | 864 | ret_mode = 0; |
858 | } else if (lkb->lkb_ast_type & AST_BAST) { | 865 | do_bast = lkb->lkb_ast_type & AST_BAST; |
859 | lkb->lkb_ast_type &= ~AST_BAST; | 866 | do_cast = lkb->lkb_ast_type & AST_COMP; |
860 | type = AST_BAST; | 867 | bastmode = lkb->lkb_bastmode; |
861 | bmode = lkb->lkb_bastmode; | 868 | castmode = lkb->lkb_castmode; |
869 | |||
870 | /* when both are queued figure out which to do first and | ||
871 | switch first so the other goes in the next read */ | ||
872 | |||
873 | if (do_cast && do_bast) { | ||
874 | if (lkb->lkb_ast_first == AST_COMP) { | ||
875 | ret_type = AST_COMP; | ||
876 | ret_mode = castmode; | ||
877 | lkb->lkb_ast_type &= ~AST_COMP; | ||
878 | lkb->lkb_ast_first = AST_BAST; | ||
879 | } else { | ||
880 | ret_type = AST_BAST; | ||
881 | ret_mode = bastmode; | ||
882 | lkb->lkb_ast_type &= ~AST_BAST; | ||
883 | lkb->lkb_ast_first = AST_COMP; | ||
884 | } | ||
885 | } else { | ||
886 | ret_type = lkb->lkb_ast_first; | ||
887 | ret_mode = (ret_type == AST_COMP) ? castmode : bastmode; | ||
888 | lkb->lkb_ast_type &= ~ret_type; | ||
889 | lkb->lkb_ast_first = 0; | ||
890 | } | ||
891 | |||
892 | /* if we're doing a bast but the bast is unnecessary, then | ||
893 | switch to do nothing or do a cast if that was needed next */ | ||
894 | |||
895 | if ((ret_type == AST_BAST) && | ||
896 | dlm_modes_compat(bastmode, lkb->lkb_castmode_done)) { | ||
897 | ret_type = 0; | ||
898 | ret_mode = 0; | ||
899 | |||
900 | if (do_cast) { | ||
901 | ret_type = AST_COMP; | ||
902 | ret_mode = castmode; | ||
903 | lkb->lkb_ast_type &= ~AST_COMP; | ||
904 | lkb->lkb_ast_first = 0; | ||
905 | } | ||
906 | } | ||
907 | |||
908 | if (lkb->lkb_ast_first != lkb->lkb_ast_type) { | ||
909 | log_print("device_read %x ast_first %x ast_type %x", | ||
910 | lkb->lkb_id, lkb->lkb_ast_first, lkb->lkb_ast_type); | ||
862 | } | 911 | } |
863 | 912 | ||
864 | if (!lkb->lkb_ast_type) { | 913 | if (!lkb->lkb_ast_type) { |
@@ -867,15 +916,29 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count, | |||
867 | } | 916 | } |
868 | spin_unlock(&proc->asts_spin); | 917 | spin_unlock(&proc->asts_spin); |
869 | 918 | ||
870 | error = copy_result_to_user(lkb->lkb_ua, | 919 | if (ret_type) { |
871 | test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), | 920 | error = copy_result_to_user(lkb->lkb_ua, |
872 | type, bmode, buf, count); | 921 | test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), |
922 | ret_type, ret_mode, buf, count); | ||
923 | |||
924 | if (ret_type == AST_COMP) | ||
925 | lkb->lkb_castmode_done = castmode; | ||
926 | if (ret_type == AST_BAST) | ||
927 | lkb->lkb_bastmode_done = bastmode; | ||
928 | } | ||
873 | 929 | ||
874 | /* removes reference for the proc->asts lists added by | 930 | /* removes reference for the proc->asts lists added by |
875 | dlm_user_add_ast() and may result in the lkb being freed */ | 931 | dlm_user_add_ast() and may result in the lkb being freed */ |
932 | |||
876 | if (removed) | 933 | if (removed) |
877 | dlm_put_lkb(lkb); | 934 | dlm_put_lkb(lkb); |
878 | 935 | ||
936 | /* the bast that was queued was eliminated (see unnecessary above), | ||
937 | leaving nothing to return */ | ||
938 | |||
939 | if (!ret_type) | ||
940 | goto try_another; | ||
941 | |||
879 | return error; | 942 | return error; |
880 | } | 943 | } |
881 | 944 | ||
diff --git a/fs/dlm/user.h b/fs/dlm/user.h index 1c9686492286..f196091dd7ff 100644 --- a/fs/dlm/user.h +++ b/fs/dlm/user.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. | 2 | * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * This copyrighted material is made available to anyone wishing to use, | 4 | * This copyrighted material is made available to anyone wishing to use, |
5 | * modify, copy, or redistribute it subject to the terms and conditions | 5 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -9,7 +9,7 @@ | |||
9 | #ifndef __USER_DOT_H__ | 9 | #ifndef __USER_DOT_H__ |
10 | #define __USER_DOT_H__ | 10 | #define __USER_DOT_H__ |
11 | 11 | ||
12 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode); | 12 | void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int mode); |
13 | int dlm_user_init(void); | 13 | int dlm_user_init(void); |
14 | void dlm_user_exit(void); | 14 | void dlm_user_exit(void); |
15 | int dlm_device_deregister(struct dlm_ls *ls); | 15 | int dlm_device_deregister(struct dlm_ls *ls); |