diff options
Diffstat (limited to 'fs/dlm/recover.c')
-rw-r--r-- | fs/dlm/recover.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index 4a7a76e42fc3..aedea28a86a1 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c | |||
@@ -717,8 +717,14 @@ void dlm_recovered_lock(struct dlm_rsb *r) | |||
717 | * the VALNOTVALID flag if necessary, and determining the correct lvb contents | 717 | * the VALNOTVALID flag if necessary, and determining the correct lvb contents |
718 | * based on the lvb's of the locks held on the rsb. | 718 | * based on the lvb's of the locks held on the rsb. |
719 | * | 719 | * |
720 | * RSB_VALNOTVALID is set if there are only NL/CR locks on the rsb. If it | 720 | * RSB_VALNOTVALID is set in two cases: |
721 | * was already set prior to recovery, it's not cleared, regardless of locks. | 721 | * |
722 | * 1. we are master, but not new, and we purged an EX/PW lock held by a | ||
723 | * failed node (in dlm_recover_purge which set RSB_RECOVER_LVB_INVAL) | ||
724 | * | ||
725 | * 2. we are a new master, and there are only NL/CR locks left. | ||
726 | * (We could probably improve this by only invaliding in this way when | ||
727 | * the previous master left uncleanly. VMS docs mention that.) | ||
722 | * | 728 | * |
723 | * The LVB contents are only considered for changing when this is a new master | 729 | * The LVB contents are only considered for changing when this is a new master |
724 | * of the rsb (NEW_MASTER2). Then, the rsb's lvb is taken from any lkb with | 730 | * of the rsb (NEW_MASTER2). Then, the rsb's lvb is taken from any lkb with |
@@ -734,6 +740,19 @@ static void recover_lvb(struct dlm_rsb *r) | |||
734 | int big_lock_exists = 0; | 740 | int big_lock_exists = 0; |
735 | int lvblen = r->res_ls->ls_lvblen; | 741 | int lvblen = r->res_ls->ls_lvblen; |
736 | 742 | ||
743 | if (!rsb_flag(r, RSB_NEW_MASTER2) && | ||
744 | rsb_flag(r, RSB_RECOVER_LVB_INVAL)) { | ||
745 | /* case 1 above */ | ||
746 | rsb_set_flag(r, RSB_VALNOTVALID); | ||
747 | return; | ||
748 | } | ||
749 | |||
750 | if (!rsb_flag(r, RSB_NEW_MASTER2)) | ||
751 | return; | ||
752 | |||
753 | /* we are the new master, so figure out if VALNOTVALID should | ||
754 | be set, and set the rsb lvb from the best lkb available. */ | ||
755 | |||
737 | list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) { | 756 | list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) { |
738 | if (!(lkb->lkb_exflags & DLM_LKF_VALBLK)) | 757 | if (!(lkb->lkb_exflags & DLM_LKF_VALBLK)) |
739 | continue; | 758 | continue; |
@@ -772,13 +791,10 @@ static void recover_lvb(struct dlm_rsb *r) | |||
772 | if (!lock_lvb_exists) | 791 | if (!lock_lvb_exists) |
773 | goto out; | 792 | goto out; |
774 | 793 | ||
794 | /* lvb is invalidated if only NL/CR locks remain */ | ||
775 | if (!big_lock_exists) | 795 | if (!big_lock_exists) |
776 | rsb_set_flag(r, RSB_VALNOTVALID); | 796 | rsb_set_flag(r, RSB_VALNOTVALID); |
777 | 797 | ||
778 | /* don't mess with the lvb unless we're the new master */ | ||
779 | if (!rsb_flag(r, RSB_NEW_MASTER2)) | ||
780 | goto out; | ||
781 | |||
782 | if (!r->res_lvbptr) { | 798 | if (!r->res_lvbptr) { |
783 | r->res_lvbptr = dlm_allocate_lvb(r->res_ls); | 799 | r->res_lvbptr = dlm_allocate_lvb(r->res_ls); |
784 | if (!r->res_lvbptr) | 800 | if (!r->res_lvbptr) |
@@ -852,12 +868,19 @@ void dlm_recover_rsbs(struct dlm_ls *ls) | |||
852 | if (is_master(r)) { | 868 | if (is_master(r)) { |
853 | if (rsb_flag(r, RSB_RECOVER_CONVERT)) | 869 | if (rsb_flag(r, RSB_RECOVER_CONVERT)) |
854 | recover_conversion(r); | 870 | recover_conversion(r); |
871 | |||
872 | /* recover lvb before granting locks so the updated | ||
873 | lvb/VALNOTVALID is presented in the completion */ | ||
874 | recover_lvb(r); | ||
875 | |||
855 | if (rsb_flag(r, RSB_NEW_MASTER2)) | 876 | if (rsb_flag(r, RSB_NEW_MASTER2)) |
856 | recover_grant(r); | 877 | recover_grant(r); |
857 | recover_lvb(r); | ||
858 | count++; | 878 | count++; |
879 | } else { | ||
880 | rsb_clear_flag(r, RSB_VALNOTVALID); | ||
859 | } | 881 | } |
860 | rsb_clear_flag(r, RSB_RECOVER_CONVERT); | 882 | rsb_clear_flag(r, RSB_RECOVER_CONVERT); |
883 | rsb_clear_flag(r, RSB_RECOVER_LVB_INVAL); | ||
861 | rsb_clear_flag(r, RSB_NEW_MASTER2); | 884 | rsb_clear_flag(r, RSB_NEW_MASTER2); |
862 | unlock_rsb(r); | 885 | unlock_rsb(r); |
863 | } | 886 | } |