Skip to content

Commit

Permalink
bcachefs: Options for recovery_passes, recovery_passes_exclude
Browse files Browse the repository at this point in the history
This adds mount options for specifying recovery passes to run, or
exclude; the immediate need for this is that backpointers fsck is having
trouble completing, so we need a way to skip it.

Signed-off-by: Kent Overstreet <[email protected]>
  • Loading branch information
Kent Overstreet committed Sep 4, 2024
1 parent ad1d4e1 commit f2c4fab
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 20 deletions.
2 changes: 0 additions & 2 deletions fs/bcachefs/bcachefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1045,8 +1045,6 @@ struct bch_fs {
* 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;
/* bitmask of recovery passes that we actually ran */
u64 recovery_passes_complete;
/* never rewinds version of curr_recovery_pass */
Expand Down
2 changes: 1 addition & 1 deletion fs/bcachefs/btree_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
bch2_btree_pos_to_text(&buf, c, b);
bch_err_ratelimited(c, "%s", buf.buf);

if (c->recovery_passes_explicit & BIT_ULL(BCH_RECOVERY_PASS_check_topology) &&
if (c->opts.recovery_passes & BIT_ULL(BCH_RECOVERY_PASS_check_topology) &&
c->curr_recovery_pass > BCH_RECOVERY_PASS_check_topology)
bch2_fatal_error(c);

Expand Down
2 changes: 1 addition & 1 deletion fs/bcachefs/btree_update_interior.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
printbuf_exit(&buf);
return ret;
topology_repair:
if ((c->recovery_passes_explicit & BIT_ULL(BCH_RECOVERY_PASS_check_topology)) &&
if ((c->opts.recovery_passes & BIT_ULL(BCH_RECOVERY_PASS_check_topology)) &&
c->curr_recovery_pass > BCH_RECOVERY_PASS_check_topology) {
bch2_inconsistent_error(c);
ret = -BCH_ERR_btree_need_topology_repair;
Expand Down
3 changes: 3 additions & 0 deletions fs/bcachefs/opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@ void bch2_opt_to_text(struct printbuf *out,
else
prt_str(out, opt->choices[v]);
break;
case BCH_OPT_BITFIELD:
prt_bitflags(out, opt->choices, v);
break;
case BCH_OPT_FN:
opt->fn.to_text(out, c, sb, v);
break;
Expand Down
10 changes: 10 additions & 0 deletions fs/bcachefs/opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,16 @@ enum fsck_err_opts {
OPT_BOOL(), \
BCH2_NO_SB_OPT, false, \
NULL, "Exit recovery immediately prior to journal replay")\
x(recovery_passes, u64, \
OPT_FS|OPT_MOUNT, \
OPT_BITFIELD(bch2_recovery_passes), \
BCH2_NO_SB_OPT, 0, \
NULL, "Recovery passes to run explicitly") \
x(recovery_passes_exclude, u64, \
OPT_FS|OPT_MOUNT, \
OPT_BITFIELD(bch2_recovery_passes), \
BCH2_NO_SB_OPT, 0, \
NULL, "Recovery passes to exclude") \
x(recovery_pass_last, u8, \
OPT_FS|OPT_MOUNT, \
OPT_STR_NOLIMIT(bch2_recovery_passes), \
Expand Down
22 changes: 11 additions & 11 deletions fs/bcachefs/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static void bch2_reconstruct_alloc(struct bch_fs *c)
bch2_write_super(c);
mutex_unlock(&c->sb_lock);

c->recovery_passes_explicit |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));
c->opts.recovery_passes |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));


bch2_shoot_down_journal_keys(c, BTREE_ID_alloc,
Expand Down Expand Up @@ -525,17 +525,17 @@ static int read_btree_roots(struct bch_fs *c)
"error reading btree root %s l=%u: %s",
bch2_btree_id_str(i), r->level, bch2_err_str(ret))) {
if (btree_id_is_alloc(i)) {
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_allocations);
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_alloc_info);
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_lrus);
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers);
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_alloc_to_lru_refs);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_allocations);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_alloc_info);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_lrus);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_alloc_to_lru_refs);
c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
r->error = 0;
} else if (!(c->recovery_passes_explicit & BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes))) {
} else if (!(c->opts.recovery_passes & BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes))) {
bch_info(c, "will run btree node scan");
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes);
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_topology);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_topology);
}

ret = 0;
Expand Down Expand Up @@ -706,14 +706,14 @@ int bch2_fs_recovery(struct bch_fs *c)
if (check_version_upgrade(c))
write_sb = true;

c->recovery_passes_explicit |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));
c->opts.recovery_passes |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));

if (write_sb)
bch2_write_super(c);
mutex_unlock(&c->sb_lock);

if (c->opts.fsck && IS_ENABLED(CONFIG_BCACHEFS_DEBUG))
c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_topology);
c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_topology);

if (c->opts.fsck)
set_bit(BCH_FS_fsck_running, &c->flags);
Expand Down
10 changes: 6 additions & 4 deletions fs/bcachefs/recovery_passes.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static int bch2_set_may_go_rw(struct bch_fs *c)

set_bit(BCH_FS_may_go_rw, &c->flags);

if (keys->nr || c->opts.fsck || !c->sb.clean || c->recovery_passes_explicit)
if (keys->nr || c->opts.fsck || !c->sb.clean || c->opts.recovery_passes)
return bch2_fs_read_write_early(c);
return 0;
}
Expand Down Expand Up @@ -97,14 +97,14 @@ u64 bch2_recovery_passes_from_stable(u64 v)
int bch2_run_explicit_recovery_pass(struct bch_fs *c,
enum bch_recovery_pass pass)
{
if (c->recovery_passes_explicit & BIT_ULL(pass))
if (c->opts.recovery_passes & BIT_ULL(pass))
return 0;

bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)",
bch2_recovery_passes[pass], pass,
bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);

c->recovery_passes_explicit |= BIT_ULL(pass);
c->opts.recovery_passes |= BIT_ULL(pass);

if (c->curr_recovery_pass >= pass) {
c->curr_recovery_pass = pass;
Expand Down Expand Up @@ -161,7 +161,9 @@ static bool should_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pa
{
struct recovery_pass_fn *p = recovery_pass_fns + pass;

if (c->recovery_passes_explicit & BIT_ULL(pass))
if (c->opts.recovery_passes_exclude & BIT_ULL(pass))
return false;
if (c->opts.recovery_passes & BIT_ULL(pass))
return true;
if ((p->when & PASS_FSCK) && c->opts.fsck)
return true;
Expand Down
2 changes: 1 addition & 1 deletion fs/bcachefs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ u64 bch2_read_flag_list(const char *opt, const char * const list[])

s = strim(d);

while ((p = strsep(&s, ","))) {
while ((p = strsep(&s, ",;"))) {
int flag = match_string(list, -1, p);

if (flag < 0) {
Expand Down

0 comments on commit f2c4fab

Please sign in to comment.