]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Add rw to .key_invalid()
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 4 Apr 2022 01:50:25 +0000 (21:50 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:30 +0000 (17:09 -0400)
This adds a new parameter to .key_invalid() methods for whether the key
is being read or written; the idea being that methods can do more
aggressive checks when a key is newly created and being written, when we
wouldn't want to delete the key because of those checks.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
26 files changed:
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_background.h
fs/bcachefs/bkey_methods.c
fs/bcachefs/bkey_methods.h
fs/bcachefs/btree_io.c
fs/bcachefs/btree_update_interior.c
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/dirent.c
fs/bcachefs/dirent.h
fs/bcachefs/ec.c
fs/bcachefs/ec.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/reflink.c
fs/bcachefs/reflink.h
fs/bcachefs/subvolume.c
fs/bcachefs/subvolume.h
fs/bcachefs/xattr.c
fs/bcachefs/xattr.h

index 588f43830a361dee4aa75b22f25e3a7107debd67..cad39119949ad8cd1c83c9d998938fcc0b8f00e4 100644 (file)
@@ -302,7 +302,8 @@ static unsigned bch_alloc_v1_val_u64s(const struct bch_alloc *a)
        return DIV_ROUND_UP(bytes, sizeof(u64));
 }
 
-int bch2_alloc_v1_invalid(const struct bch_fs *c, struct bkey_s_c k, struct printbuf *err)
+int bch2_alloc_v1_invalid(const struct bch_fs *c, struct bkey_s_c k,
+                         int rw, struct printbuf *err)
 {
        struct bkey_s_c_alloc a = bkey_s_c_to_alloc(k);
 
@@ -316,7 +317,8 @@ int bch2_alloc_v1_invalid(const struct bch_fs *c, struct bkey_s_c k, struct prin
        return 0;
 }
 
-int bch2_alloc_v2_invalid(const struct bch_fs *c, struct bkey_s_c k, struct printbuf *err)
+int bch2_alloc_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
+                         int rw, struct printbuf *err)
 {
        struct bkey_alloc_unpacked u;
 
@@ -328,7 +330,8 @@ int bch2_alloc_v2_invalid(const struct bch_fs *c, struct bkey_s_c k, struct prin
        return 0;
 }
 
-int bch2_alloc_v3_invalid(const struct bch_fs *c, struct bkey_s_c k, struct printbuf *err)
+int bch2_alloc_v3_invalid(const struct bch_fs *c, struct bkey_s_c k,
+                         int rw, struct printbuf *err)
 {
        struct bkey_alloc_unpacked u;
 
@@ -340,7 +343,8 @@ int bch2_alloc_v3_invalid(const struct bch_fs *c, struct bkey_s_c k, struct prin
        return 0;
 }
 
-int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k, struct printbuf *err)
+int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
+                         int rw, struct printbuf *err)
 {
        if (bkey_val_bytes(k.k) != sizeof(struct bch_alloc_v4)) {
                pr_buf(err, "bad val size (%zu != %zu)",
index 7ca5bfd370276eefb5bf11ad7987aa46e27dc227..9c6a590fa0737ae62f8cb95a356bbeaf580a5d84 100644 (file)
@@ -78,10 +78,10 @@ int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int);
 
 #define ALLOC_SCAN_BATCH(ca)           max_t(size_t, 1, (ca)->mi.nbuckets >> 9)
 
-int bch2_alloc_v1_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
-int bch2_alloc_v2_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
-int bch2_alloc_v3_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
-int bch2_alloc_v4_invalid(const struct bch_fs *, struct bkey_s_c k, struct printbuf *);
+int bch2_alloc_v1_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_alloc_v2_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_alloc_v3_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_alloc_v4_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_alloc_v4_swab(struct bkey_s);
 void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
index 0351cbe7d48e2ee48781a92603d872dfba76bff9..62ce1264731a57c86efc272ad940d52d672d8029 100644 (file)
@@ -23,7 +23,7 @@ const char * const bch2_bkey_types[] = {
 };
 
 static int deleted_key_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                              struct printbuf *err)
+                              int rw, struct printbuf *err)
 {
        return 0;
 }
