diff options
author | Kurt Hackel <kurt.hackel@oracle.com> | 2006-06-19 00:28:01 -0400 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2006-08-07 13:54:59 -0400 |
commit | a23eac99d4392b8b779305498d7614e41a0e16e9 (patch) | |
tree | 29541e6786334eb1556918ff9b24affeb5dbd3e5 /fs/ocfs2 | |
parent | 4b1af774451bbc8440719e3fe441934a337c3b63 (diff) |
ocfs2: do not modify lksb->status in the unlock ast
This can race with other ast notification, which can cause bad status values
to propagate into the unlock ast.
Signed-off-by: Kurt Hackel <kurt.hackel@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlm/dlmunlock.c | 37 |
1 files changed, 12 insertions, 25 deletions
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 4ce3f82fb736..59866e471d96 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
@@ -155,7 +155,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
155 | else | 155 | else |
156 | status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions); | 156 | status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions); |
157 | 157 | ||
158 | if (status != DLM_NORMAL) | 158 | if (status != DLM_NORMAL && status != DLM_CANCELGRANT) |
159 | goto leave; | 159 | goto leave; |
160 | 160 | ||
161 | /* By now this has been masked out of cancel requests. */ | 161 | /* By now this has been masked out of cancel requests. */ |
@@ -183,8 +183,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
183 | spin_lock(&lock->spinlock); | 183 | spin_lock(&lock->spinlock); |
184 | /* if the master told us the lock was already granted, | 184 | /* if the master told us the lock was already granted, |
185 | * let the ast handle all of these actions */ | 185 | * let the ast handle all of these actions */ |
186 | if (status == DLM_NORMAL && | 186 | if (status == DLM_CANCELGRANT) { |
187 | lksb->status == DLM_CANCELGRANT) { | ||
188 | actions &= ~(DLM_UNLOCK_REMOVE_LOCK| | 187 | actions &= ~(DLM_UNLOCK_REMOVE_LOCK| |
189 | DLM_UNLOCK_REGRANT_LOCK| | 188 | DLM_UNLOCK_REGRANT_LOCK| |
190 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 189 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
@@ -349,14 +348,9 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, | |||
349 | vec, veclen, owner, &status); | 348 | vec, veclen, owner, &status); |
350 | if (tmpret >= 0) { | 349 | if (tmpret >= 0) { |
351 | // successfully sent and received | 350 | // successfully sent and received |
352 | if (status == DLM_CANCELGRANT) | 351 | if (status == DLM_FORWARD) |
353 | ret = DLM_NORMAL; | ||
354 | else if (status == DLM_FORWARD) { | ||
355 | mlog(0, "master was in-progress. retry\n"); | 352 | mlog(0, "master was in-progress. retry\n"); |
356 | ret = DLM_FORWARD; | 353 | ret = status; |
357 | } else | ||
358 | ret = status; | ||
359 | lksb->status = status; | ||
360 | } else { | 354 | } else { |
361 | mlog_errno(tmpret); | 355 | mlog_errno(tmpret); |
362 | if (dlm_is_host_down(tmpret)) { | 356 | if (dlm_is_host_down(tmpret)) { |
@@ -372,7 +366,6 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, | |||
372 | /* something bad. this will BUG in ocfs2 */ | 366 | /* something bad. this will BUG in ocfs2 */ |
373 | ret = dlm_err_to_dlm_status(tmpret); | 367 | ret = dlm_err_to_dlm_status(tmpret); |
374 | } | 368 | } |
375 | lksb->status = ret; | ||
376 | } | 369 | } |
377 | 370 | ||
378 | return ret; | 371 | return ret; |
@@ -511,11 +504,8 @@ not_found: | |||
511 | "cookie=%u:%llu\n", | 504 | "cookie=%u:%llu\n", |
512 | dlm_get_lock_cookie_node(unlock->cookie), | 505 | dlm_get_lock_cookie_node(unlock->cookie), |
513 | dlm_get_lock_cookie_seq(unlock->cookie)); | 506 | dlm_get_lock_cookie_seq(unlock->cookie)); |
514 | else { | 507 | else |
515 | /* send the lksb->status back to the other node */ | ||
516 | status = lksb->status; | ||
517 | dlm_lock_put(lock); | 508 | dlm_lock_put(lock); |
518 | } | ||
519 | 509 | ||
520 | leave: | 510 | leave: |
521 | if (res) | 511 | if (res) |
@@ -537,26 +527,22 @@ static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm, | |||
537 | 527 | ||
538 | if (dlm_lock_on_list(&res->blocked, lock)) { | 528 | if (dlm_lock_on_list(&res->blocked, lock)) { |
539 | /* cancel this outright */ | 529 | /* cancel this outright */ |
540 | lksb->status = DLM_NORMAL; | ||
541 | status = DLM_NORMAL; | 530 | status = DLM_NORMAL; |
542 | *actions = (DLM_UNLOCK_CALL_AST | | 531 | *actions = (DLM_UNLOCK_CALL_AST | |
543 | DLM_UNLOCK_REMOVE_LOCK); | 532 | DLM_UNLOCK_REMOVE_LOCK); |
544 | } else if (dlm_lock_on_list(&res->converting, lock)) { | 533 | } else if (dlm_lock_on_list(&res->converting, lock)) { |
545 | /* cancel the request, put back on granted */ | 534 | /* cancel the request, put back on granted */ |
546 | lksb->status = DLM_NORMAL; | ||
547 | status = DLM_NORMAL; | 535 | status = DLM_NORMAL; |
548 | *actions = (DLM_UNLOCK_CALL_AST | | 536 | *actions = (DLM_UNLOCK_CALL_AST | |
549 | DLM_UNLOCK_REMOVE_LOCK | | 537 | DLM_UNLOCK_REMOVE_LOCK | |
550 | DLM_UNLOCK_REGRANT_LOCK | | 538 | DLM_UNLOCK_REGRANT_LOCK | |
551 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 539 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
552 | } else if (dlm_lock_on_list(&res->granted, lock)) { | 540 | } else if (dlm_lock_on_list(&res->granted, lock)) { |
553 | /* too late, already granted. DLM_CANCELGRANT */ | 541 | /* too late, already granted. */ |
554 | lksb->status = DLM_CANCELGRANT; | 542 | status = DLM_CANCELGRANT; |
555 | status = DLM_NORMAL; | ||
556 | *actions = DLM_UNLOCK_CALL_AST; | 543 | *actions = DLM_UNLOCK_CALL_AST; |
557 | } else { | 544 | } else { |
558 | mlog(ML_ERROR, "lock to cancel is not on any list!\n"); | 545 | mlog(ML_ERROR, "lock to cancel is not on any list!\n"); |
559 | lksb->status = DLM_IVLOCKID; | ||
560 | status = DLM_IVLOCKID; | 546 | status = DLM_IVLOCKID; |
561 | *actions = 0; | 547 | *actions = 0; |
562 | } | 548 | } |
@@ -573,13 +559,11 @@ static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm, | |||
573 | 559 | ||
574 | /* unlock request */ | 560 | /* unlock request */ |
575 | if (!dlm_lock_on_list(&res->granted, lock)) { | 561 | if (!dlm_lock_on_list(&res->granted, lock)) { |
576 | lksb->status = DLM_DENIED; | ||
577 | status = DLM_DENIED; | 562 | status = DLM_DENIED; |
578 | dlm_error(status); | 563 | dlm_error(status); |
579 | *actions = 0; | 564 | *actions = 0; |
580 | } else { | 565 | } else { |
581 | /* unlock granted lock */ | 566 | /* unlock granted lock */ |
582 | lksb->status = DLM_NORMAL; | ||
583 | status = DLM_NORMAL; | 567 | status = DLM_NORMAL; |
584 | *actions = (DLM_UNLOCK_FREE_LOCK | | 568 | *actions = (DLM_UNLOCK_FREE_LOCK | |
585 | DLM_UNLOCK_CALL_AST | | 569 | DLM_UNLOCK_CALL_AST | |
@@ -671,7 +655,7 @@ retry: | |||
671 | } | 655 | } |
672 | 656 | ||
673 | if (call_ast) { | 657 | if (call_ast) { |
674 | mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status); | 658 | mlog(0, "calling unlockast(%p, %d)\n", data, status); |
675 | if (is_master) { | 659 | if (is_master) { |
676 | /* it is possible that there is one last bast | 660 | /* it is possible that there is one last bast |
677 | * pending. make sure it is flushed, then | 661 | * pending. make sure it is flushed, then |
@@ -683,9 +667,12 @@ retry: | |||
683 | wait_event(dlm->ast_wq, | 667 | wait_event(dlm->ast_wq, |
684 | dlm_lock_basts_flushed(dlm, lock)); | 668 | dlm_lock_basts_flushed(dlm, lock)); |
685 | } | 669 | } |
686 | (*unlockast)(data, lksb->status); | 670 | (*unlockast)(data, status); |
687 | } | 671 | } |
688 | 672 | ||
673 | if (status == DLM_CANCELGRANT) | ||
674 | status = DLM_NORMAL; | ||
675 | |||
689 | if (status == DLM_NORMAL) { | 676 | if (status == DLM_NORMAL) { |
690 | mlog(0, "kicking the thread\n"); | 677 | mlog(0, "kicking the thread\n"); |
691 | dlm_kick_thread(dlm, res); | 678 | dlm_kick_thread(dlm, res); |