summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-05-13 00:30:02 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-06-10 14:08:05 -0400
commit50afc198530319a1be9172dfbe945fe1ee832ff3 (patch)
treed17f933b4870cf3902e7eda6149a5d80e530a285
parent031f0995978a043abd02cfbfdd9d6f5db1dbc987 (diff)
bcachefs: stripe creation fixes
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-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 de2750a07964..72aa11c0e4fb 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);