@@ -37,7 +37,7 @@ static int deleted_key_invalid(const struct bch_fs *c, struct bkey_s_c k,
 }
 
 static int empty_val_key_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                                struct printbuf *err)
+                                int rw, struct printbuf *err)
 {
        if (bkey_val_bytes(k.k)) {
                pr_buf(err, "incorrect value size (%zu != 0)",
@@ -53,7 +53,7 @@ static int empty_val_key_invalid(const struct bch_fs *c, struct bkey_s_c k,
 }
 
 static int key_type_cookie_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                                  struct printbuf *err)
+                                  int rw, struct printbuf *err)
 {
        if (bkey_val_bytes(k.k) != sizeof(struct bch_cookie)) {
                pr_buf(err, "incorrect value size (%zu != %zu)",
@@ -73,7 +73,7 @@ static int key_type_cookie_invalid(const struct bch_fs *c, struct bkey_s_c k,
 }
 
 static int key_type_inline_data_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                                       struct printbuf *err)
+                                       int rw, struct printbuf *err)
 {
        return 0;
 }
@@ -94,7 +94,7 @@ static void key_type_inline_data_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 static int key_type_set_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                               struct printbuf *err)
+                               int rw, struct printbuf *err)
 {
        if (bkey_val_bytes(k.k)) {
                pr_buf(err, "incorrect value size (%zu != %zu)",
@@ -122,14 +122,15 @@ const struct bkey_ops bch2_bkey_ops[] = {
 #undef x
 };
 
-int bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k, struct printbuf *err)
+int bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k,
+                         int rw, struct printbuf *err)
 {
        if (k.k->type >= KEY_TYPE_MAX) {
                pr_buf(err, "invalid type (%u >= %u)", k.k->type, KEY_TYPE_MAX);
                return -EINVAL;
        }
 
-       return bch2_bkey_ops[k.k->type].key_invalid(c, k, err);
+       return bch2_bkey_ops[k.k->type].key_invalid(c, k, rw, err);
 }
 
 static unsigned bch2_key_types_allowed[] = {
@@ -198,7 +199,7 @@ static unsigned bch2_key_types_allowed[] = {
 
 int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
                        enum btree_node_type type,
-                       struct printbuf *err)
+                       int rw, struct printbuf *err)
 {
        if (k.k->u64s < BKEY_U64s) {
                pr_buf(err, "u64s too small (%u < %zu)", k.k->u64s, BKEY_U64s);
@@ -254,10 +255,10 @@ int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
 
 int bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
                      enum btree_node_type type,
-                     struct printbuf *err)
+                     int rw, struct printbuf *err)
 {
-       return __bch2_bkey_invalid(c, k, type, err) ?:
-               bch2_bkey_val_invalid(c, k, err);
+       return __bch2_bkey_invalid(c, k, type, rw, err) ?:
+               bch2_bkey_val_invalid(c, k, rw, err);
 }
 
 int bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k,
index 4b90d0873be69b0d84ec769557ce47a0450c6f29..5c55e8bfe1588579bab04a2cf2ff0fa5114f4637 100644 (file)
@@ -12,10 +12,16 @@ enum btree_node_type;
 
 extern const char * const bch2_bkey_types[];
 
+/*
+ * key_invalid: checks validity of @k, returns 0 if good or -EINVAL if bad. If
+ * invalid, entire key will be deleted.
+ *
+ * When invalid, error string is returned via @err. @rw indicates whether key is
+ * being read or written; more aggressive checks can be enabled when rw == WRITE.
+*/
 struct bkey_ops {
-       /* Returns reason for being invalid if invalid, else NULL: */
-       int             (*key_invalid)(const struct bch_fs *, struct bkey_s_c,
-                                      struct printbuf *);
+       int             (*key_invalid)(const struct bch_fs *c, struct bkey_s_c k,
+                                      int rw, struct printbuf *err);
        void            (*val_to_text)(struct printbuf *, struct bch_fs *,
                                       struct bkey_s_c);
        void            (*swab)(struct bkey_s);
@@ -32,11 +38,11 @@ struct bkey_ops {
 
 extern const struct bkey_ops bch2_bkey_ops[];
 
-int bch2_bkey_val_invalid(struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_bkey_val_invalid(struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 int __bch2_bkey_invalid(struct bch_fs *, struct bkey_s_c,
-                               enum btree_node_type, struct printbuf *);
+                       enum btree_node_type, int, struct printbuf *);
 int bch2_bkey_invalid(struct bch_fs *, struct bkey_s_c,
-                             enum btree_node_type, struct printbuf *);
+                     enum btree_node_type, int, struct printbuf *);
 int bch2_bkey_in_btree_node(struct btree *, struct bkey_s_c, struct printbuf *);
 
 void bch2_bpos_to_text(struct printbuf *, struct bpos);
index d2b3ff6b9b15749b9b18ba18b331f65f9db85ef3..ba1d775039a3f80420499d872d05d0d85c986474 100644 (file)
@@ -764,12 +764,12 @@ fsck_err:
 
 static int bset_key_invalid(struct bch_fs *c, struct btree *b,
                            struct bkey_s_c k,
-                           bool updated_range, int write,
+                           bool updated_range, int rw,
                            struct printbuf *err)
 {
-       return __bch2_bkey_invalid(c, k, btree_node_type(b), err) ?:
+       return __bch2_bkey_invalid(c, k, btree_node_type(b), rw, err) ?:
                (!updated_range ? bch2_bkey_in_btree_node(b, k, err) : 0) ?:
-               (write ? bch2_bkey_val_invalid(c, k, err) : 0);
+               (rw == WRITE ? bch2_bkey_val_invalid(c, k, rw, err) : 0);
 }
 
 static int validate_bset_keys(struct bch_fs *c, struct btree *b,
@@ -1071,7 +1071,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
 
                printbuf_reset(&buf);
 
-               if (bch2_bkey_val_invalid(c, u.s_c, &buf) ||
+               if (bch2_bkey_val_invalid(c, u.s_c, READ, &buf) ||
                    (bch2_inject_invalid_keys &&
                     !bversion_cmp(u.k->version, MAX_VERSION))) {
                        printbuf_reset(&buf);
@@ -1079,7 +1079,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
                        pr_buf(&buf, "invalid bkey\n  ");
                        bch2_bkey_val_to_text(&buf, c, u.s_c);
                        pr_buf(&buf, "\n  ");
-                       bch2_bkey_val_invalid(c, u.s_c, &buf);
+                       bch2_bkey_val_invalid(c, u.s_c, READ, &buf);
 
                        btree_err(BTREE_ERR_FIXABLE, c, NULL, b, i, "%s", buf.buf);
 
@@ -1730,7 +1730,8 @@ static int validate_bset_for_write(struct bch_fs *c, struct btree *b,
        struct printbuf buf = PRINTBUF;
        int ret;
 
-       ret = bch2_bkey_invalid(c, bkey_i_to_s_c(&b->key), BKEY_TYPE_btree, &buf);
+       ret = bch2_bkey_invalid(c, bkey_i_to_s_c(&b->key),
+                               BKEY_TYPE_btree, WRITE, &buf);
 
        if (ret)
                bch2_fs_inconsistent(c, "invalid btree node key before write: %s", buf.buf);
index 0e3b3565be596e96fb2193f50675407c3c64f677..10d22d9b8c0df3de31757d7725a77769414cf20f 100644 (file)
@@ -1184,13 +1184,15 @@ 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_invalid(c, bkey_i_to_s_c(insert), btree_node_type(b), &buf) ?:
+       if (bch2_bkey_invalid(c, bkey_i_to_s_c(insert),
+                             btree_node_type(b), WRITE, &buf) ?:
            bch2_bkey_in_btree_node(b, bkey_i_to_s_c(insert), &buf)) {
                printbuf_reset(&buf);
                pr_buf(&buf, "inserting invalid bkey\n  ");
                bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(insert));
                pr_buf(&buf, "\n  ");
-               bch2_bkey_invalid(c, bkey_i_to_s_c(insert), btree_node_type(b), &buf);
+               bch2_bkey_invalid(c, bkey_i_to_s_c(insert),
+                                 btree_node_type(b), WRITE, &buf);
                bch2_bkey_in_btree_node(b, bkey_i_to_s_c(insert), &buf);
 
                bch2_fs_inconsistent(c, "%s", buf.buf);
index fce93ed65ed983de7bff8078ce29db87d37b505b..2c20ad89ca0a790a4deeea5d81979628e4f65491 100644 (file)
@@ -866,7 +866,8 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
        int ret, u64s_delta = 0;
 
        trans_for_each_update(trans, i) {
-               if (bch2_bkey_invalid(c, bkey_i_to_s_c(i->k), i->bkey_type, &buf)) {
+               if (bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
+                                     i->bkey_type, WRITE, &buf)) {
                        printbuf_reset(&buf);
                        pr_buf(&buf, "invalid bkey on insert from %s -> %ps",
                               trans->fn, (void *) i->ip_allocated);
@@ -876,7 +877,8 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
                        bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(i->k));
                        pr_newline(&buf);
 
-                       bch2_bkey_invalid(c, bkey_i_to_s_c(i->k), i->bkey_type, &buf);
+                       bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
+                                         i->bkey_type, WRITE, &buf);
 
                        bch2_fs_fatal_error(c, "%s", buf.buf);
                        printbuf_exit(&buf);
index e8a284a69be463dba24e2969f87e37c30c0c2aa6..281959885bb05e2bb90c05f3457f9effa53d48af 100644 (file)
@@ -84,7 +84,7 @@ const struct bch_hash_desc bch2_dirent_hash_desc = {
 };
 
 int bch2_dirent_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                       struct printbuf *err)
+                       int rw, struct printbuf *err)
 {
        struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k);
        unsigned len;
index 046f297a4effe4ac4c7e8021dc8b897f473fcd51..b1466932c76873c2d326f9d87507195e26fcb769 100644 (file)
@@ -6,7 +6,7 @@
 
 extern const struct bch_hash_desc bch2_dirent_hash_desc;
 
-int bch2_dirent_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_dirent_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_dirent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_dirent (struct bkey_ops) {       \
index cf9ecb7711c67242a3f1f04e9296ea6e80ba5e67..7a524f604875f86c1799cf0c485cb5761935679e 100644 (file)
@@ -103,7 +103,7 @@ struct ec_bio {
 /* Stripes btree keys: */
 
 int bch2_stripe_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                       struct printbuf *err)
+                       int rw, struct printbuf *err)
 {
        const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
 
@@ -129,7 +129,7 @@ int bch2_stripe_invalid(const struct bch_fs *c, struct bkey_s_c k,
                return -EINVAL;
        }
 
-       return bch2_bkey_ptrs_invalid(c, k, err);
+       return bch2_bkey_ptrs_invalid(c, k, rw, err);
 }
 
 void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
index 8e866460f8a08c701d54bfeed75c4851fa610393..af7f8eee94b09d39406938b706ee1359b547968c 100644 (file)
@@ -7,7 +7,7 @@
 #include "keylist_types.h"
 
 int bch2_stripe_invalid(const struct bch_fs *, struct bkey_s_c,
-                       struct printbuf *);
+                       int rw, struct printbuf *);
 void bch2_stripe_to_text(struct printbuf *, struct bch_fs *,
                         struct bkey_s_c);
 
index e0963602388266e894e9edc9c1cdb956a959366e..c56925d94bfeb9f265cd86d995b616544001c3bc 100644 (file)
@@ -156,7 +156,7 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k,
 /* KEY_TYPE_btree_ptr: */
 
 int bch2_btree_ptr_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                          struct printbuf *err)
+                          int rw, struct printbuf *err)
 {
        if (bkey_val_u64s(k.k) > BCH_REPLICAS_MAX) {
                pr_buf(err, "value too big (%zu > %u)",
@@ -164,7 +164,7 @@ int bch2_btree_ptr_invalid(const struct bch_fs *c, struct bkey_s_c k,
                return -EINVAL;
        }
 
-       return bch2_bkey_ptrs_invalid(c, k, err);
+       return bch2_bkey_ptrs_invalid(c, k, rw, err);
 }
 
 void bch2_btree_ptr_to_text(struct printbuf *out, struct bch_fs *c,
@@ -174,7 +174,7 @@ void bch2_btree_ptr_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 int bch2_btree_ptr_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                                     struct printbuf *err)
+                             int rw, struct printbuf *err)
 {
        struct bkey_s_c_btree_ptr_v2 bp = bkey_s_c_to_btree_ptr_v2(k);
 
@@ -197,11 +197,11 @@ int bch2_btree_ptr_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
                return -EINVAL;
        }
 
-       return bch2_bkey_ptrs_invalid(c, k, err);
+       return bch2_bkey_ptrs_invalid(c, k, rw, err);
 }
 
 void bch2_btree_ptr_v2_to_text(struct printbuf *out, struct bch_fs *c,
-                           struct bkey_s_c k)
+                              struct bkey_s_c k)
 {
        struct bkey_s_c_btree_ptr_v2 bp = bkey_s_c_to_btree_ptr_v2(k);
 
@@ -366,7 +366,7 @@ bool bch2_extent_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r)
 /* KEY_TYPE_reservation: */
 
 int bch2_reservation_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                            struct printbuf *err)
