Commit 7f391b2f authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_run_online_recovery_passes()

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 0953450a
...@@ -1047,6 +1047,13 @@ struct bch_fs { ...@@ -1047,6 +1047,13 @@ struct bch_fs {
/* RECOVERY */ /* RECOVERY */
u64 journal_replay_seq_start; u64 journal_replay_seq_start;
u64 journal_replay_seq_end; 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; enum bch_recovery_pass curr_recovery_pass;
/* bitmap of explicitly enabled recovery passes: */ /* bitmap of explicitly enabled recovery passes: */
u64 recovery_passes_explicit; u64 recovery_passes_explicit;
......
...@@ -665,7 +665,7 @@ u64 bch2_fsck_recovery_passes(void) ...@@ -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) 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) if (c->opts.norecovery && pass > BCH_RECOVERY_PASS_snapshots_read)
return false; return false;
...@@ -682,39 +682,58 @@ static bool should_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pa ...@@ -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) 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; 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)) { return 0;
struct recovery_pass_fn *p = recovery_pass_fns + pass; }
if (!(p->when & PASS_SILENT)) static int bch2_run_recovery_passes(struct bch_fs *c)
bch2_print(c, KERN_INFO bch2_log_msg(c, "%s..."), {
bch2_recovery_passes[pass]); int ret = 0;
ret = p->fn(c);
if (ret) while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns)) {
return ret; if (should_run_recovery_pass(c, c->curr_recovery_pass)) {
if (!(p->when & PASS_SILENT)) ret = bch2_run_recovery_pass(c, c->curr_recovery_pass);
bch2_print(c, KERN_CONT " done\n"); 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; int ret = 0;
while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns)) { for (unsigned i = 0; i < ARRAY_SIZE(recovery_pass_fns); i++) {
ret = bch2_run_recovery_pass(c, c->curr_recovery_pass); struct recovery_pass_fn *p = recovery_pass_fns + i;
if (bch2_err_matches(ret, BCH_ERR_restart_recovery))
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; continue;
}
if (ret) if (ret)
break; break;
c->curr_recovery_pass++;
} }
return ret; return ret;
......
...@@ -31,6 +31,7 @@ static inline int bch2_run_explicit_recovery_pass(struct bch_fs *c, ...@@ -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); u64 bch2_fsck_recovery_passes(void);
int bch2_fs_recovery(struct bch_fs *); int bch2_fs_recovery(struct bch_fs *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment