diff options
Diffstat (limited to 'fs/dlm/lock.c')
-rw-r--r-- | fs/dlm/lock.c | 120 |
1 files changed, 90 insertions, 30 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 9c0c1db1e105..46ffd3eeaaf7 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 |
@@ -307,7 +307,7 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv) | |||
307 | lkb->lkb_lksb->sb_status = rv; | 307 | lkb->lkb_lksb->sb_status = rv; |
308 | lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; | 308 | lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; |
309 | 309 | ||
310 | dlm_add_ast(lkb, AST_COMP, 0); | 310 | dlm_add_ast(lkb, AST_COMP, lkb->lkb_grmode); |
311 | } | 311 | } |
312 | 312 | ||
313 | static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) | 313 | static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) |
@@ -320,10 +320,12 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode) | |||
320 | { | 320 | { |
321 | lkb->lkb_time_bast = ktime_get(); | 321 | lkb->lkb_time_bast = ktime_get(); |
322 | 322 | ||
323 | if (is_master_copy(lkb)) | 323 | if (is_master_copy(lkb)) { |
324 | lkb->lkb_bastmode = rqmode; /* printed by debugfs */ | ||
324 | send_bast(r, lkb, rqmode); | 325 | send_bast(r, lkb, rqmode); |
325 | else | 326 | } else { |
326 | dlm_add_ast(lkb, AST_BAST, rqmode); | 327 | dlm_add_ast(lkb, AST_BAST, rqmode); |
328 | } | ||
327 | } | 329 | } |
328 | 330 | ||
329 | /* | 331 | /* |
@@ -2280,20 +2282,30 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2280 | if (can_be_queued(lkb)) { | 2282 | if (can_be_queued(lkb)) { |
2281 | error = -EINPROGRESS; | 2283 | error = -EINPROGRESS; |
2282 | add_lkb(r, lkb, DLM_LKSTS_WAITING); | 2284 | add_lkb(r, lkb, DLM_LKSTS_WAITING); |
2283 | send_blocking_asts(r, lkb); | ||
2284 | add_timeout(lkb); | 2285 | add_timeout(lkb); |
2285 | goto out; | 2286 | goto out; |
2286 | } | 2287 | } |
2287 | 2288 | ||
2288 | error = -EAGAIN; | 2289 | error = -EAGAIN; |
2289 | if (force_blocking_asts(lkb)) | ||
2290 | send_blocking_asts_all(r, lkb); | ||
2291 | queue_cast(r, lkb, -EAGAIN); | 2290 | queue_cast(r, lkb, -EAGAIN); |
2292 | |||
2293 | out: | 2291 | out: |
2294 | return error; | 2292 | return error; |
2295 | } | 2293 | } |
2296 | 2294 | ||
2295 | static void do_request_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2296 | int error) | ||
2297 | { | ||
2298 | switch (error) { | ||
2299 | case -EAGAIN: | ||
2300 | if (force_blocking_asts(lkb)) | ||
2301 | send_blocking_asts_all(r, lkb); | ||
2302 | break; | ||
2303 | case -EINPROGRESS: | ||
2304 | send_blocking_asts(r, lkb); | ||
2305 | break; | ||
2306 | } | ||
2307 | } | ||
2308 | |||
2297 | static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2309 | static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) |
2298 | { | 2310 | { |
2299 | int error = 0; | 2311 | int error = 0; |
@@ -2304,7 +2316,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2304 | if (can_be_granted(r, lkb, 1, &deadlk)) { | 2316 | if (can_be_granted(r, lkb, 1, &deadlk)) { |
2305 | grant_lock(r, lkb); | 2317 | grant_lock(r, lkb); |
2306 | queue_cast(r, lkb, 0); | 2318 | queue_cast(r, lkb, 0); |
2307 | grant_pending_locks(r); | ||
2308 | goto out; | 2319 | goto out; |
2309 | } | 2320 | } |
2310 | 2321 | ||
@@ -2334,7 +2345,6 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2334 | if (_can_be_granted(r, lkb, 1)) { | 2345 | if (_can_be_granted(r, lkb, 1)) { |
2335 | grant_lock(r, lkb); | 2346 | grant_lock(r, lkb); |
2336 | queue_cast(r, lkb, 0); | 2347 | queue_cast(r, lkb, 0); |
2337 | grant_pending_locks(r); | ||
2338 | goto out; | 2348 | goto out; |
2339 | } | 2349 | } |
2340 | /* else fall through and move to convert queue */ | 2350 | /* else fall through and move to convert queue */ |
@@ -2344,28 +2354,47 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2344 | error = -EINPROGRESS; | 2354 | error = -EINPROGRESS; |
2345 | del_lkb(r, lkb); | 2355 | del_lkb(r, lkb); |
2346 | add_lkb(r, lkb, DLM_LKSTS_CONVERT); | 2356 | add_lkb(r, lkb, DLM_LKSTS_CONVERT); |
2347 | send_blocking_asts(r, lkb); | ||
2348 | add_timeout(lkb); | 2357 | add_timeout(lkb); |
2349 | goto out; | 2358 | goto out; |
2350 | } | 2359 | } |
2351 | 2360 | ||
2352 | error = -EAGAIN; | 2361 | error = -EAGAIN; |
2353 | if (force_blocking_asts(lkb)) | ||
2354 | send_blocking_asts_all(r, lkb); | ||
2355 | queue_cast(r, lkb, -EAGAIN); | 2362 | queue_cast(r, lkb, -EAGAIN); |
2356 | |||
2357 | out: | 2363 | out: |
2358 | return error; | 2364 | return error; |
2359 | } | 2365 | } |
2360 | 2366 | ||
2367 | static void do_convert_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2368 | int error) | ||
2369 | { | ||
2370 | switch (error) { | ||
2371 | case 0: | ||
2372 | grant_pending_locks(r); | ||
2373 | /* grant_pending_locks also sends basts */ | ||
2374 | break; | ||
2375 | case -EAGAIN: | ||
2376 | if (force_blocking_asts(lkb)) | ||
2377 | send_blocking_asts_all(r, lkb); | ||
2378 | break; | ||
2379 | case -EINPROGRESS: | ||
2380 | send_blocking_asts(r, lkb); | ||
2381 | break; | ||
2382 | } | ||
2383 | } | ||
2384 | |||
2361 | static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2385 | static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb) |
2362 | { | 2386 | { |
2363 | remove_lock(r, lkb); | 2387 | remove_lock(r, lkb); |
2364 | queue_cast(r, lkb, -DLM_EUNLOCK); | 2388 | queue_cast(r, lkb, -DLM_EUNLOCK); |
2365 | grant_pending_locks(r); | ||
2366 | return -DLM_EUNLOCK; | 2389 | return -DLM_EUNLOCK; |
2367 | } | 2390 | } |
2368 | 2391 | ||
2392 | static void do_unlock_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2393 | int error) | ||
2394 | { | ||
2395 | grant_pending_locks(r); | ||
2396 | } | ||
2397 | |||
2369 | /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ | 2398 | /* returns: 0 did nothing, -DLM_ECANCEL canceled lock */ |
2370 | 2399 | ||
2371 | static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) | 2400 | static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) |
@@ -2375,12 +2404,18 @@ static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2375 | error = revert_lock(r, lkb); | 2404 | error = revert_lock(r, lkb); |
2376 | if (error) { | 2405 | if (error) { |
2377 | queue_cast(r, lkb, -DLM_ECANCEL); | 2406 | queue_cast(r, lkb, -DLM_ECANCEL); |
2378 | grant_pending_locks(r); | ||
2379 | return -DLM_ECANCEL; | 2407 | return -DLM_ECANCEL; |
2380 | } | 2408 | } |
2381 | return 0; | 2409 | return 0; |
2382 | } | 2410 | } |
2383 | 2411 | ||
2412 | static void do_cancel_effects(struct dlm_rsb *r, struct dlm_lkb *lkb, | ||
2413 | int error) | ||
2414 | { | ||
2415 | if (error) | ||
2416 | grant_pending_locks(r); | ||
2417 | } | ||
2418 | |||
2384 | /* | 2419 | /* |
2385 | * Four stage 3 varieties: | 2420 | * Four stage 3 varieties: |
2386 | * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() | 2421 | * _request_lock(), _convert_lock(), _unlock_lock(), _cancel_lock() |
@@ -2402,11 +2437,15 @@ static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2402 | goto out; | 2437 | goto out; |
2403 | } | 2438 | } |
2404 | 2439 | ||
2405 | if (is_remote(r)) | 2440 | if (is_remote(r)) { |
2406 | /* receive_request() calls do_request() on remote node */ | 2441 | /* receive_request() calls do_request() on remote node */ |
2407 | error = send_request(r, lkb); | 2442 | error = send_request(r, lkb); |
2408 | else | 2443 | } else { |
2409 | error = do_request(r, lkb); | 2444 | error = do_request(r, lkb); |
2445 | /* for remote locks the request_reply is sent | ||
2446 | between do_request and do_request_effects */ | ||
2447 | do_request_effects(r, lkb, error); | ||
2448 | } | ||
2410 | out: | 2449 | out: |
2411 | return error; | 2450 | return error; |
2412 | } | 2451 | } |
@@ -2417,11 +2456,15 @@ static int _convert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2417 | { | 2456 | { |
2418 | int error; | 2457 | int error; |
2419 | 2458 | ||
2420 | if (is_remote(r)) | 2459 | if (is_remote(r)) { |
2421 | /* receive_convert() calls do_convert() on remote node */ | 2460 | /* receive_convert() calls do_convert() on remote node */ |
2422 | error = send_convert(r, lkb); | 2461 | error = send_convert(r, lkb); |
2423 | else | 2462 | } else { |
2424 | error = do_convert(r, lkb); | 2463 | error = do_convert(r, lkb); |
2464 | /* for remote locks the convert_reply is sent | ||
2465 | between do_convert and do_convert_effects */ | ||
2466 | do_convert_effects(r, lkb, error); | ||
2467 | } | ||
2425 | 2468 | ||
2426 | return error; | 2469 | return error; |
2427 | } | 2470 | } |
@@ -2432,11 +2475,15 @@ static int _unlock_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2432 | { | 2475 | { |
2433 | int error; | 2476 | int error; |
2434 | 2477 | ||
2435 | if (is_remote(r)) | 2478 | if (is_remote(r)) { |
2436 | /* receive_unlock() calls do_unlock() on remote node */ | 2479 | /* receive_unlock() calls do_unlock() on remote node */ |
2437 | error = send_unlock(r, lkb); | 2480 | error = send_unlock(r, lkb); |
2438 | else | 2481 | } else { |
2439 | error = do_unlock(r, lkb); | 2482 | error = do_unlock(r, lkb); |
2483 | /* for remote locks the unlock_reply is sent | ||
2484 | between do_unlock and do_unlock_effects */ | ||
2485 | do_unlock_effects(r, lkb, error); | ||
2486 | } | ||
2440 | 2487 | ||
2441 | return error; | 2488 | return error; |
2442 | } | 2489 | } |
@@ -2447,11 +2494,15 @@ static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) | |||
2447 | { | 2494 | { |
2448 | int error; | 2495 | int error; |
2449 | 2496 | ||
2450 | if (is_remote(r)) | 2497 | if (is_remote(r)) { |
2451 | /* receive_cancel() calls do_cancel() on remote node */ | 2498 | /* receive_cancel() calls do_cancel() on remote node */ |
2452 | error = send_cancel(r, lkb); | 2499 | error = send_cancel(r, lkb); |
2453 | else | 2500 | } else { |
2454 | error = do_cancel(r, lkb); | 2501 | error = do_cancel(r, lkb); |
2502 | /* for remote locks the cancel_reply is sent | ||
2503 | between do_cancel and do_cancel_effects */ | ||
2504 | do_cancel_effects(r, lkb, error); | ||
2505 | } | ||
2455 | 2506 | ||
2456 | return error; | 2507 | return error; |
2457 | } | 2508 | } |
@@ -3191,6 +3242,7 @@ static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) | |||
3191 | attach_lkb(r, lkb); | 3242 | attach_lkb(r, lkb); |
3192 | error = do_request(r, lkb); | 3243 | error = do_request(r, lkb); |
3193 | send_request_reply(r, lkb, error); | 3244 | send_request_reply(r, lkb, error); |
3245 | do_request_effects(r, lkb, error); | ||
3194 | 3246 | ||
3195 | unlock_rsb(r); | 3247 | unlock_rsb(r); |
3196 | put_rsb(r); | 3248 | put_rsb(r); |
@@ -3226,15 +3278,19 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms) | |||
3226 | goto out; | 3278 | goto out; |
3227 | 3279 | ||
3228 | receive_flags(lkb, ms); | 3280 | receive_flags(lkb, ms); |
3281 | |||
3229 | error = receive_convert_args(ls, lkb, ms); | 3282 | error = receive_convert_args(ls, lkb, ms); |
3230 | if (error) | 3283 | if (error) { |
3231 | goto out_reply; | 3284 | send_convert_reply(r, lkb, error); |
3285 | goto out; | ||
3286 | } | ||
3287 | |||
3232 | reply = !down_conversion(lkb); | 3288 | reply = !down_conversion(lkb); |
3233 | 3289 | ||
3234 | error = do_convert(r, lkb); | 3290 | error = do_convert(r, lkb); |
3235 | out_reply: | ||
3236 | if (reply) | 3291 | if (reply) |
3237 | send_convert_reply(r, lkb, error); | 3292 | send_convert_reply(r, lkb, error); |
3293 | do_convert_effects(r, lkb, error); | ||
3238 | out: | 3294 | out: |
3239 | unlock_rsb(r); | 3295 | unlock_rsb(r); |
3240 | put_rsb(r); | 3296 | put_rsb(r); |
@@ -3266,13 +3322,16 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms) | |||
3266 | goto out; | 3322 | goto out; |
3267 | 3323 | ||
3268 | receive_flags(lkb, ms); | 3324 | receive_flags(lkb, ms); |
3325 | |||
3269 | error = receive_unlock_args(ls, lkb, ms); | 3326 | error = receive_unlock_args(ls, lkb, ms); |
3270 | if (error) | 3327 | if (error) { |
3271 | goto out_reply; | 3328 | send_unlock_reply(r, lkb, error); |
3329 | goto out; | ||
3330 | } | ||
3272 | 3331 | ||
3273 | error = do_unlock(r, lkb); | 3332 | error = do_unlock(r, lkb); |
3274 | out_reply: | ||
3275 | send_unlock_reply(r, lkb, error); | 3333 | send_unlock_reply(r, lkb, error); |
3334 | do_unlock_effects(r, lkb, error); | ||
3276 | out: | 3335 | out: |
3277 | unlock_rsb(r); | 3336 | unlock_rsb(r); |
3278 | put_rsb(r); | 3337 | put_rsb(r); |
@@ -3307,6 +3366,7 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms) | |||
3307 | 3366 | ||
3308 | error = do_cancel(r, lkb); | 3367 | error = do_cancel(r, lkb); |
3309 | send_cancel_reply(r, lkb, error); | 3368 | send_cancel_reply(r, lkb, error); |
3369 | do_cancel_effects(r, lkb, error); | ||
3310 | out: | 3370 | out: |
3311 | unlock_rsb(r); | 3371 | unlock_rsb(r); |
3312 | put_rsb(r); | 3372 | put_rsb(r); |