bcachefs: allow for custom action in fsck error messages
Be more explicit to the user about what we're doing. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
497c982f05
commit
19391b9294
@ -176,6 +176,21 @@ static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt)
|
||||
return s;
|
||||
}
|
||||
|
||||
/* s/fix?/fixing/ s/recreate?/recreating/ */
|
||||
static void prt_actioning(struct printbuf *out, const char *action)
|
||||
{
|
||||
unsigned len = strlen(action);
|
||||
|
||||
BUG_ON(action[len - 1] != '?');
|
||||
--len;
|
||||
|
||||
if (action[len - 1] == 'e')
|
||||
--len;
|
||||
|
||||
prt_bytes(out, action, len);
|
||||
prt_str(out, "ing");
|
||||
}
|
||||
|
||||
int bch2_fsck_err(struct bch_fs *c,
|
||||
enum bch_fsck_flags flags,
|
||||
enum bch_sb_error_id err,
|
||||
@ -186,6 +201,7 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
bool print = true, suppressing = false, inconsistent = false;
|
||||
struct printbuf buf = PRINTBUF, *out = &buf;
|
||||
int ret = -BCH_ERR_fsck_ignore;
|
||||
const char *action_orig = "fix?", *action = action_orig;
|
||||
|
||||
if ((flags & FSCK_CAN_FIX) &&
|
||||
test_bit(err, c->sb.errors_silent))
|
||||
@ -197,6 +213,19 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
prt_vprintf(out, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/* Custom fix/continue/recreate/etc.? */
|
||||
if (out->buf[out->pos - 1] == '?') {
|
||||
const char *p = strrchr(out->buf, ',');
|
||||
if (p) {
|
||||
out->pos = p - out->buf;
|
||||
action = kstrdup(p + 2, GFP_KERNEL);
|
||||
if (!action) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&c->fsck_error_msgs_lock);
|
||||
s = fsck_err_get(c, fmt);
|
||||
if (s) {
|
||||
@ -208,12 +237,16 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
if (s->last_msg && !strcmp(buf.buf, s->last_msg)) {
|
||||
ret = s->ret;
|
||||
mutex_unlock(&c->fsck_error_msgs_lock);
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
kfree(s->last_msg);
|
||||
s->last_msg = kstrdup(buf.buf, GFP_KERNEL);
|
||||
if (!s->last_msg) {
|
||||
mutex_unlock(&c->fsck_error_msgs_lock);
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (c->opts.ratelimit_errors &&
|
||||
!(flags & FSCK_NO_RATELIMIT) &&
|
||||
@ -239,7 +272,8 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
inconsistent = true;
|
||||
ret = -BCH_ERR_fsck_errors_not_fixed;
|
||||
} else if (flags & FSCK_CAN_FIX) {
|
||||
prt_str(out, ", fixing");
|
||||
prt_str(out, ", ");
|
||||
prt_actioning(out, action);
|
||||
ret = -BCH_ERR_fsck_fix;
|
||||
} else {
|
||||
prt_str(out, ", continuing");
|
||||
@ -254,16 +288,16 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
: c->opts.fix_errors;
|
||||
|
||||
if (fix == FSCK_FIX_ask) {
|
||||
int ask;
|
||||
prt_str(out, ", ");
|
||||
prt_str(out, action);
|
||||
|
||||
prt_str(out, ": fix?");
|
||||
if (bch2_fs_stdio_redirect(c))
|
||||
bch2_print(c, "%s", out->buf);
|
||||
else
|
||||
bch2_print_string_as_lines(KERN_ERR, out->buf);
|
||||
print = false;
|
||||
|
||||
ask = bch2_fsck_ask_yn(c);
|
||||
int ask = bch2_fsck_ask_yn(c);
|
||||
|
||||
if (ask >= YN_ALLNO && s)
|
||||
s->fix = ask == YN_ALLNO
|
||||
@ -276,10 +310,12 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
} else if (fix == FSCK_FIX_yes ||
|
||||
(c->opts.nochanges &&
|
||||
!(flags & FSCK_CAN_IGNORE))) {
|
||||
prt_str(out, ", fixing");
|
||||
prt_str(out, ", ");
|
||||
prt_actioning(out, action);
|
||||
ret = -BCH_ERR_fsck_fix;
|
||||
} else {
|
||||
prt_str(out, ", not fixing");
|
||||
prt_str(out, ", not ");
|
||||
prt_actioning(out, action);
|
||||
}
|
||||
} else if (flags & FSCK_NEED_FSCK) {
|
||||
prt_str(out, " (run fsck to correct)");
|
||||
@ -311,8 +347,6 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
|
||||
mutex_unlock(&c->fsck_error_msgs_lock);
|
||||
|
||||
printbuf_exit(&buf);
|
||||
|
||||
if (inconsistent)
|
||||
bch2_inconsistent_error(c);
|
||||
|
||||
@ -322,7 +356,10 @@ int bch2_fsck_err(struct bch_fs *c,
|
||||
set_bit(BCH_FS_errors_not_fixed, &c->flags);
|
||||
set_bit(BCH_FS_error, &c->flags);
|
||||
}
|
||||
|
||||
err:
|
||||
if (action != action_orig)
|
||||
kfree(action);
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1366,7 +1366,7 @@ int bch2_journal_read(struct bch_fs *c,
|
||||
fsck_err(c, journal_entries_missing,
|
||||
"journal entries %llu-%llu missing! (replaying %llu-%llu)\n"
|
||||
" prev at %s\n"
|
||||
" next at %s",
|
||||
" next at %s, continue?",
|
||||
missing_start, missing_end,
|
||||
*last_seq, *blacklist_seq - 1,
|
||||
buf1.buf, buf2.buf);
|
||||
|
@ -1018,7 +1018,7 @@ int bch2_reconstruct_snapshots(struct bch_fs *c)
|
||||
darray_for_each(*t, id) {
|
||||
if (fsck_err_on(!bch2_snapshot_equiv(c, *id),
|
||||
c, snapshot_node_missing,
|
||||
"snapshot node %u from tree %s missing", *id, buf.buf)) {
|
||||
"snapshot node %u from tree %s missing, recreate?", *id, buf.buf)) {
|
||||
if (t->nr > 1) {
|
||||
bch_err(c, "cannot reconstruct snapshot trees with multiple nodes");
|
||||
ret = -BCH_ERR_fsck_repair_unimplemented;
|
||||
|
Loading…
x
Reference in New Issue
Block a user