bcachefs: bch2_extent_ptr_decoded_append()
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 28 Sep 2018 01:08:39 +0000 (21:08 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:10 +0000 (17:08 -0400)
This new helper for the move path avoids creating a new CRC entry when
we already have one that matches the pointer being added.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/extents.c
fs/bcachefs/extents.h
fs/bcachefs/io.c
fs/bcachefs/move.c
fs/bcachefs/util.h

index 8b84c5e00a26d158a236ff91213847cfcdab672e..ae6b1a17abfa64bdf3592b3ba245848792a49699 100644 (file)
@@ -332,36 +332,36 @@ bool bch2_extent_narrow_crcs(struct bkey_i_extent *e,
        struct bch_extent_crc_unpacked u;
        struct extent_ptr_decoded p;
        union bch_extent_entry *i;
+       bool ret = false;
 
        /* Find a checksum entry that covers only live data: */
-       if (!n.csum_type)
+       if (!n.csum_type) {
                extent_for_each_crc(extent_i_to_s(e), u, i)
                        if (!u.compression_type &&
                            u.csum_type &&
                            u.live_size == u.uncompressed_size) {
                                n = u;
-                               break;
+                               goto found;
                        }
-
-       if (!bch2_can_narrow_extent_crcs(extent_i_to_s_c(e), n))
                return false;
-
+       }
+found:
        BUG_ON(n.compression_type);
        BUG_ON(n.offset);
        BUG_ON(n.live_size != e->k.size);
 
-       bch2_extent_crc_append(e, n);
 restart_narrow_pointers:
        extent_for_each_ptr_decode(extent_i_to_s(e), p, i)
                if (can_narrow_crc(p.crc, n)) {
-                       i->ptr.offset += p.crc.offset;
-                       extent_ptr_append(e, i->ptr);
                        bch2_extent_drop_ptr(extent_i_to_s(e), &i->ptr);
+                       p.ptr.offset += p.crc.offset;
+                       p.crc = n;
+                       bch2_extent_ptr_decoded_append(e, &p);
+                       ret = true;
                        goto restart_narrow_pointers;
                }
 
-       bch2_extent_drop_redundant_crcs(extent_i_to_s(e));
-       return true;
+       return ret;
 }
 
 /* returns true if not equal */
@@ -378,66 +378,6 @@ static inline bool bch2_crc_unpacked_cmp(struct bch_extent_crc_unpacked l,
                bch2_crc_cmp(l.csum, r.csum));
 }
 
