bcachefs: Kill bch2_bkey_ptr_data_type()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 25 Mar 2024 23:26:05 +0000 (19:26 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 1 Apr 2024 00:36:11 +0000 (20:36 -0400)
Remove some duplication, and inconsistency between check_fix_ptrs and
the main ptr marking paths

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/backpointers.c
fs/bcachefs/backpointers.h
fs/bcachefs/btree_gc.c
fs/bcachefs/buckets.c
fs/bcachefs/extents.h

index 21b3ae7df82404474f8da819ac7e3648a87f5f70..7537d78aa9db6d833c305af8519bb30481fbef2f 100644 (file)
@@ -29,8 +29,7 @@ static bool extent_matches_bp(struct bch_fs *c,
                if (p.ptr.cached)
                        continue;
 
-               bch2_extent_ptr_to_bp(c, btree_id, level, k, p,
-                                     &bucket2, &bp2);
+               bch2_extent_ptr_to_bp(c, btree_id, level, k, p, entry, &bucket2, &bp2);
                if (bpos_eq(bucket, bucket2) &&
                    !memcmp(&bp, &bp2, sizeof(bp)))
                        return true;
@@ -507,8 +506,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
                if (p.ptr.cached)
                        continue;
 
-               bch2_extent_ptr_to_bp(c, btree, level,
-                                     k, p, &bucket_pos, &bp);
+               bch2_extent_ptr_to_bp(c, btree, level, k, p, entry, &bucket_pos, &bp);
 
                ret = check_bp_exists(trans, s, bucket_pos, bp, k);
                if (ret)
index 327365a9feac4e8fa69575ec6fe6157fd3edb127..da012ca7daee5501fe04be48bc875c918abbb33a 100644 (file)
@@ -90,20 +90,40 @@ static inline int bch2_bucket_backpointer_mod(struct btree_trans *trans,
        return bch2_trans_update_buffered(trans, BTREE_ID_backpointers, &bp_k.k_i);
 }
 
-static inline enum bch_data_type bkey_ptr_data_type(enum btree_id btree_id, unsigned level,
-                                                   struct bkey_s_c k, struct extent_ptr_decoded p)
+static inline enum bch_data_type bch2_bkey_ptr_data_type(struct bkey_s_c k,
+                                                        struct extent_ptr_decoded p,
+                                                        const union bch_extent_entry *entry)
 {
-       return  level           ? BCH_DATA_btree :
-               p.has_ec        ? BCH_DATA_stripe :
-                                 BCH_DATA_user;
+       switch (k.k->type) {
+       case KEY_TYPE_btree_ptr:
+       case KEY_TYPE_btree_ptr_v2:
+               return BCH_DATA_btree;
+       case KEY_TYPE_extent:
+       case KEY_TYPE_reflink_v:
+               return p.has_ec ? BCH_DATA_stripe : BCH_DATA_user;
+       case KEY_TYPE_stripe: {
+               const struct bch_extent_ptr *ptr = &entry->ptr;
+               struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
+
+               BUG_ON(ptr < s.v->ptrs ||
+                      ptr >= s.v->ptrs + s.v->nr_blocks);
+
+               return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant
+                       ? BCH_DATA_parity
+                       : BCH_DATA_user;
+       }
+       default:
+               BUG();
+       }
 }
 
 static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
                           enum btree_id btree_id, unsigned level,
                           struct bkey_s_c k, struct extent_ptr_decoded p,
+                          const union bch_extent_entry *entry,
                           struct bpos *bucket_pos, struct bch_backpointer *bp)
 {
-       enum bch_data_type data_type = bkey_ptr_data_type(btree_id, level, k, p);
+       enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry);
        s64 sectors = level ? btree_sectors(c) : k.k->size;
        u32 bucket_offset;
 
index 26e51af9acdcf0845fed36d65ba7cf946234b0d1..0afefccf4e520a7bccb4568b8178375c9f412550 100644 (file)
@@ -7,6 +7,7 @@
 #include "bcachefs.h"
 #include "alloc_background.h"
 #include "alloc_foreground.h"
+#include "backpointers.h"
 #include "bkey_methods.h"
 #include "bkey_buf.h"
 #include "btree_journal_iter.h"
@@ -508,7 +509,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
        bkey_for_each_ptr_decode(k->k, ptrs_c, p, entry_c) {
                struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
                struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
-               enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, &entry_c->ptr);
+               enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, p, entry_c);
 
                if (fsck_err_on(!g->gen_valid,
                                c, ptr_to_missing_alloc_key,
@@ -574,7 +575,8 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                        continue;
 
                if (fsck_err_on(bucket_data_type(g->data_type) &&
-                               bucket_data_type(g->data_type) != data_type, c,
+                               bucket_data_type(g->data_type) !=
+                               bucket_data_type(data_type), c,
                                ptr_bucket_data_type_mismatch,
                                "bucket %u:%zu different types of data in same bucket: %s, %s\n"
                                "while marking %s",
@@ -615,18 +617,13 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
        }
 
        if (do_update) {
-               struct bkey_ptrs ptrs;
-               union bch_extent_entry *entry;
-               struct bch_extent_ptr *ptr;
-               struct bkey_i *new;
-
                if (is_root) {
                        bch_err(c, "cannot update btree roots yet");
                        ret = -EINVAL;
                        goto err;
                }
 
-               new = kmalloc(bkey_bytes(k->k), GFP_KERNEL);
+               struct bkey_i *new = kmalloc(bkey_bytes(k->k), GFP_KERNEL);
                if (!new) {
                        ret = -BCH_ERR_ENOMEM_gc_repair_key;
                        bch_err_msg(c, ret, "allocating new key");
@@ -641,7 +638,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                         * btree node isn't there anymore, the read path will
                         * sort it out:
                         */
-                       ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
+                       struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
                        bkey_for_each_ptr(ptrs, ptr) {
                                struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
                                struct bucket *g = PTR_GC_BUCKET(ca, ptr);
@@ -649,19 +646,26 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
                                ptr->gen = g->gen;
                        }
                } else {
-                       bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, ({
-                               struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
-                               struct bucket *g = PTR_GC_BUCKET(ca, ptr);
-                               enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, ptr);
-
-                               (ptr->cached &&
-                                (!g->gen_valid || gen_cmp(ptr->gen, g->gen) > 0)) ||
-                               (!ptr->cached &&
-                                gen_cmp(ptr->gen, g->gen) < 0) ||
-                               gen_cmp(g->gen, ptr->gen) > BUCKET_GC_GEN_MAX ||
-                               (g->data_type &&
-                                g->data_type != data_type);
-                       }));
+                       struct bkey_ptrs ptrs;
+                       union bch_extent_entry *entry;
+restart_drop_ptrs:
+                       ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
+                       bkey_for_each_ptr_decode(bkey_i_to_s(new).k, ptrs, p, entry) {
+                               struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
+                               struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
+                               enum bch_data_type data_type = bch2_bkey_ptr_data_type(bkey_i_to_s_c(new), p, entry);
+
+                               if ((p.ptr.cached &&
+                                    (!g->gen_valid || gen_cmp(p.ptr.gen, g->gen) > 0)) ||
+                                   (!p.ptr.cached &&
+                                    gen_cmp(p.ptr.gen, g->gen) < 0) ||
+                                   gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX ||
+                                   (g->data_type &&
+                                    g->data_type != data_type)) {
+                                       bch2_bkey_drop_ptr(bkey_i_to_s(new), &entry->ptr);
+                                       goto restart_drop_ptrs;
+                               }
+                       }
 again:
                        ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
                        bkey_extent_entry_for_each(ptrs, entry) {
@@ -736,10 +740,6 @@ static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
                BUG_ON(bch2_journal_seq_verify &&
                       k->k->version.lo > atomic64_read(&c->journal.seq));
 
-               ret = bch2_check_fix_ptrs(trans, btree_id, level, is_root, k);
-               if (ret)
-                       goto err;
-
                if (fsck_err_on(k->k->version.lo > atomic64_read(&c->key_version), c,
                                bkey_version_in_future,
                                "key version number higher than recorded: %llu > %llu",
@@ -748,8 +748,13 @@ static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
                        atomic64_set(&c->key_version, k->k->version.lo);
        }
 
+       ret = bch2_check_fix_ptrs(trans, btree_id, level, is_root, k);
+       if (ret)
+               goto err;
+
        ret = commit_do(trans, NULL, NULL, 0,
-                       bch2_key_trigger(trans, btree_id, level, old, unsafe_bkey_s_c_to_s(*k), BTREE_TRIGGER_GC));
+                       bch2_key_trigger(trans, btree_id, level, old,
+                                        unsafe_bkey_s_c_to_s(*k), BTREE_TRIGGER_GC));
 fsck_err:
 err:
        bch_err_fn(c, ret);
index 96edf2c34d433d1c1ad41ec8da0c77b8d40afe9f..941401a210f56993359548e51b5095d0db45e691 100644 (file)
@@ -525,6 +525,7 @@ int bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
                        "different types of data in same bucket: %s, %s",
                        bch2_data_type_str(g->data_type),
                        bch2_data_type_str(data_type))) {
+               BUG();
                ret = -EIO;
                goto err;
        }
@@ -628,6 +629,7 @@ int bch2_check_bucket_ref(struct btree_trans *trans,
                        bch2_data_type_str(ptr_data_type),
                        (printbuf_reset(&buf),
                         bch2_bkey_val_to_text(&buf, c, k), buf.buf));
+               BUG();
                ret = -EIO;
                goto err;
        }
@@ -815,14 +817,14 @@ static int __mark_pointer(struct btree_trans *trans,
 static int bch2_trigger_pointer(struct btree_trans *trans,
                        enum btree_id btree_id, unsigned level,
                        struct bkey_s_c k, struct extent_ptr_decoded p,
-                       s64 *sectors,
-                       unsigned flags)
+                       const union bch_extent_entry *entry,
+                       s64 *sectors, unsigned flags)
 {
        bool insert = !(flags & BTREE_TRIGGER_OVERWRITE);
        struct bpos bucket;
        struct bch_backpointer bp;
 
-       bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, &bucket, &bp);
+       bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, entry, &bucket, &bp);
        *sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);
 
        if (flags & BTREE_TRIGGER_TRANSACTIONAL) {
@@ -851,7 +853,7 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
        if (flags & BTREE_TRIGGER_GC) {
                struct bch_fs *c = trans->c;
                struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
-               enum bch_data_type data_type = bkey_ptr_data_type(btree_id, level, k, p);
+               enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry);
 
                percpu_down_read(&c->mark_lock);
                struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
@@ -979,7 +981,7 @@ static int __trigger_extent(struct btree_trans *trans,
 
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
                s64 disk_sectors;
-               ret = bch2_trigger_pointer(trans, btree_id, level, k, p, &disk_sectors, flags);
+               ret = bch2_trigger_pointer(trans, btree_id, level, k, p, entry, &disk_sectors, flags);
                if (ret < 0)
                        return ret;
 
index fd2669cdd76f3b23861a9c0835253d3812a6de10..3fd0169b98c18279759e92ef148b08c4847b4fed 100644 (file)
@@ -596,30 +596,6 @@ static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k)
        return ret;
 }
 
-static inline unsigned bch2_bkey_ptr_data_type(struct bkey_s_c k, const struct bch_extent_ptr *ptr)
-{
-       switch (k.k->type) {
-       case KEY_TYPE_btree_ptr:
-       case KEY_TYPE_btree_ptr_v2:
-               return BCH_DATA_btree;
-       case KEY_TYPE_extent:
-       case KEY_TYPE_reflink_v:
-               return BCH_DATA_user;
-       case KEY_TYPE_stripe: {
-               struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
-
-               BUG_ON(ptr < s.v->ptrs ||
-                      ptr >= s.v->ptrs + s.v->nr_blocks);
-
-               return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant
-                       ? BCH_DATA_parity
-                       : BCH_DATA_user;
-       }
-       default:
-               BUG();
-       }
-}
-
 unsigned bch2_bkey_nr_ptrs(struct bkey_s_c);
 unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c);
 unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c);