aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorKurt Hackel <kurt.hackel@oracle.com>2006-06-19 00:28:01 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2006-08-07 13:54:59 -0400
commita23eac99d4392b8b779305498d7614e41a0e16e9 (patch)
tree29541e6786334eb1556918ff9b24affeb5dbd3e5 /fs
parent4b1af774451bbc8440719e3fe441934a337c3b63 (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')
-rw-r--r--fs/ocfs2/dlm/dlmunlock.c37
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
520leave: 510leave:
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);