diff options
Diffstat (limited to 'fs/ocfs2/dlm/dlmunlock.c')
| -rw-r--r-- | fs/ocfs2/dlm/dlmunlock.c | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index b0c3134f4f70..37be4b2e0d4a 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 || !master_node)) |
| 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; |
| @@ -483,6 +476,10 @@ int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data) | |||
| 483 | 476 | ||
| 484 | /* lock was found on queue */ | 477 | /* lock was found on queue */ |
| 485 | lksb = lock->lksb; | 478 | lksb = lock->lksb; |
| 479 | if (flags & (LKM_VALBLK|LKM_PUT_LVB) && | ||
| 480 | lock->ml.type != LKM_EXMODE) | ||
| 481 | flags &= ~(LKM_VALBLK|LKM_PUT_LVB); | ||
| 482 | |||
| 486 | /* unlockast only called on originating node */ | 483 | /* unlockast only called on originating node */ |
| 487 | if (flags & LKM_PUT_LVB) { | 484 | if (flags & LKM_PUT_LVB) { |
| 488 | lksb->flags |= DLM_LKSB_PUT_LVB; | 485 | lksb->flags |= DLM_LKSB_PUT_LVB; |
| @@ -507,11 +504,8 @@ not_found: | |||
| 507 | "cookie=%u:%llu\n", | 504 | "cookie=%u:%llu\n", |
| 508 | dlm_get_lock_cookie_node(unlock->cookie), | 505 | dlm_get_lock_cookie_node(unlock->cookie), |
| 509 | dlm_get_lock_cookie_seq(unlock->cookie)); | 506 | dlm_get_lock_cookie_seq(unlock->cookie)); |
| 510 | else { | 507 | else |
| 511 | /* send the lksb->status back to the other node */ | ||
| 512 | status = lksb->status; | ||
| 513 | dlm_lock_put(lock); | 508 | dlm_lock_put(lock); |
| 514 | } | ||
| 515 | 509 | ||
| 516 | leave: | 510 | leave: |
| 517 | if (res) | 511 | if (res) |
| @@ -533,26 +527,22 @@ static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm, | |||
| 533 | 527 | ||
| 534 | if (dlm_lock_on_list(&res->blocked, lock)) { | 528 | if (dlm_lock_on_list(&res->blocked, lock)) { |
| 535 | /* cancel this outright */ | 529 | /* cancel this outright */ |
| 536 | lksb->status = DLM_NORMAL; | ||
| 537 | status = DLM_NORMAL; | 530 | status = DLM_NORMAL; |
| 538 | *actions = (DLM_UNLOCK_CALL_AST | | 531 | *actions = (DLM_UNLOCK_CALL_AST | |
| 539 | DLM_UNLOCK_REMOVE_LOCK); | 532 | DLM_UNLOCK_REMOVE_LOCK); |
| 540 | } else if (dlm_lock_on_list(&res->converting, lock)) { | 533 | } else if (dlm_lock_on_list(&res->converting, lock)) { |
| 541 | /* cancel the request, put back on granted */ | 534 | /* cancel the request, put back on granted */ |
| 542 | lksb->status = DLM_NORMAL; | ||
| 543 | status = DLM_NORMAL; | 535 | status = DLM_NORMAL; |
| 544 | *actions = (DLM_UNLOCK_CALL_AST | | 536 | *actions = (DLM_UNLOCK_CALL_AST | |
| 545 | DLM_UNLOCK_REMOVE_LOCK | | 537 | DLM_UNLOCK_REMOVE_LOCK | |
| 546 | DLM_UNLOCK_REGRANT_LOCK | | 538 | DLM_UNLOCK_REGRANT_LOCK | |
| 547 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 539 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
| 548 | } else if (dlm_lock_on_list(&res->granted, lock)) { | 540 | } else if (dlm_lock_on_list(&res->granted, lock)) { |
| 549 | /* too late, already granted. DLM_CANCELGRANT */ | 541 | /* too late, already granted. */ |
| 550 | lksb->status = DLM_CANCELGRANT; | 542 | status = DLM_CANCELGRANT; |
| 551 | status = DLM_NORMAL; | ||
| 552 | *actions = DLM_UNLOCK_CALL_AST; | 543 | *actions = DLM_UNLOCK_CALL_AST; |
| 553 | } else { | 544 | } else { |
| 554 | 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"); |
| 555 | lksb->status = DLM_IVLOCKID; | ||
| 556 | status = DLM_IVLOCKID; | 546 | status = DLM_IVLOCKID; |
| 557 | *actions = 0; | 547 | *actions = 0; |
| 558 | } | 548 | } |
| @@ -569,13 +559,11 @@ static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm, | |||
| 569 | 559 | ||
| 570 | /* unlock request */ | 560 | /* unlock request */ |
| 571 | if (!dlm_lock_on_list(&res->granted, lock)) { | 561 | if (!dlm_lock_on_list(&res->granted, lock)) { |
| 572 | lksb->status = DLM_DENIED; | ||
| 573 | status = DLM_DENIED; | 562 | status = DLM_DENIED; |
| 574 | dlm_error(status); | 563 | dlm_error(status); |
| 575 | *actions = 0; | 564 | *actions = 0; |
| 576 | } else { | 565 | } else { |
| 577 | /* unlock granted lock */ | 566 | /* unlock granted lock */ |
| 578 | lksb->status = DLM_NORMAL; | ||
| 579 | status = DLM_NORMAL; | 567 | status = DLM_NORMAL; |
| 580 | *actions = (DLM_UNLOCK_FREE_LOCK | | 568 | *actions = (DLM_UNLOCK_FREE_LOCK | |
| 581 | DLM_UNLOCK_CALL_AST | | 569 | DLM_UNLOCK_CALL_AST | |
| @@ -632,6 +620,8 @@ retry: | |||
| 632 | 620 | ||
| 633 | spin_lock(&res->spinlock); | 621 | spin_lock(&res->spinlock); |
| 634 | is_master = (res->owner == dlm->node_num); | 622 | is_master = (res->owner == dlm->node_num); |
| 623 | if (flags & LKM_VALBLK && lock->ml.type != LKM_EXMODE) | ||
| 624 | flags &= ~LKM_VALBLK; | ||
| 635 | spin_unlock(&res->spinlock); | 625 | spin_unlock(&res->spinlock); |
| 636 | 626 | ||
| 637 | if (is_master) { | 627 | if (is_master) { |
| @@ -665,7 +655,7 @@ retry: | |||
| 665 | } | 655 | } |
| 666 | 656 | ||
| 667 | if (call_ast) { | 657 | if (call_ast) { |
| 668 | mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status); | 658 | mlog(0, "calling unlockast(%p, %d)\n", data, status); |
| 669 | if (is_master) { | 659 | if (is_master) { |
| 670 | /* it is possible that there is one last bast | 660 | /* it is possible that there is one last bast |
| 671 | * pending. make sure it is flushed, then | 661 | * pending. make sure it is flushed, then |
| @@ -677,9 +667,12 @@ retry: | |||
| 677 | wait_event(dlm->ast_wq, | 667 | wait_event(dlm->ast_wq, |
| 678 | dlm_lock_basts_flushed(dlm, lock)); | 668 | dlm_lock_basts_flushed(dlm, lock)); |
| 679 | } | 669 | } |
| 680 | (*unlockast)(data, lksb->status); | 670 | (*unlockast)(data, status); |
| 681 | } | 671 | } |
| 682 | 672 | ||
| 673 | if (status == DLM_CANCELGRANT) | ||
| 674 | status = DLM_NORMAL; | ||
| 675 | |||
| 683 | if (status == DLM_NORMAL) { | 676 | if (status == DLM_NORMAL) { |
| 684 | mlog(0, "kicking the thread\n"); | 677 | mlog(0, "kicking the thread\n"); |
| 685 | dlm_kick_thread(dlm, res); | 678 | dlm_kick_thread(dlm, res); |
