diff options
Diffstat (limited to 'libbcachefs/btree_io.c')
-rw-r--r-- | libbcachefs/btree_io.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/libbcachefs/btree_io.c b/libbcachefs/btree_io.c index 5f1c3183..84fbceea 100644 --- a/libbcachefs/btree_io.c +++ b/libbcachefs/btree_io.c @@ -735,6 +735,15 @@ static int validate_bset(struct bch_fs *c, struct btree *b, bch2_bpos_swab(&b->data->max_key); } + if (b->key.k.type == KEY_TYPE_btree_ptr_v2) { + struct bch_btree_ptr_v2 *bp = + &bkey_i_to_btree_ptr_v2(&b->key)->v; + + btree_err_on(bkey_cmp(b->data->min_key, bp->min_key), + BTREE_ERR_MUST_RETRY, c, b, NULL, + "incorrect min_key"); + } + btree_err_on(bkey_cmp(b->data->max_key, b->key.k.p), BTREE_ERR_MUST_RETRY, c, b, i, "incorrect max key"); @@ -784,7 +793,7 @@ static int validate_bset(struct bch_fs *c, struct btree *b, for (k = i->start; k != vstruct_last(i);) { - struct bkey_s_c u; + struct bkey_s u; struct bkey tmp; const char *invalid; @@ -805,21 +814,24 @@ static int validate_bset(struct bch_fs *c, struct btree *b, } if (BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN) - bch2_bkey_swab(&b->format, k); + bch2_bkey_swab_key(&b->format, k); if (!write && version < bcachefs_metadata_version_bkey_renumber) bch2_bkey_renumber(btree_node_type(b), k, write); - u = bkey_disassemble(b, k, &tmp); + u = __bkey_disassemble(b, k, &tmp); - invalid = __bch2_bkey_invalid(c, u, btree_node_type(b)) ?: - bch2_bkey_in_btree_node(b, u) ?: - (write ? bch2_bkey_val_invalid(c, u) : NULL); + if (BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN) + bch2_bkey_swab_val(u); + + invalid = __bch2_bkey_invalid(c, u.s_c, btree_node_type(b)) ?: + bch2_bkey_in_btree_node(b, u.s_c) ?: + (write ? bch2_bkey_val_invalid(c, u.s_c) : NULL); if (invalid) { char buf[160]; - bch2_bkey_val_to_text(&PBUF(buf), c, u); + bch2_bkey_val_to_text(&PBUF(buf), c, u.s_c); btree_err(BTREE_ERR_FIXABLE, c, b, i, "invalid bkey:\n%s\n%s", invalid, buf); @@ -895,6 +907,15 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry BTREE_ERR_MUST_RETRY, c, b, NULL, "bad btree header"); + if (b->key.k.type == KEY_TYPE_btree_ptr_v2) { + struct bch_btree_ptr_v2 *bp = + &bkey_i_to_btree_ptr_v2(&b->key)->v; + + btree_err_on(b->data->keys.seq != bp->seq, + BTREE_ERR_MUST_RETRY, c, b, NULL, + "got wrong btree node"); + } + while (b->written < c->opts.btree_node_size) { unsigned sectors, whiteout_u64s = 0; struct nonce nonce; @@ -1002,15 +1023,15 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry i = &b->data->keys; for (k = i->start; k != vstruct_last(i);) { struct bkey tmp; - struct bkey_s_c u = bkey_disassemble(b, k, &tmp); - const char *invalid = bch2_bkey_val_invalid(c, u); + struct bkey_s u = __bkey_disassemble(b, k, &tmp); + const char *invalid = bch2_bkey_val_invalid(c, u.s_c); if (invalid || (inject_invalid_keys(c) && !bversion_cmp(u.k->version, MAX_VERSION))) { char buf[160]; - bch2_bkey_val_to_text(&PBUF(buf), c, u); + bch2_bkey_val_to_text(&PBUF(buf), c, u.s_c); btree_err(BTREE_ERR_FIXABLE, c, b, i, "invalid bkey %s: %s", buf, invalid); @@ -1023,6 +1044,12 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry continue; } + if (u.k->type == KEY_TYPE_btree_ptr_v2) { + struct bkey_s_btree_ptr_v2 bp = bkey_s_to_btree_ptr_v2(u); + + bp.v->mem_ptr = 0; + } + k = bkey_next_skip_noops(k, vstruct_last(i)); } @@ -1252,8 +1279,6 @@ static void bch2_btree_node_write_error(struct bch_fs *c, { struct btree *b = wbio->wbio.bio.bi_private; __BKEY_PADDED(k, BKEY_BTREE_PTR_VAL_U64s_MAX) tmp; - struct bkey_i_btree_ptr *new_key; - struct bkey_s_btree_ptr bp; struct bch_extent_ptr *ptr; struct btree_trans trans; struct btree_iter *iter; @@ -1279,16 +1304,13 @@ retry: bkey_copy(&tmp.k, &b->key); - new_key = bkey_i_to_btree_ptr(&tmp.k); - bp = btree_ptr_i_to_s(new_key); - bch2_bkey_drop_ptrs(bkey_i_to_s(&tmp.k), ptr, bch2_dev_list_has_dev(wbio->wbio.failed, ptr->dev)); - if (!bch2_bkey_nr_ptrs(bp.s_c)) + if (!bch2_bkey_nr_ptrs(bkey_i_to_s_c(&tmp.k))) goto err; - ret = bch2_btree_node_update_key(c, iter, b, new_key); + ret = bch2_btree_node_update_key(c, iter, b, &tmp.k); if (ret == -EINTR) goto retry; if (ret) |