|
@@ -717,8 +717,14 @@ void dlm_recovered_lock(struct dlm_rsb *r)
|
|
|
* the VALNOTVALID flag if necessary, and determining the correct lvb contents
|
|
|
* based on the lvb's of the locks held on the rsb.
|
|
|
*
|
|
|
- * RSB_VALNOTVALID is set if there are only NL/CR locks on the rsb. If it
|
|
|
- * was already set prior to recovery, it's not cleared, regardless of locks.
|
|
|
+ * RSB_VALNOTVALID is set in two cases:
|
|
|
+ *
|
|
|
+ * 1. we are master, but not new, and we purged an EX/PW lock held by a
|
|
|
+ * failed node (in dlm_recover_purge which set RSB_RECOVER_LVB_INVAL)
|
|
|
+ *
|
|
|
+ * 2. we are a new master, and there are only NL/CR locks left.
|
|
|
+ * (We could probably improve this by only invaliding in this way when
|
|
|
+ * the previous master left uncleanly. VMS docs mention that.)
|
|
|
*
|
|
|
* The LVB contents are only considered for changing when this is a new master
|
|
|
* 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)
|
|
|
int big_lock_exists = 0;
|
|
|
int lvblen = r->res_ls->ls_lvblen;
|
|
|
|
|
|
+ if (!rsb_flag(r, RSB_NEW_MASTER2) &&
|
|
|
+ rsb_flag(r, RSB_RECOVER_LVB_INVAL)) {
|
|
|
+ /* case 1 above */
|
|
|
+ rsb_set_flag(r, RSB_VALNOTVALID);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!rsb_flag(r, RSB_NEW_MASTER2))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* we are the new master, so figure out if VALNOTVALID should
|
|
|
+ be set, and set the rsb lvb from the best lkb available. */
|
|
|
+
|
|
|
list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
|
|
|
if (!(lkb->lkb_exflags & DLM_LKF_VALBLK))
|
|
|
continue;
|
|
@@ -772,13 +791,10 @@ static void recover_lvb(struct dlm_rsb *r)
|
|
|
if (!lock_lvb_exists)
|
|
|
goto out;
|
|
|
|
|
|
+ /* lvb is invalidated if only NL/CR locks remain */
|
|
|
if (!big_lock_exists)
|
|
|
rsb_set_flag(r, RSB_VALNOTVALID);
|
|
|
|
|
|
- /* don't mess with the lvb unless we're the new master */
|
|
|
- if (!rsb_flag(r, RSB_NEW_MASTER2))
|
|
|
- goto out;
|
|
|
-
|
|
|
if (!r->res_lvbptr) {
|
|
|
r->res_lvbptr = dlm_allocate_lvb(r->res_ls);
|
|
|
if (!r->res_lvbptr)
|
|
@@ -852,12 +868,19 @@ void dlm_recover_rsbs(struct dlm_ls *ls)
|
|
|
if (is_master(r)) {
|
|
|
if (rsb_flag(r, RSB_RECOVER_CONVERT))
|
|
|
recover_conversion(r);
|
|
|
+
|
|
|
+ /* recover lvb before granting locks so the updated
|
|
|
+ lvb/VALNOTVALID is presented in the completion */
|
|
|
+ recover_lvb(r);
|
|
|
+
|
|
|
if (rsb_flag(r, RSB_NEW_MASTER2))
|
|
|
recover_grant(r);
|
|
|
- recover_lvb(r);
|
|
|
count++;
|
|
|
+ } else {
|
|
|
+ rsb_clear_flag(r, RSB_VALNOTVALID);
|
|
|
}
|
|
|
rsb_clear_flag(r, RSB_RECOVER_CONVERT);
|
|
|
+ rsb_clear_flag(r, RSB_RECOVER_LVB_INVAL);
|
|
|
rsb_clear_flag(r, RSB_NEW_MASTER2);
|
|
|
unlock_rsb(r);
|
|
|
}
|