mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
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:
parent
4a67b94bd8
commit
123d2d09ff
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user