+                            int rw, struct printbuf *err)
 {
        struct bkey_s_c_reservation r = bkey_s_c_to_reservation(k);
 
@@ -1059,7 +1059,7 @@ static int extent_ptr_invalid(const struct bch_fs *c,
 }
 
 int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                          struct printbuf *err)
+                          int rw, struct printbuf *err)
 {
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
        const union bch_extent_entry *entry;
index 21f79e663c74400865bacc6736489bffac96c2b5..4f41f0fd6cb1c6b2911a0acdadcfe049ac1e7ed8 100644 (file)
@@ -367,11 +367,11 @@ int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c,
 
 /* KEY_TYPE_btree_ptr: */
 
-int bch2_btree_ptr_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_btree_ptr_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
 
-int bch2_btree_ptr_v2_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_btree_ptr_v2_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 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);
@@ -409,7 +409,8 @@ bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
 
 /* KEY_TYPE_reservation: */
 
-int bch2_reservation_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_reservation_invalid(const struct bch_fs *, struct bkey_s_c,
+                            int, struct printbuf *);
 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);
 
@@ -615,7 +616,8 @@ bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c,
 bool bch2_extent_normalize(struct bch_fs *, struct bkey_s);
 void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
-int bch2_bkey_ptrs_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_bkey_ptrs_invalid(const struct bch_fs *, struct bkey_s_c,
+                          int, struct printbuf *);
 
 void bch2_ptr_swab(struct bkey_s);
 
