diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-09-30 18:28:23 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:10 -0400 |
commit | a2753581f6c5c05ea93978f8217a29115450ac58 (patch) | |
tree | 6a04ae18d5ebfa7808713af91d160716cd03af65 /fs | |
parent | 1742237ba1db942b84a697509543fc5a9a25fcfa (diff) |
bcachefs: bch2_extent_drop_ptrs()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/btree_io.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 73 | ||||
-rw-r--r-- | fs/bcachefs/extents.h | 43 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/journal_io.c | 19 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 10 |
6 files changed, 71 insertions, 86 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index 96bcdf5339e8..e64e53e9d9ab 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -1570,9 +1570,9 @@ retry: new_key = bkey_i_to_extent(&tmp.k); e = extent_i_to_s(new_key); - extent_for_each_ptr_backwards(e, ptr) - if (bch2_dev_list_has_dev(wbio->wbio.failed, ptr->dev)) - bch2_extent_drop_ptr(e, ptr); + + bch2_extent_drop_ptrs(e, ptr, + bch2_dev_list_has_dev(wbio->wbio.failed, ptr->dev)); if (!bch2_extent_nr_ptrs(e.c)) goto err; diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 0441e42bb1c4..8b84c5e00a26 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -122,20 +122,11 @@ bch2_extent_has_device(struct bkey_s_c_extent e, unsigned dev) return NULL; } -bool bch2_extent_drop_device(struct bkey_s_extent e, unsigned dev) +void bch2_extent_drop_device(struct bkey_s_extent e, unsigned dev) { struct bch_extent_ptr *ptr; - bool dropped = false; - extent_for_each_ptr_backwards(e, ptr) - if (ptr->dev == dev) { - __bch2_extent_drop_ptr(e, ptr); - dropped = true; - } - - if (dropped) - bch2_extent_drop_redundant_crcs(e); - return dropped; + bch2_extent_drop_ptrs(e, ptr, ptr->dev == dev); } const struct bch_extent_ptr * @@ -267,21 +258,37 @@ bool bch2_extent_matches_ptr(struct bch_fs *c, struct bkey_s_c_extent e, return false; } -/* Doesn't cleanup redundant crcs */ -void __bch2_extent_drop_ptr(struct bkey_s_extent e, struct bch_extent_ptr *ptr) +union bch_extent_entry *bch2_extent_drop_ptr(struct bkey_s_extent e, + struct bch_extent_ptr *ptr) { + union bch_extent_entry *dst; + union bch_extent_entry *src; + EBUG_ON(ptr < &e.v->start->ptr || ptr >= &extent_entry_last(e)->ptr); EBUG_ON(ptr->type != 1 << BCH_EXTENT_ENTRY_ptr); - memmove_u64s_down(ptr, ptr + 1, - (u64 *) extent_entry_last(e) - (u64 *) (ptr + 1)); - e.k->u64s -= sizeof(*ptr) / sizeof(u64); -} -void bch2_extent_drop_ptr(struct bkey_s_extent e, struct bch_extent_ptr *ptr) -{ - __bch2_extent_drop_ptr(e, ptr); - bch2_extent_drop_redundant_crcs(e); + src = to_entry(ptr + 1); + + if (src != extent_entry_last(e) && + extent_entry_type(src) == BCH_EXTENT_ENTRY_ptr) { + dst = to_entry(ptr); + } else { + extent_for_each_entry(e, dst) { + if (dst == to_entry(ptr)) + break; + + if (extent_entry_next(dst) == to_entry(ptr) && + extent_entry_is_crc(dst)) + break; + } + } + + memmove_u64s_down(dst, src, + (u64 *) extent_entry_last(e) - (u64 *) src); + e.k->u64s -= (u64 *) src - (u64 *) dst; + + return dst; } static inline bool can_narrow_crc(struct bch_extent_crc_unpacked u, @@ -349,7 +356,7 @@ restart_narrow_pointers: 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); + bch2_extent_drop_ptr(extent_i_to_s(e), &i->ptr); goto restart_narrow_pointers; } @@ -431,27 +438,13 @@ drop: EBUG_ON(bkey_val_u64s(e.k) && !bch2_extent_nr_ptrs(e.c)); } -static bool should_drop_ptr(const struct bch_fs *c, - struct bkey_s_c_extent e, - const struct bch_extent_ptr *ptr) -{ - return ptr->cached && ptr_stale(bch_dev_bkey_exists(c, ptr->dev), ptr); -} - static void bch2_extent_drop_stale(struct bch_fs *c, struct bkey_s_extent e) { - struct bch_extent_ptr *ptr = &e.v->start->ptr; - bool dropped = false; - - while ((ptr = extent_ptr_next(e, ptr))) - if (should_drop_ptr(c, e.c, ptr)) { - __bch2_extent_drop_ptr(e, ptr); - dropped = true; - } else - ptr++; + struct bch_extent_ptr *ptr; - if (dropped) - bch2_extent_drop_redundant_crcs(e); + bch2_extent_drop_ptrs(e, ptr, + ptr->cached && + ptr_stale(bch_dev_bkey_exists(c, ptr->dev), ptr)); } bool bch2_ptr_normalize(struct bch_fs *c, struct btree *b, struct bkey_s k) diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h index b1b9c189867a..c45d70657a89 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -84,7 +84,7 @@ void bch2_extent_mark_replicas_cached(struct bch_fs *, struct bkey_s_extent, const struct bch_extent_ptr * bch2_extent_has_device(struct bkey_s_c_extent, unsigned); -bool bch2_extent_drop_device(struct bkey_s_extent, unsigned); +void bch2_extent_drop_device(struct bkey_s_extent, unsigned); const struct bch_extent_ptr * bch2_extent_has_group(struct bch_fs *, struct bkey_s_c_extent, unsigned); const struct bch_extent_ptr * @@ -400,29 +400,6 @@ out: \ /* Iterate over pointers backwards: */ -#define extent_ptr_prev(_e, _ptr) \ -({ \ - typeof(&(_e).v->start->ptr) _p; \ - typeof(&(_e).v->start->ptr) _prev = NULL; \ - \ - extent_for_each_ptr(_e, _p) { \ - if (_p == (_ptr)) \ - break; \ - _prev = _p; \ - } \ - \ - _prev; \ -}) - -/* - * Use this when you'll be dropping pointers as you iterate. Quadratic, - * unfortunately: - */ -#define extent_for_each_ptr_backwards(_e, _ptr) \ - for ((_ptr) = extent_ptr_prev(_e, NULL); \ - (_ptr); \ - (_ptr) = extent_ptr_prev(_e, _ptr)) - void bch2_extent_crc_append(struct bkey_i_extent *, struct bch_extent_crc_unpacked); @@ -517,8 +494,22 @@ bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent, bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked); void bch2_extent_drop_redundant_crcs(struct bkey_s_extent); -void __bch2_extent_drop_ptr(struct bkey_s_extent, struct bch_extent_ptr *); -void bch2_extent_drop_ptr(struct bkey_s_extent, struct bch_extent_ptr *); +union bch_extent_entry *bch2_extent_drop_ptr(struct bkey_s_extent , + struct bch_extent_ptr *); + +#define bch2_extent_drop_ptrs(_e, _ptr, _cond) \ +do { \ + _ptr = &(_e).v->start->ptr; \ + \ + while ((_ptr = extent_ptr_next(e, _ptr))) { \ + if (_cond) { \ + _ptr = (void *) bch2_extent_drop_ptr(_e, _ptr); \ + continue; \ + } \ + \ + (_ptr)++; \ + } \ +} while (0) bool bch2_cut_front(struct bpos, struct bkey_i *); bool bch2_cut_back(struct bpos, struct bkey *); diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index d64463751b84..d17128f50f98 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -327,9 +327,9 @@ static void __bch2_write_index(struct bch_write_op *op) bkey_copy(dst, src); e = bkey_i_to_s_extent(dst); - extent_for_each_ptr_backwards(e, ptr) - if (test_bit(ptr->dev, op->failed.d)) - bch2_extent_drop_ptr(e, ptr); + + bch2_extent_drop_ptrs(e, ptr, + test_bit(ptr->dev, op->failed.d)); if (!bch2_extent_nr_ptrs(e.c)) { ret = -EIO; diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index 9dd881c0410e..648c4ac58a2c 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -1067,14 +1067,19 @@ static int journal_write_alloc(struct journal *j, struct journal_buf *w, * entry - that's why we drop pointers to devices <= current free space, * i.e. whichever device was limiting the current journal entry size. */ - extent_for_each_ptr_backwards(e, ptr) { - ca = bch_dev_bkey_exists(c, ptr->dev); + bch2_extent_drop_ptrs(e, ptr, ({ + ca = bch_dev_bkey_exists(c, ptr->dev); - if (ca->mi.state != BCH_MEMBER_STATE_RW || - ca->journal.sectors_free <= sectors) - __bch2_extent_drop_ptr(e, ptr); - else - ca->journal.sectors_free -= sectors; + ca->mi.state != BCH_MEMBER_STATE_RW || + ca->journal.sectors_free <= sectors; + })); + + extent_for_each_ptr(e, ptr) { + ca = bch_dev_bkey_exists(c, ptr->dev); + + BUG_ON(ca->mi.state != BCH_MEMBER_STATE_RW || + ca->journal.sectors_free <= sectors); + ca->journal.sectors_free -= sectors; } replicas = bch2_extent_nr_ptrs(e.c); diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index 1e63d0e5ce53..edc45201faa6 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -98,13 +98,9 @@ static int bch2_migrate_index_update(struct bch_write_op *op) bch2_cut_back(new->k.p, &insert->k); bch2_cut_back(insert->k.p, &new->k); - if (m->data_cmd == DATA_REWRITE) { - struct bch_extent_ptr *ptr = (void *) - bch2_extent_has_device(extent_i_to_s_c(insert), - m->data_opts.rewrite_dev); - BUG_ON(!ptr); - bch2_extent_drop_ptr(extent_i_to_s(insert), ptr); - } + if (m->data_cmd == DATA_REWRITE) + bch2_extent_drop_device(extent_i_to_s(insert), + m->data_opts.rewrite_dev); extent_for_each_ptr_decode(extent_i_to_s(new), p, entry) { if (bch2_extent_has_device(extent_i_to_s_c(insert), p.ptr.dev)) { |