Commit 50ad5d09 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix btree_node_read_all_replicas() error handling

We weren't checking bch2_btree_node_read_done() for errors, oops.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent d976a84e
...@@ -1187,31 +1187,27 @@ static void btree_node_read_all_replicas_done(struct closure *cl) ...@@ -1187,31 +1187,27 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
container_of(cl, struct btree_node_read_all, cl); container_of(cl, struct btree_node_read_all, cl);
struct bch_fs *c = ra->c; struct bch_fs *c = ra->c;
struct btree *b = ra->b; struct btree *b = ra->b;
bool have_good_copy = false;
bool dump_bset_maps = false; bool dump_bset_maps = false;
bool have_retry = false; bool have_retry = false;
int ret = 0, write = READ; int ret = 0, best = -1, write = READ;
unsigned i, written, written2; unsigned i, written, written2;
__le64 seq = b->key.k.type == KEY_TYPE_btree_ptr_v2 __le64 seq = b->key.k.type == KEY_TYPE_btree_ptr_v2
? bkey_i_to_btree_ptr_v2(&b->key)->v.seq : 0; ? bkey_i_to_btree_ptr_v2(&b->key)->v.seq : 0;
for (i = 0; i < ra->nr; i++) { for (i = 0; i < ra->nr; i++) {
struct btree_node *bn = ra->buf[i];
if (ra->err[i]) if (ra->err[i])
continue; continue;
if (!have_good_copy) { if (le64_to_cpu(bn->magic) != bset_magic(c) ||
memcpy(b->data, ra->buf[i], btree_bytes(c)); (seq && seq != bn->keys.seq))
have_good_copy = true; continue;
written = btree_node_sectors_written(c, b->data);
}
/* Try to get the right btree node: */ if (best < 0) {
if (have_good_copy && best = i;
seq && written = btree_node_sectors_written(c, bn);
b->data->keys.seq != seq && continue;
((struct btree_node *) ra->buf[i])->keys.seq == seq) {
memcpy(b->data, ra->buf[i], btree_bytes(c));
written = btree_node_sectors_written(c, b->data);
} }
written2 = btree_node_sectors_written(c, ra->buf[i]); written2 = btree_node_sectors_written(c, ra->buf[i]);
...@@ -1221,14 +1217,14 @@ static void btree_node_read_all_replicas_done(struct closure *cl) ...@@ -1221,14 +1217,14 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
btree_err_on(btree_node_has_extra_bsets(c, written2, ra->buf[i]), btree_err_on(btree_node_has_extra_bsets(c, written2, ra->buf[i]),
BTREE_ERR_FIXABLE, c, NULL, b, NULL, BTREE_ERR_FIXABLE, c, NULL, b, NULL,
"found bset signature after last bset") || "found bset signature after last bset") ||
btree_err_on(memcmp(b->data, ra->buf[i], written << 9), btree_err_on(memcmp(ra->buf[best], ra->buf[i], written << 9),
BTREE_ERR_FIXABLE, c, NULL, b, NULL, BTREE_ERR_FIXABLE, c, NULL, b, NULL,
"btree node replicas content mismatch")) "btree node replicas content mismatch"))
dump_bset_maps = true; dump_bset_maps = true;
if (written2 > written) { if (written2 > written) {
written = written2; written = written2;
memcpy(b->data, ra->buf[i], btree_bytes(c)); best = i;
} }
} }
fsck_err: fsck_err:
...@@ -1281,9 +1277,14 @@ static void btree_node_read_all_replicas_done(struct closure *cl) ...@@ -1281,9 +1277,14 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
} }
} }
if (have_good_copy) if (best >= 0) {
bch2_btree_node_read_done(c, NULL, b, false); memcpy(b->data, ra->buf[best], btree_bytes(c));
else ret = bch2_btree_node_read_done(c, NULL, b, false);
} else {
ret = -1;
}
if (ret)
set_btree_node_read_error(b); set_btree_node_read_error(b);
for (i = 0; i < ra->nr; i++) { for (i = 0; i < ra->nr; i++) {
......
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