diff options
Diffstat (limited to 'fs/dlm/lock.c')
-rw-r--r-- | fs/dlm/lock.c | 127 |
1 files changed, 94 insertions, 33 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index eb507c453c5f..17903b491298 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 | /* |
@@ -2280,20 +2283,30 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2280 | if (can_be_queued(lkb)) { | 2283 | if (can_be_queued(lkb)) { |
2281 | error = -EINPROGRESS; | 2284 | error = -EINPROGRESS; |
2282 | add_lkb(r, lkb, DLM_LKSTS_WAITING); | 2285 | add_lkb(r, lkb, DLM_LKSTS_WAITING); |
2283 | send_blocking_asts(r, lkb); | ||
2284 | add_timeout(lkb); | 2286 | add_timeout(lkb); |
2285 | goto out; | 2287 | goto out; |
2286 | } | 2288 | } |
2287 | 2289 | ||
2288 | error = -EAGAIN; | 2290 | error = -EAGAIN; |
2289 | if (force_blocking_asts(lkb)) | ||
2290 | send_blocking_asts_all(r, lkb); | ||
2291 | queue_cast(r, lkb, -EAGAIN); | 2291 | queue_cast(r, lkb, -EAGAIN); |
2292 | |||
2293 | out: | 2292 | out: |
2294 | return error; | 2293 | return error; |
2295 | } | 2294 | } |
2296 | 2295 | ||
2296 | static void do_request_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2297 | int error) | ||
2298 | { | ||
2299 | switch (error) { | ||
2300 | case -EAGAIN: | ||
2301 | if (force_blocking_asts(lkb)) | ||
2302 | send_blocking_asts_all(r, lkb); | ||
2303 | break; | ||
2304 | case -EINPROGRESS: | ||
2305 | send_blocking_asts(r, lkb); | ||
2306 | break; | ||
2307 | } | ||
2308 | } | ||
2309 | |||
2297 | static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2310 | static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) |
2298 | { | 2311 | { |
2299 | int error = 0; | 2312 | int error = 0; |
@@ -2304,7 +2317,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2304 | if (can_be_granted(r, lkb, 1, &deadlk)) { | 2317 | if (can_be_granted(r, lkb, 1, &deadlk)) { |
2305 | grant_lock(r, lkb); | 2318 | grant_lock(r, lkb); |
2306 | queue_cast(r, lkb, 0); | 2319 | queue_cast(r, lkb, 0); |
2307 | grant_pending_locks(r); | ||
2308 | goto out; | 2320 | goto out; |
2309 | } | 2321 | } |
2310 | 2322 | ||
@@ -2334,7 +2346,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2334 | if (_can_be_granted(r, lkb, 1)) { | 2346 | if (_can_be_granted(r, lkb, 1)) { |
2335 | grant_lock(r, lkb); | 2347 | grant_lock(r, lkb); |
2336 | queue_cast(r, lkb, 0); | 2348 | queue_cast(r, lkb, 0); |
2337 | grant_pending_locks(r); | ||
2338 | goto out; | 2349 | goto out; |
2339 | } | 2350 | } |
2340 | /* else fall through and move to convert queue */ | 2351 | /* else fall through and move to convert queue */ |
@@ -2344,28 +2355,47 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2344 | error = -EINPROGRESS; | 2355 | error = -EINPROGRESS; |
2345 | del_lkb(r, lkb); | 2356 | del_lkb(r, lkb); |
2346 | add_lkb(r, lkb, DLM_LKSTS_CONVERT); | 2357 | add_lkb(r, lkb, DLM_LKSTS_CONVERT); |
2347 | send_blocking_asts(r, lkb); | ||
2348 | add_timeout(lkb); | 2358 | add_timeout(lkb); |
2349 | goto out; | 2359 | goto out; |
2350 | } | 2360 | } |
2351 | 2361 | ||
2352 | error = -EAGAIN; | 2362 | error = -EAGAIN; |
2353 | if (force_blocking_asts(lkb)) | ||
2354 | send_blocking_asts_all(r, lkb); | ||
2355 | queue_cast(r, lkb, -EAGAIN); | 2363 | queue_cast(r, lkb, -EAGAIN); |
2356 | |||
2357 | out: | 2364 | out: |
2358 | return error; | 2365 | return error; |
2359 | } | 2366 | } |
2360 | 2367 | ||
2368 | static void do_convert_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2369 | int error) | ||
2370 | { | ||
2371 | switch (error) { | ||
2372 | case 0: | ||
2373 | grant_pending_locks(r); | ||
2374 | /* grant_pending_locks also sends basts */ | ||
2375 | break; | ||
2376 | case -EAGAIN: | ||
2377 | if (force_blocking_asts(lkb)) | ||
2378 | send_blocking_asts_all(r, lkb); | ||
2379 | break; | ||
2380 | case -EINPROGRESS: | ||
2381 | send_blocking_asts(r, lkb); | ||
2382 | break; | ||
2383 | } | ||
2384 | } | ||
2385 | |||
2361 | static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2386 | static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) |
2362 | { | 2387 | { |
2363 | remove_lock(r, lkb); | 2388 | remove_lock(r, lkb); |
2364 | queue_cast(r, lkb, -DLM_EUNLOCK); | 2389 | queue_cast(r, lkb, -DLM_EUNLOCK); |
2365 | grant_pending_locks(r); | ||
2366 | return -DLM_EUNLOCK; | 2390 | return -DLM_EUNLOCK; |
2367 | } | 2391 | } |
2368 | 2392 | ||
2393 | static void do_unlock_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2394 | int error) | ||
2395 | { | ||
2396 | grant_pending_locks(r); | ||
2397 | } | ||
2398 | |||
2369 | /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ | 2399 | /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ |
2370 | 2400 | ||
2371 | static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2401 | static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) |
@@ -2375,12 +2405,18 @@ static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2375 | error = revert_lock(r, lkb); | 2405 | error = revert_lock(r, lkb); |
2376 | if (error) { | 2406 | if (error) { |
2377 | queue_cast(r, lkb, -DLM_ECANCEL); | 2407 | queue_cast(r, lkb, -DLM_ECANCEL); |
2378 | grant_pending_locks(r); | ||
2379 | return -DLM_ECANCEL; | 2408 | return -DLM_ECANCEL; |
2380 | } | 2409 | } |
2381 | return 0; | 2410 | return 0; |
2382 | } | 2411 | } |
2383 | 2412 | ||
2413 | static void do_cancel_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2414 | int error) | ||
2415 | { | ||
2416 | if (error) | ||
2417 | grant_pending_locks(r); | ||
2418 | } | ||
2419 | |||
2384 | /* | 2420 | /* |
2385 | * Four stage 3 varieties: | 2421 | * Four stage 3 varieties: |
2386 | * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() | 2422 | * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() |
@@ -2402,11 +2438,15 @@ static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2402 | goto out; | 2438 | goto out; |
2403 | } | 2439 | } |
2404 | 2440 | ||
2405 | if (is_remote(r)) | 2441 | if (is_remote(r)) { |
2406 | /* receive_request() calls do_request() on remote node */ | 2442 | /* receive_request() calls do_request() on remote node */ |
2407 | error = send_request(r, lkb); | 2443 | error = send_request(r, lkb); |
2408 | else | 2444 | } else { |
2409 | error = do_request(r, lkb); | 2445 | error = do_request(r, lkb); |
2446 | /* for remote locks the request_reply is sent | ||
2447 | between do_request and do_request_effects */ | ||
2448 | do_request_effects(r, lkb, error); | ||
2449 | } | ||
2410 | out: | 2450 | out: |
2411 | return error; | 2451 | return error; |
2412 | } | 2452 | } |
@@ -2417,11 +2457,15 @@ static int _convert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2417 | { | 2457 | { |
2418 | int error; | 2458 | int error; |
2419 | 2459 | ||
2420 | if (is_remote(r)) | 2460 | if (is_remote(r)) { |
2421 | /* receive_convert() calls do_convert() on remote node */ | 2461 | /* receive_convert() calls do_convert() on remote node */ |
2422 | error = send_convert(r, lkb); | 2462 | error = send_convert(r, lkb); |
2423 | else | 2463 | } else { |
2424 | error = do_convert(r, lkb); | 2464 | error = do_convert(r, lkb); |
2465 | /* for remote locks the convert_reply is sent | ||
2466 | between do_convert and do_convert_effects */ | ||
2467 | do_convert_effects(r, lkb, error); | ||
2468 | } | ||
2425 | 2469 | ||
2426 | return error; | 2470 | return error; |
2427 | } | 2471 | } |
@@ -2432,11 +2476,15 @@ static int _unlock_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2432 | { | 2476 | { |
2433 | int error; | 2477 | int error; |
2434 | 2478 | ||
2435 | if (is_remote(r)) | 2479 | if (is_remote(r)) { |
2436 | /* receive_unlock() calls do_unlock() on remote node */ | 2480 | /* receive_unlock() calls do_unlock() on remote node */ |
2437 | error = send_unlock(r, lkb); | 2481 | error = send_unlock(r, lkb); |
2438 | else | 2482 | } else { |
2439 | error = do_unlock(r, lkb); | 2483 | error = do_unlock(r, lkb); |
2484 | /* for remote locks the unlock_reply is sent | ||
2485 | between do_unlock and do_unlock_effects */ | ||
2486 | do_unlock_effects(r, lkb, error); | ||
2487 | } | ||
2440 | 2488 | ||
2441 | return error; | 2489 | return error; |
2442 | } | 2490 | } |
@@ -2447,11 +2495,15 @@ static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2447 | { | 2495 | { |
2448 | int error; | 2496 | int error; |
2449 | 2497 | ||
2450 | if (is_remote(r)) | 2498 | if (is_remote(r)) { |
2451 | /* receive_cancel() calls do_cancel() on remote node */ | 2499 | /* receive_cancel() calls do_cancel() on remote node */ |
2452 | error = send_cancel(r, lkb); | 2500 | error = send_cancel(r, lkb); |
2453 | else | 2501 | } else { |
2454 | error = do_cancel(r, lkb); | 2502 | error = do_cancel(r, lkb); |
2503 | /* for remote locks the cancel_reply is sent | ||
2504 | between do_cancel and do_cancel_effects */ | ||
2505 | do_cancel_effects(r, lkb, error); | ||
2506 | } | ||
2455 | 2507 | ||
2456 | return error; | 2508 | return error; |
2457 | } | 2509 | } |
@@ -2689,7 +2741,7 @@ static int _create_message(struct dlm_ls *ls, int mb_len, | |||
2689 | pass into lowcomms_commit and a message buffer (mb) that we | 2741 | pass into lowcomms_commit and a message buffer (mb) that we |
2690 | write our data into */ | 2742 | write our data into */ |
2691 | 2743 | ||
2692 | mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb); | 2744 | mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb); |
2693 | if (!mh) | 2745 | if (!mh) |
2694 | return -ENOBUFS; | 2746 | return -ENOBUFS; |
2695 | 2747 | ||
@@ -3191,6 +3243,7 @@ static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) | |||
3191 | attach_lkb(r, lkb); | 3243 | attach_lkb(r, lkb); |
3192 | error = do_request(r, lkb); | 3244 | error = do_request(r, lkb); |
3193 | send_request_reply(r, lkb, error); | 3245 | send_request_reply(r, lkb, error); |
3246 | do_request_effects(r, lkb, error); | ||
3194 | 3247 | ||
3195 | unlock_rsb(r); | 3248 | unlock_rsb(r); |
3196 | put_rsb(r); | 3249 | put_rsb(r); |
@@ -3226,15 +3279,19 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms) | |||
3226 | goto out; | 3279 | goto out; |
3227 | 3280 | ||
3228 | receive_flags(lkb, ms); | 3281 | receive_flags(lkb, ms); |
3282 | |||
3229 | error = receive_convert_args(ls, lkb, ms); | 3283 | error = receive_convert_args(ls, lkb, ms); |
3230 | if (error) | 3284 | if (error) { |
3231 | goto out_reply; | 3285 | send_convert_reply(r, lkb, error); |
3286 | goto out; | ||
3287 | } | ||
3288 | |||
3232 | reply = !down_conversion(lkb); | 3289 | reply = !down_conversion(lkb); |
3233 | 3290 | ||
3234 | error = do_convert(r, lkb); | 3291 | error = do_convert(r, lkb); |
3235 | out_reply: | ||
3236 | if (reply) | 3292 | if (reply) |
3237 | send_convert_reply(r, lkb, error); | 3293 | send_convert_reply(r, lkb, error); |
3294 | do_convert_effects(r, lkb, error); | ||
3238 | out: | 3295 | out: |
3239 | unlock_rsb(r); | 3296 | unlock_rsb(r); |
3240 | put_rsb(r); | 3297 | put_rsb(r); |
@@ -3266,13 +3323,16 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms) | |||
3266 | goto out; | 3323 | goto out; |
3267 | 3324 | ||
3268 | receive_flags(lkb, ms); | 3325 | receive_flags(lkb, ms); |
3326 | |||
3269 | error = receive_unlock_args(ls, lkb, ms); | 3327 | error = receive_unlock_args(ls, lkb, ms); |
3270 | if (error) | 3328 | if (error) { |
3271 | goto out_reply; | 3329 | send_unlock_reply(r, lkb, error); |
3330 | goto out; | ||
3331 | } | ||
3272 | 3332 | ||
3273 | error = do_unlock(r, lkb); | 3333 | error = do_unlock(r, lkb); |
3274 | out_reply: | ||
3275 | send_unlock_reply(r, lkb, error); | 3334 | send_unlock_reply(r, lkb, error); |
3335 | do_unlock_effects(r, lkb, error); | ||
3276 | out: | 3336 | out: |
3277 | unlock_rsb(r); | 3337 | unlock_rsb(r); |
3278 | put_rsb(r); | 3338 | put_rsb(r); |
@@ -3307,6 +3367,7 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms) | |||
3307 | 3367 | ||
3308 | error = do_cancel(r, lkb); | 3368 | error = do_cancel(r, lkb); |
3309 | send_cancel_reply(r, lkb, error); | 3369 | send_cancel_reply(r, lkb, error); |
3370 | do_cancel_effects(r, lkb, error); | ||
3310 | out: | 3371 | out: |
3311 | unlock_rsb(r); | 3372 | unlock_rsb(r); |
3312 | put_rsb(r); | 3373 | put_rsb(r); |
@@ -4512,7 +4573,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, | |||
4512 | } | 4573 | } |
4513 | 4574 | ||
4514 | if (flags & DLM_LKF_VALBLK) { | 4575 | if (flags & DLM_LKF_VALBLK) { |
4515 | ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); | 4576 | ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS); |
4516 | if (!ua->lksb.sb_lvbptr) { | 4577 | if (!ua->lksb.sb_lvbptr) { |
4517 | kfree(ua); | 4578 | kfree(ua); |
4518 | __put_lkb(ls, lkb); | 4579 | __put_lkb(ls, lkb); |
@@ -4582,7 +4643,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, | |||
4582 | ua = lkb->lkb_ua; | 4643 | ua = lkb->lkb_ua; |
4583 | 4644 | ||
4584 | if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { | 4645 | if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) { |
4585 | ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL); | 4646 | ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS); |
4586 | if (!ua->lksb.sb_lvbptr) { | 4647 | if (!ua->lksb.sb_lvbptr) { |
4587 | error = -ENOMEM; | 4648 | error = -ENOMEM; |
4588 | goto out_put; | 4649 | goto out_put; |