]> git.ipfire.org Git - people/ms/linux.git/blobdiff - fs/dlm/recoverd.c
Merge branch 'for-6.0/dax' into libnvdimm-fixes
[people/ms/linux.git] / fs / dlm / recoverd.c
index a55dfce705dd264b78d0dc8df352517c993f4a14..e15eb511b04b0a2a99f59cfb35c462880a620e5d 100644 (file)
@@ -70,6 +70,10 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 
        /*
         * Add or remove nodes from the lockspace's ls_nodes list.
+        *
+        * Due to the fact that we must report all membership changes to lsops
+        * or midcomms layer, it is not permitted to abort ls_recover() until
+        * this is done.
         */
 
        error = dlm_recover_members(ls, rv, &neg);
@@ -239,14 +243,12 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
                  jiffies_to_msecs(jiffies - start));
        mutex_unlock(&ls->ls_recoverd_active);
 
-       dlm_lsop_recover_done(ls);
        return 0;
 
  fail:
        dlm_release_root_list(ls);
-       log_rinfo(ls, "dlm_recover %llu error %d",
-                 (unsigned long long)rv->seq, error);
        mutex_unlock(&ls->ls_recoverd_active);
+
        return error;
 }
 
@@ -257,6 +259,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
 static void do_ls_recovery(struct dlm_ls *ls)
 {
        struct dlm_recover *rv = NULL;
+       int error;
 
        spin_lock(&ls->ls_recover_lock);
        rv = ls->ls_recover_args;
@@ -266,7 +269,31 @@ static void do_ls_recovery(struct dlm_ls *ls)
        spin_unlock(&ls->ls_recover_lock);
 
        if (rv) {
-               ls_recover(ls, rv);
+               error = ls_recover(ls, rv);
+               switch (error) {
+               case 0:
+                       ls->ls_recovery_result = 0;
+                       complete(&ls->ls_recovery_done);
+
+                       dlm_lsop_recover_done(ls);
+                       break;
+               case -EINTR:
+                       /* if recovery was interrupted -EINTR we wait for the next
+                        * ls_recover() iteration until it hopefully succeeds.
+                        */
+                       log_rinfo(ls, "%s %llu interrupted and should be queued to run again",
+                                 __func__, (unsigned long long)rv->seq);
+                       break;
+               default:
+                       log_rinfo(ls, "%s %llu error %d", __func__,
+                                 (unsigned long long)rv->seq, error);
+
+                       /* let new_lockspace() get aware of critical error */
+                       ls->ls_recovery_result = error;
+                       complete(&ls->ls_recovery_done);
+                       break;
+               }
+
                kfree(rv->nodes);
                kfree(rv);
        }