bcachefs: bch2_fsck_err_opt()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 22 Apr 2025 13:02:15 +0000 (09:02 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:34 +0000 (20:14 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/errcode.h
fs/bcachefs/error.c
fs/bcachefs/error.h

index 1a52edc7c8d849fc84e2902e802db436a4f7253a..4aac0182cbedd87fd1410f4e46a503e8102ae276 100644 (file)
        x(0,                            backpointer_to_overwritten_btree_node)  \
        x(0,                            journal_reclaim_would_deadlock)         \
        x(EINVAL,                       fsck)                                   \
+       x(BCH_ERR_fsck,                 fsck_ask)                               \
        x(BCH_ERR_fsck,                 fsck_fix)                               \
        x(BCH_ERR_fsck,                 fsck_delete_bkey)                       \
        x(BCH_ERR_fsck,                 fsck_ignore)                            \
index 20495062d6e15ec2b6eb2b0d0c1e550e735ff938..731733e12e6baa72e88d68dfe2124cec2055e583 100644 (file)
@@ -393,6 +393,48 @@ bool __bch2_count_fsck_err(struct bch_fs *c,
        return print && !repeat;
 }
 
+int bch2_fsck_err_opt(struct bch_fs *c,
+                     enum bch_fsck_flags flags,
+                     enum bch_sb_error_id err)
+{
+       if (!WARN_ON(err >= ARRAY_SIZE(fsck_flags_extra)))
+               flags |= fsck_flags_extra[err];
+
+       if (test_bit(BCH_FS_fsck_running, &c->flags)) {
+               if (!(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE)))
+                       return -BCH_ERR_fsck_repair_unimplemented;
+
+               switch (c->opts.fix_errors) {
+               case FSCK_FIX_exit:
+                       return -BCH_ERR_fsck_errors_not_fixed;
+               case FSCK_FIX_yes:
+                       if (flags & FSCK_CAN_FIX)
+                               return -BCH_ERR_fsck_fix;
+                       fallthrough;
+               case FSCK_FIX_no:
+                       if (flags & FSCK_CAN_IGNORE)
+                               return -BCH_ERR_fsck_ignore;
+                       return -BCH_ERR_fsck_errors_not_fixed;
+               case FSCK_FIX_ask:
+                       if (flags & FSCK_AUTOFIX)
+                               return -BCH_ERR_fsck_fix;
+                       return -BCH_ERR_fsck_ask;
+               default:
+                       BUG();
+               }
+       } else {
+               if ((flags & FSCK_AUTOFIX) &&
+                   (c->opts.errors == BCH_ON_ERROR_continue ||
+                    c->opts.errors == BCH_ON_ERROR_fix_safe))
+                       return -BCH_ERR_fsck_fix;
+
+               if (c->opts.errors == BCH_ON_ERROR_continue &&
+                   (flags & FSCK_CAN_IGNORE))
+                       return -BCH_ERR_fsck_ignore;
+               return -BCH_ERR_fsck_errors_not_fixed;
+       }
+}
+
 int __bch2_fsck_err(struct bch_fs *c,
                  struct btree_trans *trans,
                  enum bch_fsck_flags flags,
index 0b3ede1c20158badc00dacbef66f7128a1b0e7df..d89dd270b2e58bf45cdd0664a671cb64e6ee8d62 100644 (file)
@@ -80,6 +80,10 @@ bool __bch2_count_fsck_err(struct bch_fs *, enum bch_sb_error_id, struct printbu
 #define bch2_count_fsck_err(_c, _err, ...)                             \
        __bch2_count_fsck_err(_c, BCH_FSCK_ERR_##_err, __VA_ARGS__)
 
+int bch2_fsck_err_opt(struct bch_fs *,
+                     enum bch_fsck_flags,
+                     enum bch_sb_error_id);
+
 __printf(5, 6) __cold
 int __bch2_fsck_err(struct bch_fs *, struct btree_trans *,
                  enum bch_fsck_flags,