summaryrefslogtreecommitdiff
path: root/fs/bcachefs/ec.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-05-13 07:30:02 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:08:22 +0300
commit42c7d748e4983be1b7fdf3ff58920eab92c8833d (patch)
treea1aa0c09b40430ab4915d9433dca8117bf6df848 /fs/bcachefs/ec.c
parent6009b4e5086783619172900e4090781491664517 (diff)
downloadlinux-42c7d748e4983be1b7fdf3ff58920eab92c8833d.tar.xz
bcachefs: stripe creation fixes
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/ec.c')
-rw-r--r--fs/bcachefs/ec.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
index 07245717ca4e..56939428a21a 100644
--- a/fs/bcachefs/ec.c
+++ b/fs/bcachefs/ec.c
@@ -180,6 +180,25 @@ static int extent_matches_stripe(struct bch_fs *c,
return -1;
}
+static bool extent_has_stripe_ptr(struct bkey_s_c k, u64 idx)
+{
+ struct bkey_s_c_extent e;
+ const union bch_extent_entry *entry;
+
+ if (!bkey_extent_is_data(k.k))
+ return false;
+
+ e = bkey_s_c_to_extent(k);
+
+ extent_for_each_entry(e, entry)
+ if (extent_entry_type(entry) ==
+ BCH_EXTENT_ENTRY_stripe_ptr &&
+ entry->stripe_ptr.idx == idx)
+ return true;
+
+ return false;
+}
+
static void ec_stripe_key_init(struct bch_fs *c,
struct bkey_i_stripe *s,
struct open_buckets *blocks,
@@ -756,12 +775,19 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
while ((k = bch2_btree_iter_peek(iter)).k &&
!(ret = bkey_err(k)) &&
bkey_cmp(bkey_start_pos(k.k), pos->p) < 0) {
+ if (extent_has_stripe_ptr(k, s->key.k.p.offset)) {
+ bch2_btree_iter_next(iter);
+ continue;
+ }
+
idx = extent_matches_stripe(c, &s->key.v, k);
if (idx < 0) {
bch2_btree_iter_next(iter);
continue;
}
+ bch2_btree_iter_set_pos(iter, bkey_start_pos(k.k));
+
dev = s->key.v.ptrs[idx].dev;
bkey_reassemble(&tmp.k, k);