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); | 
