bcachefs: bch2_inode_find_snapshot_root()

Factor out a small common helper.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2025-05-15 08:31:02 -04:00
parent 4a67b94bd8
commit 123d2d09ff
4 changed files with 34 additions and 51 deletions

View File

@ -1115,32 +1115,6 @@ static int check_inode_dirent_inode(struct btree_trans *trans,
return ret;
}
static int get_snapshot_root_inode(struct btree_trans *trans,
struct bch_inode_unpacked *root,
u64 inum)
{
struct btree_iter iter;
struct bkey_s_c k;
int ret = 0;
for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes,
SPOS(0, inum, U32_MAX),
BTREE_ITER_all_snapshots, k, ret) {
if (k.k->p.offset != inum)
break;
if (bkey_is_inode(k.k))
goto found_root;
}
if (ret)
goto err;
BUG();
found_root:
ret = bch2_inode_unpack(k, root);
err:
bch2_trans_iter_exit(trans, &iter);
return ret;
}
static int check_inode(struct btree_trans *trans,
struct btree_iter *iter,
struct bkey_s_c k,
@ -1171,7 +1145,7 @@ static int check_inode(struct btree_trans *trans,
goto err;
if (snapshot_root->bi_inum != u.bi_inum) {
ret = get_snapshot_root_inode(trans, snapshot_root, u.bi_inum);
ret = bch2_inode_find_snapshot_root(trans, u.bi_inum, snapshot_root);
if (ret)
goto err;
}

View File

@ -1131,6 +1131,30 @@ int bch2_inode_find_by_inum(struct bch_fs *c, subvol_inum inum,
return bch2_trans_do(c, bch2_inode_find_by_inum_trans(trans, inum, inode));
}
int bch2_inode_find_snapshot_root(struct btree_trans *trans, u64 inum,
struct bch_inode_unpacked *root)
{
struct btree_iter iter;
struct bkey_s_c k;
int ret = 0;
for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes,
SPOS(0, inum, U32_MAX),
BTREE_ITER_all_snapshots, k, ret) {
if (k.k->p.offset != inum)
break;
if (bkey_is_inode(k.k)) {
ret = bch2_inode_unpack(k, root);
goto out;
}
}
/* We're only called when we know we have an inode for @inum */
BUG_ON(!ret);
out:
bch2_trans_iter_exit(trans, &iter);
return ret;
}
int bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
{
if (bi->bi_flags & BCH_INODE_unlinked)

View File

@ -173,6 +173,9 @@ int bch2_inode_find_by_inum_trans(struct btree_trans *, subvol_inum,
int bch2_inode_find_by_inum(struct bch_fs *, subvol_inum,
struct bch_inode_unpacked *);
int bch2_inode_find_snapshot_root(struct btree_trans *trans, u64 inum,
struct bch_inode_unpacked *root);
#define inode_opt_get(_c, _inode, _name) \
((_inode)->bi_##_name ? (_inode)->bi_##_name - 1 : (_c)->opts._name)

View File

@ -146,34 +146,17 @@ static noinline int check_inode_hash_info_matches_root(struct btree_trans *trans
struct bch_hash_info *hash_info)
{
struct bch_fs *c = trans->c;
struct btree_iter iter;
struct bkey_s_c k;
int ret = 0;
for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes, SPOS(0, inum, U32_MAX),
BTREE_ITER_all_snapshots, k, ret) {
if (k.k->p.offset != inum)
break;
if (bkey_is_inode(k.k))
goto found;
}
/* This would've been caught by check_key_has_inode() */
bch_err(c, "%s(): inum %llu not found", __func__, inum);
ret = -BCH_ERR_fsck_repair_unimplemented;
goto err;
found:;
struct bch_inode_unpacked inode;
ret = bch2_inode_unpack(k, &inode);
struct bch_inode_unpacked snapshot_root;
int ret = bch2_inode_find_snapshot_root(trans, inum, &snapshot_root);
if (ret)
goto err;
return ret;
struct bch_hash_info hash_root = bch2_hash_info_init(c, &inode);
struct bch_hash_info hash_root = bch2_hash_info_init(c, &snapshot_root);
if (hash_info->type != hash_root.type ||
memcmp(&hash_info->siphash_key,
&hash_root.siphash_key,
sizeof(hash_root.siphash_key))) {
ret = repair_inode_hash_info(trans, &inode);
ret = repair_inode_hash_info(trans, &snapshot_root);
if (!ret) {
struct printbuf buf = PRINTBUF;
prt_printf(&buf, "inode %llu hash info mismatch with root, but mismatch not found\n", inum);
@ -190,8 +173,7 @@ found:;
ret = -BCH_ERR_fsck_repair_unimplemented;
}
}
err:
bch2_trans_iter_exit(trans, &iter);
return ret;
}