mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 21:33:52 +00:00
bcachefs: Add repair code for out of order keys in a btree node.
This just drops the offending key - in the bug report where this was seen, it was clearly a single bit memory error, and fsck will fix the missing key. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
a84b6c50f1
commit
5f65d74d79
1 changed files with 14 additions and 22 deletions
|
@ -578,6 +578,10 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
|
|||
mutex_unlock(&c->sb_lock);
|
||||
}
|
||||
|
||||
btree_err_on(BSET_SEPARATE_WHITEOUTS(i),
|
||||
BTREE_ERR_FATAL, c, ca, b, i,
|
||||
"BSET_SEPARATE_WHITEOUTS no longer supported");
|
||||
|
||||
if (btree_err_on(b->written + sectors > c->opts.btree_node_size,
|
||||
BTREE_ERR_FIXABLE, c, ca, b, i,
|
||||
"bset past end of btree node")) {
|
||||
|
@ -660,14 +664,8 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
|
|||
{
|
||||
unsigned version = le16_to_cpu(i->version);
|
||||
struct bkey_packed *k, *prev = NULL;
|
||||
bool seen_non_whiteout = false;
|
||||
int ret = 0;
|
||||
|
||||
if (!BSET_SEPARATE_WHITEOUTS(i)) {
|
||||
seen_non_whiteout = true;
|
||||
*whiteout_u64s = 0;
|
||||
}
|
||||
|
||||
for (k = i->start;
|
||||
k != vstruct_last(i);) {
|
||||
struct bkey_s u;
|
||||
|
@ -719,18 +717,7 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
|
|||
BSET_BIG_ENDIAN(i), write,
|
||||
&b->format, k);
|
||||
|
||||
/*
|
||||
* with the separate whiteouts thing (used for extents), the
|
||||
* second set of keys actually can have whiteouts too, so we
|
||||
* can't solely go off bkey_deleted()...
|
||||
*/
|
||||
|
||||
if (!seen_non_whiteout &&
|
||||
(!bkey_deleted(k) ||
|
||||
(prev && bkey_iter_cmp(b, prev, k) > 0))) {
|
||||
*whiteout_u64s = k->_data - i->_data;
|
||||
seen_non_whiteout = true;
|
||||
} else if (prev && bkey_iter_cmp(b, prev, k) > 0) {
|
||||
if (prev && bkey_iter_cmp(b, prev, k) > 0) {
|
||||
char buf1[80];
|
||||
char buf2[80];
|
||||
struct bkey up = bkey_unpack_key(b, prev);
|
||||
|
@ -739,10 +726,15 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
|
|||
bch2_bkey_to_text(&PBUF(buf2), u.k);
|
||||
|
||||
bch2_dump_bset(c, b, i, 0);
|
||||
btree_err(BTREE_ERR_FATAL, c, NULL, b, i,
|
||||
"keys out of order: %s > %s",
|
||||
buf1, buf2);
|
||||
/* XXX: repair this */
|
||||
|
||||
if (btree_err(BTREE_ERR_FIXABLE, c, NULL, b, i,
|
||||
"keys out of order: %s > %s",
|
||||
buf1, buf2)) {
|
||||
i->u64s = cpu_to_le16(le16_to_cpu(i->u64s) - k->u64s);
|
||||
memmove_u64s_down(k, bkey_next(k),
|
||||
(u64 *) vstruct_end(i) - (u64 *) k);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
prev = k;
|
||||
|
|
Loading…
Reference in a new issue