]> www.infradead.org Git - users/hch/configfs.git/commitdiff
bcachefs: bch2_run_online_recovery_passes()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 6 Dec 2023 19:36:18 +0000 (14:36 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 1 Jan 2024 16:47:40 +0000 (11:47 -0500)
Add a new helper for running online recovery passes - i.e. online fsck.
This is a subset of our normal recovery passes, and does not - for now -
use or follow c->curr_recovery_pass.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/recovery.c
fs/bcachefs/recovery.h

index 3c9d24e42ff7ff307eaacc711c89fbb2a6ef08d2..18bc1bbef918896145623a2fd8af2c228693086a 100644 (file)
@@ -1047,6 +1047,13 @@ struct bch_fs {
        /* RECOVERY */
        u64                     journal_replay_seq_start;
        u64                     journal_replay_seq_end;
+       /*
+        * Two different uses:
+        * "Has this fsck pass?" - i.e. should this type of error be an
+        * emergency read-only
+        * And, in certain situations fsck will rewind to an earlier pass: used
+        * for signaling to the toplevel code which pass we want to run now.
+        */
        enum bch_recovery_pass  curr_recovery_pass;
        /* bitmap of explicitly enabled recovery passes: */
        u64                     recovery_passes_explicit;
index b296a8fc2fdc695243a242a0589ddabd3c4a61fb..629ddbb5850f64dcfcbb5cdc098c2a343a45e0b3 100644 (file)
@@ -665,7 +665,7 @@ u64 bch2_fsck_recovery_passes(void)
 
 static bool should_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass)
 {
-       struct recovery_pass_fn *p = recovery_pass_fns + c->curr_recovery_pass;
+       struct recovery_pass_fn *p = recovery_pass_fns + pass;
 
        if (c->opts.norecovery && pass > BCH_RECOVERY_PASS_snapshots_read)
                return false;
@@ -682,39 +682,58 @@ static bool should_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pa
 
 static int bch2_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass)
 {
+       struct recovery_pass_fn *p = recovery_pass_fns + pass;
        int ret;
 
-       c->curr_recovery_pass = pass;
+       if (!(p->when & PASS_SILENT))
+               bch2_print(c, KERN_INFO bch2_log_msg(c, "%s..."),
+                          bch2_recovery_passes[pass]);
+       ret = p->fn(c);
+       if (ret)
+               return ret;
+       if (!(p->when & PASS_SILENT))
+               bch2_print(c, KERN_CONT " done\n");
 
-       if (should_run_recovery_pass(c, pass)) {
-               struct recovery_pass_fn *p = recovery_pass_fns + pass;
+       return 0;
+}
 
-               if (!(p->when & PASS_SILENT))
-                       bch2_print(c, KERN_INFO bch2_log_msg(c, "%s..."),
-                                  bch2_recovery_passes[pass]);
-               ret = p->fn(c);
-               if (ret)
-                       return ret;
-               if (!(p->when & PASS_SILENT))
-                       bch2_print(c, KERN_CONT " done\n");
+static int bch2_run_recovery_passes(struct bch_fs *c)
+{
+       int ret = 0;
+
+       while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns)) {
+               if (should_run_recovery_pass(c, c->curr_recovery_pass)) {
+                       ret = bch2_run_recovery_pass(c, c->curr_recovery_pass);
+                       if (bch2_err_matches(ret, BCH_ERR_restart_recovery))
+                               continue;
+                       if (ret)
+                               break;
 
-               c->recovery_passes_complete |= BIT_ULL(pass);
+                       c->recovery_passes_complete |= BIT_ULL(c->curr_recovery_pass);
+               }
+               c->curr_recovery_pass++;
        }
 
-       return 0;
+       return ret;
 }
 
-static int bch2_run_recovery_passes(struct bch_fs *c)
+int bch2_run_online_recovery_passes(struct bch_fs *c)
 {
        int ret = 0;
 
-       while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns)) {
-               ret = bch2_run_recovery_pass(c, c->curr_recovery_pass);
-               if (bch2_err_matches(ret, BCH_ERR_restart_recovery))
+       for (unsigned i = 0; i < ARRAY_SIZE(recovery_pass_fns); i++) {
+               struct recovery_pass_fn *p = recovery_pass_fns + i;
+
+               if (!(p->when & PASS_ONLINE))
+                       continue;
+
+               ret = bch2_run_recovery_pass(c, i);
+               if (bch2_err_matches(ret, BCH_ERR_restart_recovery)) {
+                       i = c->curr_recovery_pass;
                        continue;
+               }
                if (ret)
                        break;
-               c->curr_recovery_pass++;
        }
 
        return ret;
index 3a554b0751d01429ccb16c19440a46cb33d49979..4e9d24719b2e85c356fa88a0bd3923c3a2ff30cc 100644 (file)
@@ -31,6 +31,7 @@ static inline int bch2_run_explicit_recovery_pass(struct bch_fs *c,
        }
 }
 
+int bch2_run_online_recovery_passes(struct bch_fs *);
 u64 bch2_fsck_recovery_passes(void);
 
 int bch2_fs_recovery(struct bch_fs *);