]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: struct bkey_validate_context
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 27 Nov 2024 05:29:52 +0000 (00:29 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:20 +0000 (01:36 -0500)
Add a new parameter to bkey validate functions, and use it to improve
invalid bkey error messages: we can now print the btree and depth it
came from, or if it came from the journal, or is a btree root.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
39 files changed:
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_background.h
fs/bcachefs/backpointers.c
fs/bcachefs/backpointers.h
fs/bcachefs/bkey.h
fs/bcachefs/bkey_methods.c
fs/bcachefs/bkey_methods.h
fs/bcachefs/bkey_types.h
fs/bcachefs/btree_io.c
fs/bcachefs/btree_node_scan.c
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_update_interior.c
fs/bcachefs/data_update.c
fs/bcachefs/dirent.c
fs/bcachefs/dirent.h
fs/bcachefs/disk_accounting.c
fs/bcachefs/disk_accounting.h
fs/bcachefs/ec.c
fs/bcachefs/ec.h
fs/bcachefs/error.c
fs/bcachefs/error.h
fs/bcachefs/extents.c
fs/bcachefs/extents.h
fs/bcachefs/inode.c
fs/bcachefs/inode.h
fs/bcachefs/journal_io.c
fs/bcachefs/lru.c
fs/bcachefs/lru.h
fs/bcachefs/quota.c
fs/bcachefs/quota.h
fs/bcachefs/recovery.c
fs/bcachefs/reflink.c
fs/bcachefs/reflink.h
fs/bcachefs/snapshot.c
fs/bcachefs/snapshot.h
fs/bcachefs/subvolume.c
fs/bcachefs/subvolume.h
fs/bcachefs/xattr.c
fs/bcachefs/xattr.h

index 1e9f53db4bb81e3259304cba96eaa4d5a1fcd763..8846daaa116239f939f062a79c56dceb6ffb5472 100644 (file)
@@ -198,7 +198,7 @@ static unsigned bch_alloc_v1_val_u64s(const struct bch_alloc *a)
 }
 
 int bch2_alloc_v1_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bkey_s_c_alloc a = bkey_s_c_to_alloc(k);
        int ret = 0;
@@ -213,7 +213,7 @@ fsck_err:
 }
 
 int bch2_alloc_v2_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bkey_alloc_unpacked u;
        int ret = 0;
@@ -226,7 +226,7 @@ fsck_err:
 }
 
 int bch2_alloc_v3_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bkey_alloc_unpacked u;
        int ret = 0;
@@ -239,7 +239,7 @@ fsck_err:
 }
 
 int bch2_alloc_v4_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bch_alloc_v4 a;
        int ret = 0;
@@ -509,7 +509,7 @@ static unsigned alloc_gen(struct bkey_s_c k, unsigned offset)
 }
 
 int bch2_bucket_gens_validate(struct bch_fs *c, struct bkey_s_c k,
-                            enum bch_validate_flags flags)
+                             struct bkey_validate_context from)
 {
        int ret = 0;
 
index 57723a37abb8de744c3c912a2730cc08bf94bb1d..8cacddd188f4b0d52f793ddf877e5622209fdb57 100644 (file)
@@ -8,8 +8,6 @@
 #include "debug.h"
 #include "super.h"
 
-enum bch_validate_flags;
-
 /* How out of date a pointer gen is allowed to be: */
 #define BUCKET_GC_GEN_MAX      96U
 
@@ -245,10 +243,14 @@ struct bkey_i_alloc_v4 *bch2_alloc_to_v4_mut(struct btree_trans *, struct bkey_s
 
 int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int);
 
-int bch2_alloc_v1_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
-int bch2_alloc_v2_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
-int bch2_alloc_v3_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
-int bch2_alloc_v4_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_alloc_v1_validate(struct bch_fs *, struct bkey_s_c,
+                          struct bkey_validate_context);
+int bch2_alloc_v2_validate(struct bch_fs *, struct bkey_s_c,
+                          struct bkey_validate_context);
+int bch2_alloc_v3_validate(struct bch_fs *, struct bkey_s_c,
+                          struct bkey_validate_context);
+int bch2_alloc_v4_validate(struct bch_fs *, struct bkey_s_c,
+                          struct bkey_validate_context);
 void bch2_alloc_v4_swab(struct bkey_s);
 void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
@@ -282,7 +284,7 @@ void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 })
 
 int bch2_bucket_gens_validate(struct bch_fs *, struct bkey_s_c,
-                            enum bch_validate_flags);
+                             struct bkey_validate_context);
 void bch2_bucket_gens_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_bucket_gens ((struct bkey_ops) { \
index cfd9b9ead473048d319214cd36460d61dc3ea546..ff08afd667a07e6491ca7f3186904621aea4964b 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/mm.h>
 
 int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
-                             enum bch_validate_flags flags)
+                             struct bkey_validate_context from)
 {
        struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
        int ret = 0;
index d8a15f5fa7675a20ebf7c26331d5a1bc4ddefecd..95caeabb8978f7c3233184ed610493edfafe54cd 100644 (file)
@@ -18,7 +18,8 @@ static inline u64 swab40(u64 x)
                ((x & 0xff00000000ULL) >> 32));
 }
 
-int bch2_backpointer_validate(struct bch_fs *, struct bkey_s_c k, enum bch_validate_flags);
+int bch2_backpointer_validate(struct bch_fs *, struct bkey_s_c k,
+                             struct bkey_validate_context);
 void bch2_backpointer_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 void bch2_backpointer_swab(struct bkey_s);
 
index 41df24a53d971e6fc67db0378a2d1320b25e993b..054e2d5e8448a36ce1bd21f40258e2b355f2e117 100644 (file)
@@ -9,13 +9,6 @@
 #include "util.h"
 #include "vstructs.h"
 
