Commit 2aee59eb authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: improve error messages in bch2_ec_read_extent()

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent cb771fe8
...@@ -829,13 +829,16 @@ static int get_stripe_key_trans(struct btree_trans *trans, u64 idx, ...@@ -829,13 +829,16 @@ static int get_stripe_key_trans(struct btree_trans *trans, u64 idx,
} }
/* recovery read path: */ /* recovery read path: */
int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio) int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio,
struct bkey_s_c orig_k)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct ec_stripe_buf *buf; struct ec_stripe_buf *buf = NULL;
struct closure cl; struct closure cl;
struct bch_stripe *v; struct bch_stripe *v;
unsigned i, offset; unsigned i, offset;
const char *msg = NULL;
struct printbuf msgbuf = PRINTBUF;
int ret = 0; int ret = 0;
closure_init_stack(&cl); closure_init_stack(&cl);
...@@ -848,32 +851,28 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio) ...@@ -848,32 +851,28 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio)
ret = lockrestart_do(trans, get_stripe_key_trans(trans, rbio->pick.ec.idx, buf)); ret = lockrestart_do(trans, get_stripe_key_trans(trans, rbio->pick.ec.idx, buf));
if (ret) { if (ret) {
bch_err_ratelimited(c, msg = "stripe not found";
"error doing reconstruct read: error %i looking up stripe", ret); goto err;
kfree(buf);
return -BCH_ERR_stripe_reconstruct;
} }
v = &bkey_i_to_stripe(&buf->key)->v; v = &bkey_i_to_stripe(&buf->key)->v;
if (!bch2_ptr_matches_stripe(v, rbio->pick)) { if (!bch2_ptr_matches_stripe(v, rbio->pick)) {
bch_err_ratelimited(c, msg = "pointer doesn't match stripe";
"error doing reconstruct read: pointer doesn't match stripe");
ret = -BCH_ERR_stripe_reconstruct;
goto err; goto err;
} }
offset = rbio->bio.bi_iter.bi_sector - v->ptrs[rbio->pick.ec.block].offset; offset = rbio->bio.bi_iter.bi_sector - v->ptrs[rbio->pick.ec.block].offset;
if (offset + bio_sectors(&rbio->bio) > le16_to_cpu(v->sectors)) { if (offset + bio_sectors(&rbio->bio) > le16_to_cpu(v->sectors)) {
bch_err_ratelimited(c, msg = "read is bigger than stripe";
"error doing reconstruct read: read is bigger than stripe");
ret = -BCH_ERR_stripe_reconstruct;
goto err; goto err;
} }
ret = ec_stripe_buf_init(buf, offset, bio_sectors(&rbio->bio)); ret = ec_stripe_buf_init(buf, offset, bio_sectors(&rbio->bio));
if (ret) if (ret) {
msg = "-ENOMEM";
goto err; goto err;
}
for (i = 0; i < v->nr_blocks; i++) for (i = 0; i < v->nr_blocks; i++)
ec_block_io(c, buf, REQ_OP_READ, i, &cl); ec_block_io(c, buf, REQ_OP_READ, i, &cl);
...@@ -881,9 +880,7 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio) ...@@ -881,9 +880,7 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio)
closure_sync(&cl); closure_sync(&cl);
if (ec_nr_failed(buf) > v->nr_redundant) { if (ec_nr_failed(buf) > v->nr_redundant) {
bch_err_ratelimited(c, msg = "unable to read enough blocks";
"error doing reconstruct read: unable to read enough blocks");
ret = -BCH_ERR_stripe_reconstruct;
goto err; goto err;
} }
...@@ -895,10 +892,17 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio) ...@@ -895,10 +892,17 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio)
memcpy_to_bio(&rbio->bio, rbio->bio.bi_iter, memcpy_to_bio(&rbio->bio, rbio->bio.bi_iter,
buf->data[rbio->pick.ec.block] + ((offset - buf->offset) << 9)); buf->data[rbio->pick.ec.block] + ((offset - buf->offset) << 9));
err: out:
ec_stripe_buf_exit(buf); ec_stripe_buf_exit(buf);
kfree(buf); kfree(buf);
return ret; return ret;
err:
bch2_bkey_val_to_text(&msgbuf, c, orig_k);
bch_err_ratelimited(c,
"error doing reconstruct read: %s\n %s", msg, msgbuf.buf);
printbuf_exit(&msgbuf);;
ret = -BCH_ERR_stripe_reconstruct;
goto out;
} }
/* stripe bucket accounting: */ /* stripe bucket accounting: */
......
...@@ -206,7 +206,7 @@ struct ec_stripe_head { ...@@ -206,7 +206,7 @@ struct ec_stripe_head {
struct ec_stripe_new *s; struct ec_stripe_new *s;
}; };
int bch2_ec_read_extent(struct btree_trans *, struct bch_read_bio *); int bch2_ec_read_extent(struct btree_trans *, struct bch_read_bio *, struct bkey_s_c);
void *bch2_writepoint_ec_buf(struct bch_fs *, struct write_point *); void *bch2_writepoint_ec_buf(struct bch_fs *, struct write_point *);
......
...@@ -1092,7 +1092,7 @@ int __bch2_read_extent(struct btree_trans *trans, struct bch_read_bio *orig, ...@@ -1092,7 +1092,7 @@ int __bch2_read_extent(struct btree_trans *trans, struct bch_read_bio *orig,
trans->notrace_relock_fail = true; trans->notrace_relock_fail = true;
} else { } else {
/* Attempting reconstruct read: */ /* Attempting reconstruct read: */
if (bch2_ec_read_extent(trans, rbio)) { if (bch2_ec_read_extent(trans, rbio, k)) {
bch2_rbio_error(rbio, READ_RETRY_AVOID, BLK_STS_IOERR); bch2_rbio_error(rbio, READ_RETRY_AVOID, BLK_STS_IOERR);
goto out; goto out;
} }
......
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