summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-09-30 18:28:23 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:10 -0400
commita2753581f6c5c05ea93978f8217a29115450ac58 (patch)
tree6a04ae18d5ebfa7808713af91d160716cd03af65 /fs
parent1742237ba1db942b84a697509543fc5a9a25fcfa (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.c6
-rw-r--r--fs/bcachefs/extents.c73
-rw-r--r--fs/bcachefs/extents.h43
-rw-r--r--fs/bcachefs/io.c6
-rw-r--r--fs/bcachefs/journal_io.c19
-rw-r--r--fs/bcachefs/move.c10
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)) {