diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-09-27 21:08:39 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:10 -0400 |
commit | 71c9e0ba427ae0572693c133e33dad30efaf3aba (patch) | |
tree | 0fab58d78d2842a83b6d733bedf68927c84c3688 | |
parent | a2753581f6c5c05ea93978f8217a29115450ac58 (diff) | |
download | linux-stable-71c9e0ba427ae0572693c133e33dad30efaf3aba.tar.gz linux-stable-71c9e0ba427ae0572693c133e33dad30efaf3aba.tar.bz2 linux-stable-71c9e0ba427ae0572693c133e33dad30efaf3aba.zip |
bcachefs: bch2_extent_ptr_decoded_append()
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>
-rw-r--r-- | fs/bcachefs/extents.c | 129 | ||||
-rw-r--r-- | fs/bcachefs/extents.h | 9 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/util.h | 10 |
5 files changed, 69 insertions, 94 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 8b84c5e00a26..ae6b1a17abfa 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -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)); } /* diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h index c45d70657a89..fe5eb32b6ed9 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -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 *); diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index d17128f50f98..549a179b85e6 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -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); diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index edc45201faa6..c7132a65566b 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -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; } diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h index 446216eb8c76..44e2c96b6509 100644 --- a/fs/bcachefs/util.h +++ b/fs/bcachefs/util.h @@ -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) { |