-enum bch_validate_flags {
-       BCH_VALIDATE_write              = BIT(0),
-       BCH_VALIDATE_commit             = BIT(1),
-       BCH_VALIDATE_journal            = BIT(2),
-       BCH_VALIDATE_silent             = BIT(3),
-};
-
 #if 0
 
 /*
index e7ac227ba7e89594da975b6b25c576ba2488a17d..15c93576b5c2041c62f3fa6884e48d8271ddc47a 100644 (file)
@@ -28,7 +28,7 @@ const char * const bch2_bkey_types[] = {
 };
 
 static int deleted_key_validate(struct bch_fs *c, struct bkey_s_c k,
-                               enum bch_validate_flags flags)
+                               struct bkey_validate_context from)
 {
        return 0;
 }
@@ -42,7 +42,7 @@ static int deleted_key_validate(struct bch_fs *c, struct bkey_s_c k,
 })
 
 static int empty_val_key_validate(struct bch_fs *c, struct bkey_s_c k,
-                                enum bch_validate_flags flags)
+                                 struct bkey_validate_context from)
 {
        int ret = 0;
 
@@ -59,7 +59,7 @@ fsck_err:
 })
 
 static int key_type_cookie_validate(struct bch_fs *c, struct bkey_s_c k,
-                                   enum bch_validate_flags flags)
+                                   struct bkey_validate_context from)
 {
        return 0;
 }
@@ -83,7 +83,7 @@ static void key_type_cookie_to_text(struct printbuf *out, struct bch_fs *c,
 })
 
 static int key_type_inline_data_validate(struct bch_fs *c, struct bkey_s_c k,
-                                        enum bch_validate_flags flags)
+                                        struct bkey_validate_context from)
 {
        return 0;
 }
@@ -124,7 +124,7 @@ const struct bkey_ops bch2_bkey_null_ops = {
 };
 
 int bch2_bkey_val_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        if (test_bit(BCH_FS_no_invalid_checks, &c->flags))
                return 0;
@@ -140,7 +140,7 @@ int bch2_bkey_val_validate(struct bch_fs *c, struct bkey_s_c k,
        if (!ops->key_validate)
                return 0;
 
-       ret = ops->key_validate(c, k, flags);
+       ret = ops->key_validate(c, k, from);
 fsck_err:
        return ret;
 }
@@ -161,9 +161,10 @@ const char *bch2_btree_node_type_str(enum btree_node_type type)
 }
 
 int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k,
-                        enum btree_node_type type,
-                        enum bch_validate_flags flags)
+                        struct bkey_validate_context from)
 {
+       enum btree_node_type type = __btree_node_type(from.level, from.btree);
+
        if (test_bit(BCH_FS_no_invalid_checks, &c->flags))
                return 0;
 
@@ -177,7 +178,7 @@ int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k,
                return 0;
 
        bkey_fsck_err_on(k.k->type < KEY_TYPE_MAX &&
-                        (type == BKEY_TYPE_btree || (flags & BCH_VALIDATE_commit)) &&
+                        (type == BKEY_TYPE_btree || (from.flags & BCH_VALIDATE_commit)) &&
                         !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)),
                         c, bkey_invalid_type_for_btree,
                         "invalid key type for btree %s (%s)",
@@ -228,15 +229,15 @@ fsck_err:
 }
 
 int bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k,
-                     enum btree_node_type type,
-                     enum bch_validate_flags flags)
+                      struct bkey_validate_context from)
 {
-       return __bch2_bkey_validate(c, k, type, flags) ?:
-               bch2_bkey_val_validate(c, k, flags);
+       return __bch2_bkey_validate(c, k, from) ?:
+               bch2_bkey_val_validate(c, k, from);
 }
 
 int bch2_bkey_in_btree_node(struct bch_fs *c, struct btree *b,
-                           struct bkey_s_c k, enum bch_validate_flags flags)
+                           struct bkey_s_c k,
+                           struct bkey_validate_context from)
 {
        int ret = 0;
 
index 018fb72e32d398da175cdff0c373ecb785415288..bf34111cdf008d5d989cd80bec4e5ce130d3d241 100644 (file)
@@ -22,7 +22,7 @@ extern const struct bkey_ops bch2_bkey_null_ops;
  */
 struct bkey_ops {
        int             (*key_validate)(struct bch_fs *c, struct bkey_s_c k,
-                                       enum bch_validate_flags flags);
+                                       struct bkey_validate_context from);
        void            (*val_to_text)(struct printbuf *, struct bch_fs *,
                                       struct bkey_s_c);
        void            (*swab)(struct bkey_s);
@@ -48,13 +48,14 @@ static inline const struct bkey_ops *bch2_bkey_type_ops(enum bch_bkey_type type)
                : &bch2_bkey_null_ops;
 }
 
-int bch2_bkey_val_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
-int __bch2_bkey_validate(struct bch_fs *, struct bkey_s_c, enum btree_node_type,
-                        enum bch_validate_flags);
-int bch2_bkey_validate(struct bch_fs *, struct bkey_s_c, enum btree_node_type,
-                      enum bch_validate_flags);
+int bch2_bkey_val_validate(struct bch_fs *, struct bkey_s_c,
+                          struct bkey_validate_context);
+int __bch2_bkey_validate(struct bch_fs *, struct bkey_s_c,
+                        struct bkey_validate_context);
+int bch2_bkey_validate(struct bch_fs *, struct bkey_s_c,
+                      struct bkey_validate_context);
 int bch2_bkey_in_btree_node(struct bch_fs *, struct btree *, struct bkey_s_c,
-                           enum bch_validate_flags);
+                           struct bkey_validate_context from);
 
 void bch2_bpos_to_text(struct printbuf *, struct bpos);
 void bch2_bkey_to_text(struct printbuf *, const struct bkey *);
index c9ae9e42b38512f934de680d47ef296daddcd089..2af6279b02a9ad8f3a0e28e6b05f21790d1c79ed 100644 (file)
@@ -210,4 +210,30 @@ static inline struct bkey_i_##name *bkey_##name##_init(struct bkey_i *_k)\
 BCH_BKEY_TYPES();
 #undef x
 
+enum bch_validate_flags {
+       BCH_VALIDATE_write              = BIT(0),
+       BCH_VALIDATE_commit             = BIT(1),
+       BCH_VALIDATE_journal            = BIT(2),
+       BCH_VALIDATE_silent             = BIT(3),
+};
+
+#define BKEY_VALIDATE_CONTEXTS()       \
+       x(unknown)                      \
+       x(commit)                       \
+       x(journal)                      \
+       x(btree_root)                   \
+       x(btree_node)
+
+struct bkey_validate_context {
+       enum {
+#define x(n)   BKEY_VALIDATE_##n,
+       BKEY_VALIDATE_CONTEXTS()
+#undef x
+       }                       from:8;
+       u8                      level;
+       enum btree_id           btree;
+       bool                    root:1;
+       enum bch_validate_flags flags:8;
+};
+
 #endif /* _BCACHEFS_BKEY_TYPES_H */