index 2f7bafc7db13acf4afc082571b8efdd5a81fc6a0..28f4f192772f26522f2902ad34ea9e73d455968e 100644 (file)
@@ -339,7 +339,7 @@ static int __bch2_inode_invalid(struct bkey_s_c k, struct printbuf *err)
 }
 
 int bch2_inode_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                      struct printbuf *err)
+                      int rw, struct printbuf *err)
 {
        struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
 
@@ -359,7 +359,7 @@ int bch2_inode_invalid(const struct bch_fs *c, struct bkey_s_c k,
 }
 
 int bch2_inode_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                         struct printbuf *err)
+                         int rw, struct printbuf *err)
 {
        struct bkey_s_c_inode_v2 inode = bkey_s_c_to_inode_v2(k);
 
@@ -410,7 +410,7 @@ void bch2_inode_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 int bch2_inode_generation_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                                 struct printbuf *err)
+                                 int rw, struct printbuf *err)
 {
        if (k.k->p.inode) {
                pr_buf(err, "nonzero k.p.inode");
index e3418dc4a1e9e81537d33807981bc597cd7c6d07..9442600a7440e6c471d152d86a66be932147896e 100644 (file)
@@ -6,8 +6,8 @@
 
 extern const char * const bch2_inode_opts[];
 
-int bch2_inode_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
-int bch2_inode_v2_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_inode_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_inode_v2_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_inode (struct bkey_ops) {                \
@@ -30,7 +30,8 @@ static inline bool bkey_is_inode(const struct bkey *k)
                k->type == KEY_TYPE_inode_v2;
 }
 
-int bch2_inode_generation_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_inode_generation_invalid(const struct bch_fs *, struct bkey_s_c,
+                                 int, struct printbuf *);
 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 56221e316ee6395ccd9c42eecdffbed604dd32c1..5ea685fd15e7838ede038fab140bf84a980aa5b8 100644 (file)
@@ -250,7 +250,7 @@ static int journal_validate_key(struct bch_fs *c, const char *where,
                                 write, NULL, bkey_to_packed(k));
 
        if (bch2_bkey_invalid(c, bkey_i_to_s_c(k),
-                             __btree_node_type(level, btree_id), &buf)) {
+                             __btree_node_type(level, btree_id), write, &buf)) {
                printbuf_reset(&buf);
                pr_buf(&buf, "invalid %s in %s entry offset %zi/%u:",
                       type, where,
@@ -262,7 +262,7 @@ static int journal_validate_key(struct bch_fs *c, const char *where,
                bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k));
                pr_newline(&buf);
                bch2_bkey_invalid(c, bkey_i_to_s_c(k),
-                                 __btree_node_type(level, btree_id), &buf);
+                                 __btree_node_type(level, btree_id), write, &buf);
 
                mustfix_fsck_err(c, "%s", buf.buf);
 
index c20a3bc2336b5e2c59722ac9fa84f1d130cadecb..c6f433153286a5e1529e8fa8d31cc77b50154b6a 100644 (file)
@@ -9,7 +9,7 @@
 #include "recovery.h"
 
 int bch2_lru_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                    struct printbuf *err)
