bcachefs: allow for custom action in fsck error messages
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 28 Mar 2024 04:39:11 +0000 (00:39 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:18 +0000 (17:29 -0400)
Be more explicit to the user about what we're doing.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/error.c
fs/bcachefs/journal_io.c
fs/bcachefs/snapshot.c

index 82a6656c941c5f16e6725d0bfbf66a3b63157e0f..c66eeffcd7f2a85d85da7873125aba0ef2df41a7 100644 (file)
@@ -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;
 }
 
index eb1f9d6f5a196e55aebf5b74f485bfa634169da5..cd14636bc2ab4a8eaf0ef654cb40a643743c76ee 100644 (file)
@@ -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);
index 544322d5c2517070143d367fa15d4ff353642556..c415ea0a649b03790761b3ce058d613fe4a2e3f5 100644 (file)
@@ -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;