index 3bb6db9bd4a46a41f431f977694c361b92acb5e5..eedcb2445b9900e40ba300204c97de945a7a4e94 100644 (file)
@@ -831,13 +831,32 @@ fsck_err:
        return ret;
 }
 
+static int btree_node_bkey_val_validate(struct bch_fs *c, struct btree *b,
+                                       struct bkey_s_c k,
+                                       enum bch_validate_flags flags)
+{
+       return bch2_bkey_val_validate(c, k, (struct bkey_validate_context) {
+               .from   = BKEY_VALIDATE_btree_node,
+               .level  = b->c.level,
+               .btree  = b->c.btree_id,
+               .flags  = flags
+       });
+}
+
 static int bset_key_validate(struct bch_fs *c, struct btree *b,
                             struct bkey_s_c k,
-                            bool updated_range, int rw)
+                            bool updated_range,
+                            enum bch_validate_flags flags)
 {
-       return __bch2_bkey_validate(c, k, btree_node_type(b), 0) ?:
-               (!updated_range ? bch2_bkey_in_btree_node(c, b, k, 0) : 0) ?:
-               (rw == WRITE ? bch2_bkey_val_validate(c, k, 0) : 0);
+       struct bkey_validate_context from = (struct bkey_validate_context) {
+               .from   = BKEY_VALIDATE_btree_node,
+               .level  = b->c.level,
+               .btree  = b->c.btree_id,
+               .flags  = flags,
+       };
+       return __bch2_bkey_validate(c, k, from) ?:
+               (!updated_range ? bch2_bkey_in_btree_node(c, b, k, from) : 0) ?:
+               (flags & BCH_VALIDATE_write ? btree_node_bkey_val_validate(c, b, k, flags) : 0);
 }
 
 static bool bkey_packed_valid(struct bch_fs *c, struct btree *b,
@@ -854,7 +873,13 @@ static bool bkey_packed_valid(struct bch_fs *c, struct btree *b,
 
        struct bkey tmp;
        struct bkey_s u = __bkey_disassemble(b, k, &tmp);
-       return !__bch2_bkey_validate(c, u.s_c, btree_node_type(b), BCH_VALIDATE_silent);
+       return !__bch2_bkey_validate(c, u.s_c,
+                                    (struct bkey_validate_context) {
+                                       .from   = BKEY_VALIDATE_btree_node,
+                                       .level  = b->c.level,
+                                       .btree  = b->c.btree_id,
+                                       .flags  = BCH_VALIDATE_silent
+                                    });
 }
 
 static inline int btree_node_read_bkey_cmp(const struct btree *b,
@@ -1224,7 +1249,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
                struct bkey tmp;
                struct bkey_s u = __bkey_disassemble(b, k, &tmp);
 
-               ret = bch2_bkey_val_validate(c, u.s_c, READ);
+               ret = btree_node_bkey_val_validate(c, b, u.s_c, READ);
                if (ret == -BCH_ERR_fsck_delete_bkey ||
                    (bch2_inject_invalid_keys &&
                     !bversion_cmp(u.k->bversion, MAX_VERSION))) {
@@ -1943,7 +1968,12 @@ static int validate_bset_for_write(struct bch_fs *c, struct btree *b,
        bool saw_error;
 
        int ret = bch2_bkey_validate(c, bkey_i_to_s_c(&b->key),
-                                    BKEY_TYPE_btree, WRITE);
+                                    (struct bkey_validate_context) {
+                                       .from   = BKEY_VALIDATE_btree_node,
+                                       .level  = b->c.level + 1,
+                                       .btree  = b->c.btree_id,
+                                       .flags  = BCH_VALIDATE_write,
+                                    });
        if (ret) {
                bch2_fs_inconsistent(c, "invalid btree node key before write");
                return ret;
index 327f1a1859b943caf135eec58b7f7a706a66b857..eeafb5e7354edca0ce428683db5e221b22c6a8f2 100644 (file)
@@ -538,7 +538,12 @@ int bch2_get_scanned_nodes(struct bch_fs *c, enum btree_id btree,
                bch_verbose(c, "%s(): recovering %s", __func__, buf.buf);
                printbuf_exit(&buf);
 
-               BUG_ON(bch2_bkey_validate(c, bkey_i_to_s_c(&tmp.k), BKEY_TYPE_btree, 0));
+               BUG_ON(bch2_bkey_validate(c, bkey_i_to_s_c(&tmp.k),
+                                         (struct bkey_validate_context) {
+                                               .from   = BKEY_VALIDATE_btree_node,
+                                               .level  = level + 1,
+                                               .btree  = btree,
+                                         }));
 
                ret = bch2_journal_key_insert(c, btree, level + 1, &tmp.k);
                if (ret)
index cf313477567a56227110f90abebec21ad31ad8be..78d72c26083d9aa58b226630997e1e592b04d22e 100644 (file)
@@ -726,7 +726,12 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                        invalid_flags |= BCH_VALIDATE_write|BCH_VALIDATE_commit;
 
                ret = bch2_bkey_validate(c, bkey_i_to_s_c(i->k),
-                                        i->bkey_type, invalid_flags);
+                                        (struct bkey_validate_context) {
+                                               .from   = BKEY_VALIDATE_commit,
+                                               .level  = i->level,
+                                               .btree  = i->btree_id,
+                                               .flags  = invalid_flags,
+                                        });
                if (unlikely(ret)){
                        bch2_trans_inconsistent(trans, "invalid bkey on insert from %s -> %ps\n",
                                                trans->fn, (void *) i->ip_allocated);
index faa2816e02a024cad53500e08311b0813c57a6ec..56a70e95ef9a41d887546180605f98b7e9d9ab39 100644 (file)
@@ -1360,9 +1360,14 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
        if (unlikely(!test_bit(JOURNAL_replay_done, &c->journal.flags)))
                bch2_journal_key_overwritten(c, b->c.btree_id, b->c.level, insert->k.p);
 
-       if (bch2_bkey_validate(c, bkey_i_to_s_c(insert),
-                             btree_node_type(b), BCH_VALIDATE_write) ?:
-           bch2_bkey_in_btree_node(c, b, bkey_i_to_s_c(insert), BCH_VALIDATE_write)) {
+       struct bkey_validate_context from = (struct bkey_validate_context) {
+               .from   = BKEY_VALIDATE_btree_node,
+               .level  = b->c.level,
+               .btree  = b->c.btree_id,
+               .flags  = BCH_VALIDATE_commit,
+       };
+       if (bch2_bkey_validate(c, bkey_i_to_s_c(insert), from) ?:
+           bch2_bkey_in_btree_node(c, b, bkey_i_to_s_c(insert), from)) {
                bch2_fs_inconsistent(c, "%s: inserting invalid bkey", __func__);
                dump_stack();
        }
index e4af2ccdf4c8e6dd628282bea0e16121786d9a65..31b2aeb0c6e6108e333907646284cec605d7c93c 100644 (file)
@@ -318,8 +318,11 @@ restart_drop_extra_replicas:
                 * it's been hard to reproduce, so this should give us some more
                 * information when it does occur:
                 */
-               int invalid = bch2_bkey_validate(c, bkey_i_to_s_c(insert), __btree_node_type(0, m->btree_id),
-                                                BCH_VALIDATE_commit);
+               int invalid = bch2_bkey_validate(c, bkey_i_to_s_c(insert),
+                                                (struct bkey_validate_context) {
+                                                       .btree  = m->btree_id,
+                                                       .flags  = BCH_VALIDATE_commit,
+                                                });
                if (invalid) {
                        struct printbuf buf = PRINTBUF;
 
index 4c22f78b04847807abc0011fc745806d892dd33a..41813f9ce8315576df95798058b716a3bf7e3b12 100644 (file)
@@ -101,7 +101,7 @@ const struct bch_hash_desc bch2_dirent_hash_desc = {
 };
 
 int bch2_dirent_validate(struct bch_fs *c, struct bkey_s_c k,
-                        enum bch_validate_flags flags)
+                        struct bkey_validate_context from)
 {
        struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k);
        struct qstr d_name = bch2_dirent_get_name(d);
@@ -120,7 +120,7 @@ int bch2_dirent_validate(struct bch_fs *c, struct bkey_s_c k,
         * Check new keys don't exceed the max length
         * (older keys may be larger.)
         */
-       bkey_fsck_err_on((flags & BCH_VALIDATE_commit) && d_name.len > BCH_NAME_MAX,
+       bkey_fsck_err_on((from.flags & BCH_VALIDATE_commit) && d_name.len > BCH_NAME_MAX,
                         c, dirent_name_too_long,
                         "dirent name too big (%u > %u)",
                         d_name.len, BCH_NAME_MAX);
index 53ad996660226be6c46e991cc6b65709e466f851..362b3b2f2f2e38f4b06e666960c51daf26c4551e 100644 (file)
@@ -4,10 +4,10 @@
 
 #include "str_hash.h"
 
-enum bch_validate_flags;
 extern const struct bch_hash_desc bch2_dirent_hash_desc;
 
-int bch2_dirent_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_dirent_validate(struct bch_fs *, struct bkey_s_c,
+                        struct bkey_validate_context);
 void bch2_dirent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_dirent ((struct bkey_ops) {      \
index c5e61265b7098cd85b9f7f8fd74767c8424f23e9..71c49a7ee2feb036fcede798ab4d1813c73c27fa 100644 (file)
@@ -127,14 +127,14 @@ static inline bool is_zero(char *start, char *end)
 #define field_end(p, member)   (((void *) (&p.member)) + sizeof(p.member))
 
 int bch2_accounting_validate(struct bch_fs *c, struct bkey_s_c k,
-                            enum bch_validate_flags flags)
+                            struct bkey_validate_context from)
 {
        struct disk_accounting_pos acc_k;
        bpos_to_disk_accounting_pos(&acc_k, k.k->p);
        void *end = &acc_k + 1;
        int ret = 0;
 
-       bkey_fsck_err_on((flags & BCH_VALIDATE_commit) &&
+       bkey_fsck_err_on((from.flags & BCH_VALIDATE_commit) &&
                         bversion_zero(k.k->bversion),
                         c, accounting_key_version_0,
                         "accounting key with version=0");
index 8b2b2f83e6a43534899bfba0a4c257534dd9d83f..566aa2a8539d563ad8c75d83c04aef01ce5401ef 100644 (file)
@@ -83,7 +83,8 @@ int bch2_disk_accounting_mod(struct btree_trans *, struct disk_accounting_pos *,
                             s64 *, unsigned, bool);
 int bch2_mod_dev_cached_sectors(struct btree_trans *, unsigned, s64, bool);
 
-int bch2_accounting_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_accounting_validate(struct bch_fs *, struct bkey_s_c,
+                            struct bkey_validate_context);
 void bch2_accounting_key_to_text(struct printbuf *, struct disk_accounting_pos *);
 void bch2_accounting_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 void bch2_accounting_swab(struct bkey_s);
index cd377ce6cf64e28f9e94d8021d5aaef1bb96957d..eaca4c39d703d46fd8808e36baeddc1d909ce55d 100644 (file)
@@ -110,7 +110,7 @@ struct ec_bio {
 /* Stripes btree keys: */
 
 int bch2_stripe_validate(struct bch_fs *c, struct bkey_s_c k,
-                        enum bch_validate_flags flags)
+                        struct bkey_validate_context from)
 {
        const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
        int ret = 0;
@@ -130,7 +130,7 @@ int bch2_stripe_validate(struct bch_fs *c, struct bkey_s_c k,
                         "invalid csum granularity (%u >= 64)",
                         s->csum_granularity_bits);
 
-       ret = bch2_bkey_ptrs_validate(c, k, flags);
+       ret = bch2_bkey_ptrs_validate(c, k, from);
 fsck_err:
        return ret;
 }
index 43326370b410a65e93969db37fe83c389d4ab71d..583ca6a226dae0b51955dddd2ef356e83c2069b9 100644 (file)
@@ -6,9 +6,8 @@
 #include "buckets_types.h"
 #include "extents_types.h"
 
-enum bch_validate_flags;
-
-int bch2_stripe_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_stripe_validate(struct bch_fs *, struct bkey_s_c,
+                        struct bkey_validate_context);
 void bch2_stripe_to_text(struct printbuf *, struct bch_fs *,
                         struct bkey_s_c);
 int bch2_trigger_stripe(struct btree_trans *, enum btree_id, unsigned,
index 2960baa023f66451438c3461898ff3fb7886f2b0..9a695322b33c259c99d4492f61baf137f42e76da 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcachefs.h"
+#include "btree_cache.h"
 #include "btree_iter.h"
 #include "error.h"
 #include "journal.h"
@@ -443,23 +444,34 @@ err:
        return ret;
 }
 
+static const char * const bch2_bkey_validate_contexts[] = {
+#define x(n) #n,
+       BKEY_VALIDATE_CONTEXTS()
+#undef x
+       NULL
+};
+
 int __bch2_bkey_fsck_err(struct bch_fs *c,
                         struct bkey_s_c k,
-                        enum bch_validate_flags validate_flags,
+                        struct bkey_validate_context from,
                         enum bch_sb_error_id err,
                         const char *fmt, ...)
 {
-       if (validate_flags & BCH_VALIDATE_silent)
+       if (from.flags & BCH_VALIDATE_silent)
                return -BCH_ERR_fsck_delete_bkey;
 
        unsigned fsck_flags = 0;
-       if (!(validate_flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)))
+       if (!(from.flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)))
                fsck_flags |= FSCK_AUTOFIX|FSCK_CAN_FIX;
 
        struct printbuf buf = PRINTBUF;
        va_list args;
 
-       prt_str(&buf, "invalid bkey ");
+       prt_printf(&buf, "invalid bkey in %s btree=",
+                  bch2_bkey_validate_contexts[from.from]);
+       bch2_btree_id_to_text(&buf, from.btree);
+       prt_printf(&buf, " level=%u: ", from.level);
+
        bch2_bkey_val_to_text(&buf, c, k);
        prt_str(&buf, "\n  ");
        va_start(args, fmt);
index 8327a34615350efc5988ff6c5338b913a45a483b..3b278f28e56b61e7dd7670a818c79fb815a2e9a1 100644 (file)
@@ -153,7 +153,7 @@ enum bch_validate_flags;
 __printf(5, 6)
 int __bch2_bkey_fsck_err(struct bch_fs *,
                         struct bkey_s_c,
-                        enum bch_validate_flags,
+                        struct bkey_validate_context from,
                         enum bch_sb_error_id,
                         const char *, ...);
 
@@ -163,7 +163,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *,
  */
 #define bkey_fsck_err(c, _err_type, _err_msg, ...)                     \
 do {                                                                   \
-       int _ret = __bch2_bkey_fsck_err(c, k, flags,                    \
+       int _ret = __bch2_bkey_fsck_err(c, k, from,                     \
                                BCH_FSCK_ERR_##_err_type,               \
                                _err_msg, ##__VA_ARGS__);               \
        if (_ret != -BCH_ERR_fsck_fix &&                                \
index 83aeceb688479160de7f74ab7b1cc6669d2df29a..aa3b8829181437395c6bc66ee82636352ab1a20e 100644 (file)
@@ -178,7 +178,7 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k,
 /* KEY_TYPE_btree_ptr: */
 
 int bch2_btree_ptr_validate(struct bch_fs *c, struct bkey_s_c k,
-                           enum bch_validate_flags flags)
+                           struct bkey_validate_context from)
 {
        int ret = 0;
 
@@ -186,7 +186,7 @@ int bch2_btree_ptr_validate(struct bch_fs *c, struct bkey_s_c k,
                         c, btree_ptr_val_too_big,
                         "value too big (%zu > %u)", bkey_val_u64s(k.k), BCH_REPLICAS_MAX);
 
-       ret = bch2_bkey_ptrs_validate(c, k, flags);
+       ret = bch2_bkey_ptrs_validate(c, k, from);
 fsck_err:
        return ret;
 }
@@ -198,7 +198,7 @@ void bch2_btree_ptr_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 int bch2_btree_ptr_v2_validate(struct bch_fs *c, struct bkey_s_c k,
-                              enum bch_validate_flags flags)
+                              struct bkey_validate_context from)
 {
        struct bkey_s_c_btree_ptr_v2 bp = bkey_s_c_to_btree_ptr_v2(k);
        int ret = 0;
@@ -212,13 +212,13 @@ int bch2_btree_ptr_v2_validate(struct bch_fs *c, struct bkey_s_c k,
                         c, btree_ptr_v2_min_key_bad,
                         "min_key > key");
 
-       if ((flags & BCH_VALIDATE_write) &&
+       if ((from.flags & BCH_VALIDATE_write) &&
            c->sb.version_min >= bcachefs_metadata_version_btree_ptr_sectors_written)
                bkey_fsck_err_on(!bp.v->sectors_written,
                                 c, btree_ptr_v2_written_0,
                                 "sectors_written == 0");
 
-       ret = bch2_bkey_ptrs_validate(c, k, flags);
+       ret = bch2_bkey_ptrs_validate(c, k, from);
 fsck_err:
        return ret;
 }
@@ -405,7 +405,7 @@ bool bch2_extent_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r)
 /* KEY_TYPE_reservation: */
 
 int bch2_reservation_validate(struct bch_fs *c, struct bkey_s_c k,
-                             enum bch_validate_flags flags)
+                             struct bkey_validate_context from)
 {
        struct bkey_s_c_reservation r = bkey_s_c_to_reservation(k);
        int ret = 0;
@@ -1231,7 +1231,7 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
 
 static int extent_ptr_validate(struct bch_fs *c,
                               struct bkey_s_c k,
-                              enum bch_validate_flags flags,
+                              struct bkey_validate_context from,
                               const struct bch_extent_ptr *ptr,
                               unsigned size_ondisk,
                               bool metadata)
@@ -1274,7 +1274,7 @@ fsck_err:
 }
 
 int bch2_bkey_ptrs_validate(struct bch_fs *c, struct bkey_s_c k,
-                           enum bch_validate_flags flags)
+                           struct bkey_validate_context from)
 {
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
        const union bch_extent_entry *entry;
@@ -1301,7 +1301,7 @@ int bch2_bkey_ptrs_validate(struct bch_fs *c, struct bkey_s_c k,
 
                switch (extent_entry_type(entry)) {
                case BCH_EXTENT_ENTRY_ptr:
-                       ret = extent_ptr_validate(c, k, flags, &entry->ptr, size_ondisk, false);
+                       ret = extent_ptr_validate(c, k, from, &entry->ptr, size_ondisk, false);
                        if (ret)
                                return ret;
 
@@ -1348,7 +1348,7 @@ int bch2_bkey_ptrs_validate(struct bch_fs *c, struct bkey_s_c k,
 
                        bkey_fsck_err_on(crc_is_encoded(crc) &&
                                         (crc.uncompressed_size > c->opts.encoded_extent_max >> 9) &&
-                                        (flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)),
+                                        (from.flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)),
                                         c, ptr_crc_uncompressed_size_too_big,
                                         "too large encoded extent");
 
index ba33788fee36d75d4931f45380670f29fd395f30..620b284aa34f00a6d948a613eecf9c1dec4042c0 100644 (file)
@@ -8,7 +8,6 @@
 
 struct bch_fs;
 struct btree_trans;
-enum bch_validate_flags;
 
 /* extent entries: */
 
@@ -410,12 +409,12 @@ int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c,
 /* KEY_TYPE_btree_ptr: */
 
 int bch2_btree_ptr_validate(struct bch_fs *, struct bkey_s_c,
-                           enum bch_validate_flags);
+                           struct bkey_validate_context);
 void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
 
 int bch2_btree_ptr_v2_validate(struct bch_fs *, struct bkey_s_c,
-                              enum bch_validate_flags);
+                              struct bkey_validate_context);
 void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned,
                              int, struct bkey_s);
@@ -452,7 +451,7 @@ bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
 /* KEY_TYPE_reservation: */
 
 int bch2_reservation_validate(struct bch_fs *, struct bkey_s_c,
-                             enum bch_validate_flags);
+                             struct bkey_validate_context);
 void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 bool bch2_reservation_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
 
@@ -696,7 +695,7 @@ void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *, const struct
 void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
 int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c,
-                           enum bch_validate_flags);
+                           struct bkey_validate_context);
 
 static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1,
                                      struct bch_extent_ptr ptr2)
index 5c603ab66be0e6e50a64859ebc5052b50845cf48..8818e41883f2c0293c8323b384323ebe30e43325 100644 (file)
@@ -429,7 +429,7 @@ struct bkey_i *bch2_inode_to_v3(struct btree_trans *trans, struct bkey_i *k)
 }
 
 static int __bch2_inode_validate(struct bch_fs *c, struct bkey_s_c k,
-                                enum bch_validate_flags flags)
+                                struct bkey_validate_context from)
 {
        struct bch_inode_unpacked unpacked;
        int ret = 0;
@@ -469,7 +469,7 @@ fsck_err:
 }
 
 int bch2_inode_validate(struct bch_fs *c, struct bkey_s_c k,
-                       enum bch_validate_flags flags)
+                       struct bkey_validate_context from)
 {
        struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
        int ret = 0;
@@ -479,13 +479,13 @@ int bch2_inode_validate(struct bch_fs *c, struct bkey_s_c k,
                         "invalid str hash type (%llu >= %u)",
                         INODEv1_STR_HASH(inode.v), BCH_STR_HASH_NR);
 
-       ret = __bch2_inode_validate(c, k, flags);
+       ret = __bch2_inode_validate(c, k, from);
 fsck_err:
        return ret;
 }
 
 int bch2_inode_v2_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bkey_s_c_inode_v2 inode = bkey_s_c_to_inode_v2(k);
        int ret = 0;
@@ -495,13 +495,13 @@ int bch2_inode_v2_validate(struct bch_fs *c, struct bkey_s_c k,
                         "invalid str hash type (%llu >= %u)",
                         INODEv2_STR_HASH(inode.v), BCH_STR_HASH_NR);
 
-       ret = __bch2_inode_validate(c, k, flags);
+       ret = __bch2_inode_validate(c, k, from);
 fsck_err:
        return ret;
 }
 
 int bch2_inode_v3_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bkey_s_c_inode_v3 inode = bkey_s_c_to_inode_v3(k);
        int ret = 0;
@@ -519,7 +519,7 @@ int bch2_inode_v3_validate(struct bch_fs *c, struct bkey_s_c k,
                         "invalid str hash type (%llu >= %u)",
                         INODEv3_STR_HASH(inode.v), BCH_STR_HASH_NR);
 
-       ret = __bch2_inode_validate(c, k, flags);
+       ret = __bch2_inode_validate(c, k, from);
 fsck_err:
        return ret;
 }
@@ -780,7 +780,7 @@ int bch2_trigger_inode(struct btree_trans *trans,
 }
 
 int bch2_inode_generation_validate(struct bch_fs *c, struct bkey_s_c k,
-                                  enum bch_validate_flags flags)
+                                  struct bkey_validate_context from)
 {
        int ret = 0;
 
index f52336cb298f5e1de16ea41deaae9fd4fe860652..927c875976da9b68ace42f0c682c6e19e2e287cb 100644 (file)
@@ -7,15 +7,14 @@
 #include "opts.h"
 #include "snapshot.h"
 
-enum bch_validate_flags;
 extern const char * const bch2_inode_opts[];
 
 int bch2_inode_validate(struct bch_fs *, struct bkey_s_c,
-                      enum bch_validate_flags);
+                       struct bkey_validate_context);
 int bch2_inode_v2_validate(struct bch_fs *, struct bkey_s_c,
-                         enum bch_validate_flags);
+                          struct bkey_validate_context);
 int bch2_inode_v3_validate(struct bch_fs *, struct bkey_s_c,
-                         enum bch_validate_flags);
+                          struct bkey_validate_context);
 void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 int __bch2_inode_has_child_snapshots(struct btree_trans *, struct bpos);
@@ -60,7 +59,7 @@ static inline bool bkey_is_inode(const struct bkey *k)
 }
 
 int bch2_inode_generation_validate(struct bch_fs *, struct bkey_s_c,
-                                 enum bch_validate_flags);
+                                  struct bkey_validate_context);
 void bch2_inode_generation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_inode_generation ((struct bkey_ops) {    \
index 768a3b9509976a85e68a7c3e984a08b237d816b5..1627f3e165171d194c74d09287abaf7718de1019 100644 (file)
@@ -327,11 +327,11 @@ static void journal_entry_err_msg(struct printbuf *out,
 static int journal_validate_key(struct bch_fs *c,
                                struct jset *jset,
                                struct jset_entry *entry,
-                               unsigned level, enum btree_id btree_id,
                                struct bkey_i *k,
-                               unsigned version, int big_endian,
-                               enum bch_validate_flags flags)
+                               struct bkey_validate_context from,
+                               unsigned version, int big_endian)
 {
+       enum bch_validate_flags flags = from.flags;
        int write = flags & BCH_VALIDATE_write;
        void *next = vstruct_next(entry);
        int ret = 0;
@@ -366,11 +366,10 @@ static int journal_validate_key(struct bch_fs *c,
        }
 
        if (!write)
-               bch2_bkey_compat(level, btree_id, version, big_endian,
+               bch2_bkey_compat(from.level, from.btree, version, big_endian,
                                 write, NULL, bkey_to_packed(k));
 
-       ret = bch2_bkey_validate(c, bkey_i_to_s_c(k),
-                                __btree_node_type(level, btree_id), write);
+       ret = bch2_bkey_validate(c, bkey_i_to_s_c(k), from);
        if (ret == -BCH_ERR_fsck_delete_bkey) {
                le16_add_cpu(&entry->u64s, -((u16) k->k.u64s));
                memmove(k, bkey_next(k), next - (void *) bkey_next(k));
@@ -381,7 +380,7 @@ static int journal_validate_key(struct bch_fs *c,
                goto fsck_err;
 
        if (write)
-               bch2_bkey_compat(level, btree_id, version, big_endian,
+               bch2_bkey_compat(from.level, from.btree, version, big_endian,
                                 write, NULL, bkey_to_packed(k));
 fsck_err:
        return ret;
@@ -394,13 +393,15 @@ static int journal_entry_btree_keys_validate(struct bch_fs *c,
                                enum bch_validate_flags flags)
 {
        struct bkey_i *k = entry->start;
+       struct bkey_validate_context from = {
+               .from   = BKEY_VALIDATE_journal,
+               .level  = entry->level,
+               .btree  = entry->btree_id,
+               .flags  = flags|BCH_VALIDATE_journal,
+       };
 
        while (k != vstruct_last(entry)) {
-               int ret = journal_validate_key(c, jset, entry,
-                                              entry->level,
-                                              entry->btree_id,
-                                              k, version, big_endian,
-                                              flags|BCH_VALIDATE_journal);
+               int ret = journal_validate_key(c, jset, entry, k, from, version, big_endian);
                if (ret == FSCK_DELETED_KEY)
                        continue;
                else if (ret)
@@ -455,8 +456,14 @@ static int journal_entry_btree_root_validate(struct bch_fs *c,
                return 0;
        }
 
-       ret = journal_validate_key(c, jset, entry, 1, entry->btree_id, k,
-                                  version, big_endian, flags);
+       struct bkey_validate_context from = {
+               .from   = BKEY_VALIDATE_journal,
+               .level  = entry->level + 1,
+               .btree  = entry->btree_id,
+               .root   = true,
+               .flags  = flags,
+       };
+       ret = journal_validate_key(c, jset, entry, k, from, version, big_endian);
        if (ret == FSCK_DELETED_KEY)
                ret = 0;
 fsck_err:
index c18242748ca3451cca7e9a3e3b27994c7cec04ae..ce794d55818fb91c0c712c4e958a617e2745f80d 100644 (file)
@@ -12,7 +12,7 @@
 
 /* KEY_TYPE_lru is obsolete: */
 int bch2_lru_validate(struct bch_fs *c, struct bkey_s_c k,
-                    enum bch_validate_flags flags)
+                     struct bkey_validate_context from)
 {
        int ret = 0;
 
index e6a7d8241bb807bb658f79681f7a8fef114952cc..f31a6cf1514cdd5229c12723c3483236eaa0aaed 100644 (file)
@@ -33,7 +33,7 @@ static inline enum bch_lru_type lru_type(struct bkey_s_c l)
        return BCH_LRU_read;
 }
 
-int bch2_lru_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_lru_validate(struct bch_fs *, struct bkey_s_c, struct bkey_validate_context);
 void bch2_lru_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 void bch2_lru_pos_to_text(struct printbuf *, struct bpos);
index 74f45a8162ad7f649a8157bf7ddfd54c73021061..8b857fc33244ac3699c1b82b63aedd7650baf9e9 100644 (file)
@@ -60,7 +60,7 @@ const struct bch_sb_field_ops bch_sb_field_ops_quota = {
 };
 
 int bch2_quota_validate(struct bch_fs *c, struct bkey_s_c k,
-                       enum bch_validate_flags flags)
+                       struct bkey_validate_context from)
 {
        int ret = 0;
 
index a62abcc5332ad399c2022eb155e41106539c7ea8..1551800ff44c9183d485ae625406de9c6fe6f86f 100644 (file)
@@ -5,10 +5,10 @@
 #include "inode.h"
 #include "quota_types.h"
 
-enum bch_validate_flags;
 extern const struct bch_sb_field_ops bch_sb_field_ops_quota;
 
-int bch2_quota_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_quota_validate(struct bch_fs *, struct bkey_s_c,
+                       struct bkey_validate_context);
 void bch2_quota_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_quota ((struct bkey_ops) {       \
index 727e894762f544eebeb7c5373536e874cff58526..e361057ffad4b22614a0f858c71b41f3b26c105e 100644 (file)
@@ -569,6 +569,7 @@ static int read_btree_roots(struct bch_fs *c)
                                r->error = 0;
 
                        ret = bch2_btree_lost_data(c, i);
+                       BUG_ON(ret);
                }
        }
 
index 38db5a0117027122831b73676479cb933acfdaac..e1911b9beb61999a483137ceab2addabffc85aac 100644 (file)
@@ -41,7 +41,7 @@ static inline unsigned bkey_type_to_indirect(const struct bkey *k)
 /* reflink pointers */
 
 int bch2_reflink_p_validate(struct bch_fs *c, struct bkey_s_c k,
-                           enum bch_validate_flags flags)
+                           struct bkey_validate_context from)
 {
        struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
        int ret = 0;
@@ -89,7 +89,7 @@ bool bch2_reflink_p_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r
 /* indirect extents */
 
 int bch2_reflink_v_validate(struct bch_fs *c, struct bkey_s_c k,
-                           enum bch_validate_flags flags)
+                           struct bkey_validate_context from)
 {
        int ret = 0;
 
@@ -98,7 +98,7 @@ int bch2_reflink_v_validate(struct bch_fs *c, struct bkey_s_c k,
                         "indirect extent above maximum position 0:%llu",
                         REFLINK_P_IDX_MAX);
 
-       ret = bch2_bkey_ptrs_validate(c, k, flags);
+       ret = bch2_bkey_ptrs_validate(c, k, from);
 fsck_err:
        return ret;
 }
@@ -128,7 +128,7 @@ bool bch2_reflink_v_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r
 /* indirect inline data */
 
 int bch2_indirect_inline_data_validate(struct bch_fs *c, struct bkey_s_c k,
-                                     enum bch_validate_flags flags)
+                                      struct bkey_validate_context from)
 {
        return 0;
 }
index b61a4bdd8e829219c53b58ebeef40d2ff22cc99f..f119316adc81ec943b7294f0f0fecf6c667a247a 100644 (file)
@@ -2,9 +2,8 @@
 #ifndef _BCACHEFS_REFLINK_H
 #define _BCACHEFS_REFLINK_H
 
-enum bch_validate_flags;
-
-int bch2_reflink_p_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_reflink_p_validate(struct bch_fs *, struct bkey_s_c,
+                           struct bkey_validate_context);
 void bch2_reflink_p_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 bool bch2_reflink_p_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
 int bch2_trigger_reflink_p(struct btree_trans *, enum btree_id, unsigned,
@@ -19,7 +18,8 @@ int bch2_trigger_reflink_p(struct btree_trans *, enum btree_id, unsigned,
        .min_val_size   = 16,                                   \
 })
 
-int bch2_reflink_v_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_reflink_v_validate(struct bch_fs *, struct bkey_s_c,
+                           struct bkey_validate_context);
 void bch2_reflink_v_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 int bch2_trigger_reflink_v(struct btree_trans *, enum btree_id, unsigned,
                           struct bkey_s_c, struct bkey_s,
@@ -34,7 +34,7 @@ int bch2_trigger_reflink_v(struct btree_trans *, enum btree_id, unsigned,
 })
 
 int bch2_indirect_inline_data_validate(struct bch_fs *, struct bkey_s_c,
-                                     enum bch_validate_flags);
+                                      struct bkey_validate_context);
 void bch2_indirect_inline_data_to_text(struct printbuf *,
                                struct bch_fs *, struct bkey_s_c);
 int bch2_trigger_indirect_inline_data(struct btree_trans *,
index 6a52090485dca6280de13ae235a9df5433ba0485..f368270d6d9bd282211a1b73158a258a70216393 100644 (file)
@@ -32,7 +32,7 @@ void bch2_snapshot_tree_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 int bch2_snapshot_tree_validate(struct bch_fs *c, struct bkey_s_c k,
-                              enum bch_validate_flags flags)
+                               struct bkey_validate_context from)
 {
        int ret = 0;
 
@@ -225,7 +225,7 @@ void bch2_snapshot_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 int bch2_snapshot_validate(struct bch_fs *c, struct bkey_s_c k,
-                         enum bch_validate_flags flags)
+                          struct bkey_validate_context from)
 {
        struct bkey_s_c_snapshot s;
        u32 i, id;
index 29c94716293e1ace5639ad62dd2c598df458318f..ae23d45fad6669cb10d88d368761c0174947ab0f 100644 (file)
@@ -2,11 +2,9 @@
 #ifndef _BCACHEFS_SNAPSHOT_H
 #define _BCACHEFS_SNAPSHOT_H
 
-enum bch_validate_flags;
-
 void bch2_snapshot_tree_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 int bch2_snapshot_tree_validate(struct bch_fs *, struct bkey_s_c,
-                              enum bch_validate_flags);
+                               struct bkey_validate_context);
 
 #define bch2_bkey_ops_snapshot_tree ((struct bkey_ops) {       \
        .key_validate   = bch2_snapshot_tree_validate,          \
@@ -19,7 +17,8 @@ struct bkey_i_snapshot_tree *__bch2_snapshot_tree_create(struct btree_trans *);
 int bch2_snapshot_tree_lookup(struct btree_trans *, u32, struct bch_snapshot_tree *);
 
 void bch2_snapshot_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
-int bch2_snapshot_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_snapshot_validate(struct bch_fs *, struct bkey_s_c,
+                          struct bkey_validate_context);
 int bch2_mark_snapshot(struct btree_trans *, enum btree_id, unsigned,
                       struct bkey_s_c, struct bkey_s,
                       enum btree_iter_update_trigger_flags);
index cb45ef769c540be19e52c865e8bd4c6ef7b29bf5..5e5ae405cb28782325e0293f50bcf1a12301916d 100644 (file)
@@ -207,7 +207,7 @@ int bch2_check_subvol_children(struct bch_fs *c)
 /* Subvolumes: */
 
 int bch2_subvolume_validate(struct bch_fs *c, struct bkey_s_c k,
-                          enum bch_validate_flags flags)
+                           struct bkey_validate_context from)
 {
        struct bkey_s_c_subvolume subvol = bkey_s_c_to_subvolume(k);
        int ret = 0;
index 07b23dc08614d3d84b28345010a2ccf15c51d554..d53d292c22d7acf880e9cbeedc77c89d64f304bf 100644 (file)
@@ -5,12 +5,11 @@
 #include "darray.h"
 #include "subvolume_types.h"
 
-enum bch_validate_flags;
-
 int bch2_check_subvols(struct bch_fs *);
 int bch2_check_subvol_children(struct bch_fs *);
 
-int bch2_subvolume_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_subvolume_validate(struct bch_fs *, struct bkey_s_c,
+                           struct bkey_validate_context);
 void bch2_subvolume_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 int bch2_subvolume_trigger(struct btree_trans *, enum btree_id, unsigned,
                           struct bkey_s_c, struct bkey_s,
index 820c1791545a11efd4725c75738a70a98122a360..aed7c69841734a0d85ef8e2adf68f21ec15fa9e4 100644 (file)
@@ -71,7 +71,7 @@ const struct bch_hash_desc bch2_xattr_hash_desc = {
 };
 
 int bch2_xattr_validate(struct bch_fs *c, struct bkey_s_c k,
-                      enum bch_validate_flags flags)
+                       struct bkey_validate_context from)
 {
        struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k);
        unsigned val_u64s = xattr_val_u64s(xattr.v->x_name_len,
index 2c96de051f3e29e6984b93989224fa126069beb2..132fbbd15a66d06ba4a76d1a292b72073acfe88f 100644 (file)
@@ -6,7 +6,8 @@
 
 extern const struct bch_hash_desc bch2_xattr_hash_desc;
 
-int bch2_xattr_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
+int bch2_xattr_validate(struct bch_fs *, struct bkey_s_c,
+                       struct bkey_validate_context);
 void bch2_xattr_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_xattr ((struct bkey_ops) {       \