diff options
author | David Teigland <teigland@redhat.com> | 2010-02-24 12:59:23 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2010-02-26 12:57:37 -0500 |
commit | cf6620acc0f6fac57968aafef79ab372bdcf6157 (patch) | |
tree | fae381f0ffc0f13124f6138de9843140fc816cb3 /fs/dlm/lock.c | |
parent | 7fe2b3190b8b299409f13cf3a6f85c2bd371f8bb (diff) |
dlm: send reply before bast
When the lock master processes a successful operation (request,
convert, cancel, or unlock), it will process the effects of the
change before sending the reply for the operation. The "effects"
of the operation are:
- blocking callbacks (basts) for any newly granted locks
- waiting or converting locks that can now be granted
The cast is queued on the local node when the reply from the lock
master is received. This means that a lock holder can receive a
bast for a lock mode that is doesn't yet know has been granted.
Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm/lock.c')
-rw-r--r-- | fs/dlm/lock.c | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index e08ea93432bc..d0e43a3da887 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -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); |