]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/recovery.c
Update bcachefs sources to 841a95c29f4c bcachefs: fix userspace build errors
[bcachefs-tools-debian] / libbcachefs / recovery.c
index 69b49845a730e612062a1e3b8aa3ed210480a466..f51456f29c0ee4b39fec8d4c58283d47a0a0af79 100644 (file)
@@ -150,7 +150,7 @@ static int bch2_journal_replay(struct bch_fs *c)
        u64 start_seq   = c->journal_replay_seq_start;
        u64 end_seq     = c->journal_replay_seq_start;
        struct btree_trans *trans = bch2_trans_get(c);
-       int ret;
+       int ret = 0;
 
        if (keys->nr) {
                ret = bch2_journal_log_msg(c, "Starting journal replay (%zu keys in entries %llu-%llu)",
@@ -533,7 +533,8 @@ static int bch2_set_may_go_rw(struct bch_fs *c)
        keys->gap = keys->nr;
 
        set_bit(BCH_FS_may_go_rw, &c->flags);
-       if (keys->nr || c->opts.fsck)
+
+       if (keys->nr || c->opts.fsck || !c->sb.clean)
                return bch2_fs_read_write_early(c);
        return 0;
 }
@@ -634,7 +635,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;
@@ -651,39 +652,59 @@ 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;
 
-               c->recovery_passes_complete |= BIT_ULL(pass);
+       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(c->curr_recovery_pass);
+               }
+               c->curr_recovery_pass++;
+               c->recovery_pass_done = max(c->recovery_pass_done, 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;