mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-08 14:13:53 +00:00
bcachefs: Fix bch2_check_discard_freespace_key()
We weren't correctly checking the freespace btree - it's an extents btree, which means we need to iterate over each bucket in a freespace extent. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
25aa8c2167
commit
e96f5a61cb
@ -788,10 +788,12 @@ static int bch2_bucket_do_index(struct btree_trans *trans,
|
||||
if (ca->mi.freespace_initialized &&
|
||||
test_bit(BCH_FS_CHECK_ALLOC_DONE, &c->flags) &&
|
||||
bch2_trans_inconsistent_on(old.k->type != old_type, trans,
|
||||
"incorrect key when %s %s btree (got %s should be %s)\n"
|
||||
"incorrect key when %s %s:%llu:%llu:0 (got %s should be %s)\n"
|
||||
" for %s",
|
||||
set ? "setting" : "clearing",
|
||||
bch2_btree_ids[btree],
|
||||
iter.pos.inode,
|
||||
iter.pos.offset,
|
||||
bch2_bkey_types[old.k->type],
|
||||
bch2_bkey_types[old_type],
|
||||
(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
|
||||
@ -1278,8 +1280,8 @@ static int bch2_check_alloc_hole_bucket_gens(struct btree_trans *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_check_discard_freespace_key(struct btree_trans *trans,
|
||||
struct btree_iter *iter)
|
||||
static int __bch2_check_discard_freespace_key(struct btree_trans *trans,
|
||||
struct btree_iter *iter)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_iter alloc_iter;
|
||||
@ -1313,23 +1315,46 @@ static int bch2_check_discard_freespace_key(struct btree_trans *trans,
|
||||
if (fsck_err_on(a->data_type != state ||
|
||||
(state == BCH_DATA_free &&
|
||||
genbits != alloc_freespace_genbits(*a)), c,
|
||||
"%s\n incorrectly set in %s index (free %u, genbits %llu should be %llu)",
|
||||
"%s\n incorrectly set at %s:%llu:%llu:0 (free %u, genbits %llu should be %llu)",
|
||||
(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf),
|
||||
bch2_btree_ids[iter->btree_id],
|
||||
iter->pos.inode,
|
||||
iter->pos.offset,
|
||||
a->data_type == state,
|
||||
genbits >> 56, alloc_freespace_genbits(*a) >> 56))
|
||||
goto delete;
|
||||
out:
|
||||
fsck_err:
|
||||
set_btree_iter_dontneed(&alloc_iter);
|
||||
bch2_trans_iter_exit(trans, &alloc_iter);
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
delete:
|
||||
ret = bch2_btree_delete_extent_at(trans, iter,
|
||||
iter->btree_id == BTREE_ID_freespace ? 1 : 0, 0);
|
||||
ret = bch2_btree_delete_extent_at(trans, iter,
|
||||
iter->btree_id == BTREE_ID_freespace ? 1 : 0, 0) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int bch2_check_discard_freespace_key(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
struct bpos end)
|
||||
{
|
||||
if (!btree_node_type_is_extents(iter->btree_id)) {
|
||||
return __bch2_check_discard_freespace_key(trans, iter);
|
||||
} else {
|
||||
int ret = 0;
|
||||
|
||||
while (!bkey_eq(iter->pos, end) &&
|
||||
!(ret = btree_trans_too_many_iters(trans) ?:
|
||||
__bch2_check_discard_freespace_key(trans, iter)))
|
||||
bch2_btree_iter_set_pos(iter, bpos_nosnap_successor(iter->pos));
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We've already checked that generation numbers in the bucket_gens btree are
|
||||
* valid for buckets that exist; this just checks for keys for nonexistent
|
||||
@ -1481,16 +1506,14 @@ int bch2_check_alloc_info(struct bch_fs *c)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = for_each_btree_key_commit(&trans, iter,
|
||||
ret = for_each_btree_key2(&trans, iter,
|
||||
BTREE_ID_need_discard, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
|
||||
bch2_check_discard_freespace_key(&trans, &iter)) ?:
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
bch2_check_discard_freespace_key(&trans, &iter, k.k->p)) ?:
|
||||
for_each_btree_key2(&trans, iter,
|
||||
BTREE_ID_freespace, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
|
||||
bch2_check_discard_freespace_key(&trans, &iter)) ?:
|
||||
bch2_check_discard_freespace_key(&trans, &iter, k.k->p)) ?:
|
||||
for_each_btree_key_commit(&trans, iter,
|
||||
BTREE_ID_bucket_gens, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k,
|
||||
|
Loading…
Reference in New Issue
Block a user