diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-03-03 03:11:06 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:55 -0400 |
commit | 9d32097f3b6617680c75ccbb5cd36d89bcff0dfc (patch) | |
tree | d9e8dcb7c8761b54d8ee30e78aa9ded6184231ef | |
parent | a1fb08f5df6a8b2995d9daf8c2997cd478b51c55 (diff) | |
download | lwn-9d32097f3b6617680c75ccbb5cd36d89bcff0dfc.tar.gz lwn-9d32097f3b6617680c75ccbb5cd36d89bcff0dfc.zip |
bcachefs: More stripe create cleanup/fixes
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_gc.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/ec.c | 38 |
2 files changed, 26 insertions, 17 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index df4cdd16c08d..f6db56765f38 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -1702,11 +1702,12 @@ static int bch2_gc_write_stripes_key(struct btree_trans *trans, return 0; inconsistent: if (fsck_err_on(true, c, - "stripe has wrong block sector count %u:\n" + "stripe block %u has wrong sector count:\n" " %s\n" - " should be %u", i, + " got %u, should be %u", i, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf), + stripe_blockcount_get(s, i), m ? m->block_sectors[i] : 0)) { struct bkey_i_stripe *new; diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index 4bf655b0de0a..d206da686da8 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -866,8 +866,16 @@ static int ec_stripe_key_update(struct btree_trans *trans, goto err; } - for (i = 0; i < new->v.nr_blocks; i++) - stripe_blockcount_set(&new->v, i, stripe_blockcount_get(old, i)); + for (i = 0; i < new->v.nr_blocks; i++) { + unsigned v = stripe_blockcount_get(old, i); + + BUG_ON(v && + (old->ptrs[i].dev != new->v.ptrs[i].dev || + old->ptrs[i].gen != new->v.ptrs[i].gen || + old->ptrs[i].offset != new->v.ptrs[i].offset)); + + stripe_blockcount_set(&new->v, i, v); + } } ret = bch2_trans_update(trans, &iter, &new->k_i, 0); @@ -1542,10 +1550,11 @@ static int __bch2_ec_stripe_head_reuse(struct btree_trans *trans, struct ec_stri if (idx < 0) return -BCH_ERR_ENOSPC_stripe_reuse; - h->s->have_existing_stripe = true; ret = get_stripe_key_trans(trans, idx, &h->s->existing_stripe); if (ret) { - bch2_fs_fatal_error(c, "error reading stripe key: %i", ret); + bch2_stripe_close(c, h->s); + if (!bch2_err_matches(ret, BCH_ERR_transaction_restart)) + bch2_fs_fatal_error(c, "error reading stripe key: %s", bch2_err_str(ret)); return ret; } @@ -1569,8 +1578,8 @@ static int __bch2_ec_stripe_head_reuse(struct btree_trans *trans, struct ec_stri ec_block_io(c, &h->s->existing_stripe, READ, i, &h->s->iodone); } - bkey_copy(&h->s->new_stripe.key.k_i, - &h->s->existing_stripe.key.k_i); + bkey_copy(&h->s->new_stripe.key.k_i, &h->s->existing_stripe.key.k_i); + h->s->have_existing_stripe = true; return 0; } @@ -1584,13 +1593,14 @@ static int __bch2_ec_stripe_head_reserve(struct btree_trans *trans, struct ec_st struct bpos start_pos = bpos_max(min_pos, POS(0, c->ec_stripe_hint)); int ret; - BUG_ON(h->s->res.sectors); - - ret = bch2_disk_reservation_get(c, &h->s->res, + if (!h->s->res.sectors) { + ret = bch2_disk_reservation_get(c, &h->s->res, h->blocksize, - h->s->nr_parity, 0); - if (ret) - return ret; + h->s->nr_parity, + BCH_DISK_RESERVATION_NOFAIL); + if (ret) + return ret; + } for_each_btree_key_norestart(trans, iter, BTREE_ID_stripes, start_pos, BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k, ret) { @@ -1673,10 +1683,8 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans, if (ret && needs_stripe_new) ret = __bch2_ec_stripe_head_reuse(trans, h); - if (ret) { - bch_err_ratelimited(c, "failed to get stripe: %s", bch2_err_str(ret)); + if (ret) goto err; - } if (!h->s->allocated) { ret = new_stripe_alloc_buckets(trans, h, reserve, cl); |