bcachefs: Fix lookup_first_inode() when inode_generations are present
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 26 May 2024 17:24:31 +0000 (13:24 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 28 May 2024 15:29:26 +0000 (11:29 -0400)
This function is used for finding the hash seed (which is the same in
all versions of an inode in different snapshots): ff an inode has been
deleted in a child snapshot we need to iterate until we find a live
version.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fsck.c

index c8f57465131c54becd0cb745d7ce2b54b1e87cd1..4cd28db9bad8deded3a314952905e6bd97989286 100644 (file)
@@ -77,21 +77,17 @@ static int lookup_first_inode(struct btree_trans *trans, u64 inode_nr,
        struct bkey_s_c k;
        int ret;
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes,
-                            POS(0, inode_nr),
-                            BTREE_ITER_all_snapshots);
-       k = bch2_btree_iter_peek(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
-
-       if (!k.k || !bkey_eq(k.k->p, POS(0, inode_nr))) {
-               ret = -BCH_ERR_ENOENT_inode;
-               goto err;
+       for_each_btree_key_norestart(trans, iter, BTREE_ID_inodes, POS(0, inode_nr),
+                                    BTREE_ITER_all_snapshots, k, ret) {
+               if (k.k->p.offset != inode_nr)
+                       break;
+               if (!bkey_is_inode(k.k))
+                       continue;
+               ret = bch2_inode_unpack(k, inode);
+               goto found;
        }
-
-       ret = bch2_inode_unpack(k, inode);
-err:
+       ret = -BCH_ERR_ENOENT_inode;
+found:
        bch_err_msg(trans->c, ret, "fetching inode %llu", inode_nr);
        bch2_trans_iter_exit(trans, &iter);
        return ret;