+                    int rw, struct printbuf *err)
 {
        const struct bch_lru *lru = bkey_s_c_to_lru(k).v;
 
index 0af62ecf6638d9593bad0b3b59f0b83aa38000b3..e8f508174b0a81671041bf489c7ae169e8c0f3aa 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _BCACHEFS_LRU_H
 #define _BCACHEFS_LRU_H
 
-int bch2_lru_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_lru_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_lru_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_lru (struct bkey_ops) {  \
index 5f370da2f3d20bc3cd6149a013888113024e472e..364ef63146519c0b10771623859c00f4e19f415b 100644 (file)
@@ -58,7 +58,7 @@ const struct bch_sb_field_ops bch_sb_field_ops_quota = {
 };
 
 int bch2_quota_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                      struct printbuf *err)
+                      int rw, struct printbuf *err)
 {
        if (k.k->p.inode >= QTYP_NR) {
                pr_buf(err, "invalid quota type (%llu >= %u)",
index 4ba40fce39a8cf109a346138fdd8381663f80679..8c67ae1da7c75806fff2ee4a22182bdd704799aa 100644 (file)
@@ -7,7 +7,7 @@
 
 extern const struct bch_sb_field_ops bch_sb_field_ops_quota;
 
-int bch2_quota_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_quota_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_quota_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_quota (struct bkey_ops) {                \
index e07f0339d87effa695e8a95648c433c6f24324fa..6a81eb9b41a021e1ac68e21a4977fa7fc5ac3fe4 100644 (file)
@@ -26,7 +26,7 @@ static inline unsigned bkey_type_to_indirect(const struct bkey *k)
 /* reflink pointers */
 
 int bch2_reflink_p_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                          struct printbuf *err)
+                          int rw, struct printbuf *err)
 {
        struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
 
@@ -78,7 +78,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_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                          struct printbuf *err)
+                          int rw, struct printbuf *err)
 {
        struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
 
@@ -88,7 +88,7 @@ int bch2_reflink_v_invalid(const struct bch_fs *c, struct bkey_s_c k,
                return -EINVAL;
        }
 
-       return bch2_bkey_ptrs_invalid(c, k, err);
+       return bch2_bkey_ptrs_invalid(c, k, rw, err);
 }
 
 void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c,
@@ -130,7 +130,7 @@ int bch2_trans_mark_reflink_v(struct btree_trans *trans,
 /* indirect inline data */
 
 int bch2_indirect_inline_data_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                                     struct printbuf *err)
+                                     int rw, struct printbuf *err)
 {
        if (bkey_val_bytes(k.k) < sizeof(struct bch_indirect_inline_data)) {
                pr_buf(err, "incorrect value size (%zu < %zu)",
index d292761f8a980410a99492d27ae994941a141826..e0a9d8e4d1caabc11e04629b06ec62b9bb849d60 100644 (file)
@@ -2,7 +2,8 @@
 #ifndef _BCACHEFS_REFLINK_H
 #define _BCACHEFS_REFLINK_H
 
-int bch2_reflink_p_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_reflink_p_invalid(const struct bch_fs *, struct bkey_s_c,
+                          int, struct printbuf *);
 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);
@@ -15,7 +16,8 @@ bool bch2_reflink_p_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
        .atomic_trigger = bch2_mark_reflink_p,                  \
 }
 
-int bch2_reflink_v_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_reflink_v_invalid(const struct bch_fs *, struct bkey_s_c,
+                          int, struct printbuf *);
 void bch2_reflink_v_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
 int bch2_trans_mark_reflink_v(struct btree_trans *, struct bkey_s_c,
@@ -30,7 +32,7 @@ int bch2_trans_mark_reflink_v(struct btree_trans *, struct bkey_s_c,
 }
 
 int bch2_indirect_inline_data_invalid(const struct bch_fs *, struct bkey_s_c,
-                                     struct printbuf *);
+                                     int, struct printbuf *);
 void bch2_indirect_inline_data_to_text(struct printbuf *,
                                struct bch_fs *, struct bkey_s_c);
 int bch2_trans_mark_indirect_inline_data(struct btree_trans *,
index d3f043f901105ed99c5bc06fb63c1f861d9bd0f0..81bdcb7795ae5e7599af087d6054eaab42cc6459 100644 (file)
@@ -27,7 +27,7 @@ void bch2_snapshot_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 int bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                         struct printbuf *err)
+                         int rw, struct printbuf *err)
 {
        struct bkey_s_c_snapshot s;
        u32 i, id;
@@ -746,7 +746,7 @@ static int bch2_delete_dead_snapshots_hook(struct btree_trans *trans,
 /* Subvolumes: */
 
 int bch2_subvolume_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                          struct printbuf *err)
+                          int rw, struct printbuf *err)
 {
        if (bkey_cmp(k.k->p, SUBVOL_POS_MIN) < 0 ||
            bkey_cmp(k.k->p, SUBVOL_POS_MAX) > 0) {
index f466bf7e454383dab5d5854aecd504880d68c137..b1739d29c7d40af0a6082e42c4c5e0ea1cb567fb 100644 (file)
@@ -6,7 +6,8 @@
 #include "subvolume_types.h"
 
 void bch2_snapshot_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
-int bch2_snapshot_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_snapshot_invalid(const struct bch_fs *, struct bkey_s_c,
+                         int rw, struct printbuf *);
 
 #define bch2_bkey_ops_snapshot (struct bkey_ops) {             \
        .key_invalid    = bch2_snapshot_invalid,                \
@@ -96,7 +97,8 @@ int bch2_fs_snapshots_check(struct bch_fs *);
 void bch2_fs_snapshots_exit(struct bch_fs *);
 int bch2_fs_snapshots_start(struct bch_fs *);
 
-int bch2_subvolume_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_subvolume_invalid(const struct bch_fs *, struct bkey_s_c,
+                          int rw, struct printbuf *);
 void bch2_subvolume_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_subvolume (struct bkey_ops) {            \
index 55c4d48f8b388562cc1f280cc4edf1cd6e6b11ef..b5e42ca35dea11552e4e46f48ab29cb9a5edb77e 100644 (file)
@@ -70,7 +70,7 @@ const struct bch_hash_desc bch2_xattr_hash_desc = {
 };
 
 int bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k,
-                      struct printbuf *err)
+                      int rw, struct printbuf *err)
 {
        const struct xattr_handler *handler;
        struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k);
index 3fd03018fdd8d20304904200e7a1b4ccbf5d1023..66d7a1e30350e30875d3e1597675ddf264a9c8e6 100644 (file)
@@ -6,7 +6,7 @@
 
 extern const struct bch_hash_desc bch2_xattr_hash_desc;
 
-int bch2_xattr_invalid(const struct bch_fs *, struct bkey_s_c, struct printbuf *);
+int bch2_xattr_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
 void bch2_xattr_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_xattr (struct bkey_ops) {                \