-void bch2_extent_drop_redundant_crcs(struct bkey_s_extent e)
-{
-       union bch_extent_entry *entry = e.v->start;
-       union bch_extent_crc *crc, *prev = NULL;
-       struct bch_extent_crc_unpacked u, prev_u = { 0 };
-
-       while (entry != extent_entry_last(e)) {
-               union bch_extent_entry *next = extent_entry_next(entry);
-               size_t crc_u64s = extent_entry_u64s(entry);
-
-               if (!extent_entry_is_crc(entry))
-                       goto next;
-
-               crc = entry_to_crc(entry);
-               u = bch2_extent_crc_unpack(e.k, crc);
-
-               if (next == extent_entry_last(e)) {
-                       /* crc entry with no pointers after it: */
-                       goto drop;
-               }
-
-               if (extent_entry_is_crc(next)) {
-                       /* no pointers before next crc entry: */
-                       goto drop;
-               }
-
-               if (prev && !bch2_crc_unpacked_cmp(u, prev_u)) {
-                       /* identical to previous crc entry: */
-                       goto drop;
-               }
-
-               if (!prev &&
-                   !u.csum_type &&
-                   !u.compression_type) {
-                       /* null crc entry: */
-                       union bch_extent_entry *e2;
-
-                       extent_for_each_entry_from(e, e2, extent_entry_next(entry)) {
-                               if (!extent_entry_is_ptr(e2))
-                                       break;
-
-                               e2->ptr.offset += u.offset;
-                       }
-                       goto drop;
-               }
-
-               prev = crc;
-               prev_u = u;
-next:
-               entry = next;
-               continue;
-drop:
-               memmove_u64s_down(crc, next,
-                                 (u64 *) extent_entry_last(e) - (u64 *) next);
-               e.k->u64s -= crc_u64s;
-       }
-
-       EBUG_ON(bkey_val_u64s(e.k) && !bch2_extent_nr_ptrs(e.c));
-}
-
 static void bch2_extent_drop_stale(struct bch_fs *c, struct bkey_s_extent e)
 {
        struct bch_extent_ptr *ptr;
@@ -1846,25 +1786,44 @@ static void bch2_extent_crc_init(union bch_extent_crc *crc,
 void bch2_extent_crc_append(struct bkey_i_extent *e,
                            struct bch_extent_crc_unpacked new)
 {
-       struct bch_extent_crc_unpacked crc;
-       const union bch_extent_entry *i;
+       bch2_extent_crc_init((void *) extent_entry_last(extent_i_to_s(e)), new);
+       __extent_entry_push(e);
+}
 
-       BUG_ON(new.compressed_size > new.uncompressed_size);
-       BUG_ON(new.live_size != e->k.size);
-       BUG_ON(!new.compressed_size || !new.uncompressed_size);
+static inline void __extent_entry_insert(struct bkey_i_extent *e,
+                                        union bch_extent_entry *dst,
+                                        union bch_extent_entry *new)
+{
+       union bch_extent_entry *end = extent_entry_last(extent_i_to_s(e));
 
-       /*
-        * Look up the last crc entry, so we can check if we need to add
-        * another:
-        */
-       extent_for_each_crc(extent_i_to_s(e), crc, i)
-               ;
+       memmove_u64s_up((u64 *) dst + extent_entry_u64s(new),
+                       dst, (u64 *) end - (u64 *) dst);
+       e->k.u64s += extent_entry_u64s(new);
+       memcpy_u64s_small(dst, new, extent_entry_u64s(new));
+}
 
-       if (!bch2_crc_unpacked_cmp(crc, new))
-               return;
+void bch2_extent_ptr_decoded_append(struct bkey_i_extent *e,
+                                   struct extent_ptr_decoded *p)
+{
+       struct bch_extent_crc_unpacked crc = bch2_extent_crc_unpack(&e->k, NULL);
+       union bch_extent_entry *pos;
 
-       bch2_extent_crc_init((void *) extent_entry_last(extent_i_to_s(e)), new);
-       __extent_entry_push(e);
+       if (!bch2_crc_unpacked_cmp(crc, p->crc)) {
+               pos = e->v.start;
+               goto found;
+       }
+
+       extent_for_each_crc(extent_i_to_s(e), crc, pos)
+               if (!bch2_crc_unpacked_cmp(crc, p->crc)) {
+                       pos = extent_entry_next(pos);
+                       goto found;
+               }
+
+       bch2_extent_crc_append(e, p->crc);
+       pos = extent_entry_last(extent_i_to_s(e));
+found:
+       p->ptr.type = 1 << BCH_EXTENT_ENTRY_ptr;
+       __extent_entry_insert(e, pos, to_entry(&p->ptr));
 }
 
 /*
index c45d70657a8918c1bbcf6f83d8e0ff9d77302500..fe5eb32b6ed9473636de13ce2939f487e3e35be5 100644 (file)
@@ -213,11 +213,13 @@ union bch_extent_crc {
 #define to_entry(_entry)                                               \
 ({                                                                     \
        BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) &&        \
-                    !type_is(_entry, struct bch_extent_ptr *));        \
+                    !type_is(_entry, struct bch_extent_ptr *) &&       \
+                    !type_is(_entry, struct bch_extent_stripe_ptr *)); \
                                                                        \
        __builtin_choose_expr(                                          \
                (type_is_exact(_entry, const union bch_extent_crc *) || \
-                type_is_exact(_entry, const struct bch_extent_ptr *)), \
+                type_is_exact(_entry, const struct bch_extent_ptr *) ||\
+                type_is_exact(_entry, const struct bch_extent_stripe_ptr *)),\
                (const union bch_extent_entry *) (_entry),              \
                (union bch_extent_entry *) (_entry));                   \
 })
@@ -402,6 +404,8 @@ out:                                                                        \
 
 void bch2_extent_crc_append(struct bkey_i_extent *,
                            struct bch_extent_crc_unpacked);
+void bch2_extent_ptr_decoded_append(struct bkey_i_extent *,
+                                   struct extent_ptr_decoded *);
 
 static inline void __extent_entry_push(struct bkey_i_extent *e)
 {
@@ -492,7 +496,6 @@ static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k)
 bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent,
                                 struct bch_extent_crc_unpacked);
 bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked);
-void bch2_extent_drop_redundant_crcs(struct bkey_s_extent);
 
 union bch_extent_entry *bch2_extent_drop_ptr(struct bkey_s_extent ,
                                             struct bch_extent_ptr *);
index d17128f50f98b0be5108cb3dc98b4569f2de7058..549a179b85e6a38f712c36665d55ea80216f587d 100644 (file)
@@ -431,12 +431,16 @@ static void init_append_extent(struct bch_write_op *op,
        struct bkey_i_extent *e = bkey_extent_init(op->insert_keys.top);
 
        op->pos.offset += crc.uncompressed_size;
-       e->k.p = op->pos;
-       e->k.size = crc.uncompressed_size;
-       e->k.version = version;
+       e->k.p          = op->pos;
+       e->k.size       = crc.uncompressed_size;
+       e->k.version    = version;
        bkey_extent_set_cached(&e->k, op->flags & BCH_WRITE_CACHED);
 
-       bch2_extent_crc_append(e, crc);
+       if (crc.csum_type ||
+           crc.compression_type ||
+           crc.nonce)
+               bch2_extent_crc_append(e, crc);
+
        bch2_alloc_sectors_append_ptrs(op->c, wp, e, crc.compressed_size);
 
        bch2_keylist_push(&op->insert_keys);
index edc45201faa6537ce3e19c9e55822f0ffc355df6..c7132a65566b715bbaed4d9c2ea8a3fb7b81e709 100644 (file)
@@ -112,8 +112,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
                                continue;
                        }
 
-                       bch2_extent_crc_append(insert, p.crc);
-                       extent_ptr_append(insert, p.ptr);
+                       bch2_extent_ptr_decoded_append(insert, &p);
                        did_work = true;
                }
 
index 446216eb8c763eedbd4d00e86d753a6d2a45b453..44e2c96b65090beeaf95d99e931857938801ba09 100644 (file)
@@ -581,6 +581,16 @@ size_t bch2_rand_range(size_t);
 void memcpy_to_bio(struct bio *, struct bvec_iter, void *);
 void memcpy_from_bio(void *, struct bio *, struct bvec_iter);
 
+static inline void memcpy_u64s_small(void *dst, const void *src,
+                                    unsigned u64s)
+{
+       u64 *d = dst;
+       const u64 *s = src;
+
+       while (u64s--)
+               *d++ = *s++;
+}
+
 static inline void __memcpy_u64s(void *dst, const void *src,
                                 unsigned u64s)
 {