aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-05-15 08:31:02 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-05-21 20:14:59 -0400
commit123d2d09ff599ec11a01687f472c7bdc3b3b6f12 (patch)
tree5ba37f6a9cb571028631a8618f86c03e5bd31e72
parentbcachefs: Early return to avoid unnecessary lock (diff)
downloadwireguard-linux-123d2d09ff599ec11a01687f472c7bdc3b3b6f12.tar.xz
wireguard-linux-123d2d09ff599ec11a01687f472c7bdc3b3b6f12.zip
bcachefs: bch2_inode_find_snapshot_root()
Factor out a small common helper. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/fsck.c28
-rw-r--r--fs/bcachefs/inode.c24
-rw-r--r--fs/bcachefs/inode.h3
-rw-r--r--fs/bcachefs/str_hash.c30
4 files changed, 34 insertions, 51 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index 4258c91e6df3..e7cac5a69154 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -1115,32 +1115,6 @@ fsck_err:
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;
}
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index 96d4ab0148bf..a17a952ea161 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -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)
diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h
index 5cfba9e98966..bb81b7c269bb 100644
--- a/fs/bcachefs/inode.h
+++ b/fs/bcachefs/inode.h
@@ -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)
diff --git a/fs/bcachefs/str_hash.c b/fs/bcachefs/str_hash.c
index 55a3a116b5a8..2d6379473ad4 100644
--- a/fs/bcachefs/str_hash.c
+++ b/fs/bcachefs/str_hash.c
@@ -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;
}