Commit 66bddc6c authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Only try to get existing stripe once in stripe create path

The stripe creation path was too state-machiney: it would always run the
full state machine until it had succesfully created a new stripe.

But if we tried to get and reuse an existing stripe after we'd already
allocated some buckets, the buckets we'd allocated might have conflicted
with the blocks in the existing stripe we need to keep - oops.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent cc578a36
......@@ -874,7 +874,7 @@ static void ec_stripe_create(struct ec_stripe_new *s)
for_each_keylist_key(&s->keys, k) {
ret = ec_stripe_update_ptrs(c, &s->stripe, &k->k);
if (ret) {
bch_err(c, "error creating stripe: error updating pointers");
bch_err(c, "error creating stripe: error %i updating pointers", ret);
break;
}
}
......@@ -1341,16 +1341,14 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c,
if (!h)
return NULL;
if (!h->s && ec_new_stripe_alloc(c, h)) {
if (!h->s) {
if (ec_new_stripe_alloc(c, h)) {
bch2_ec_stripe_head_put(c, h);
return NULL;
}
if (!h->s->allocated) {
if (!h->s->existing_stripe &&
(idx = get_existing_stripe(c, target, algo, redundancy)) >= 0) {
//pr_info("got existing stripe %llu", idx);
idx = get_existing_stripe(c, target, algo, redundancy);
if (idx >= 0) {
h->s->existing_stripe = true;
h->s->existing_stripe_idx = idx;
if (get_stripe_key(c, idx, &h->s->stripe)) {
......@@ -1364,7 +1362,9 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct bch_fs *c,
ec_block_io(c, &h->s->stripe, READ, i, &cl);
}
}
}
if (!h->s->allocated) {
if (!h->s->existing_stripe &&
!h->s->res.sectors) {
ret = bch2_disk_reservation_get(c, &h->s->res,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment