]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/fsck.c
Merge remote-tracking branch 'firestack/dev/nix/add-which'
[bcachefs-tools-debian] / libbcachefs / fsck.c
index 16a1eae9b374b953ddb9f7078214745325fc6ddb..826a3577ee9318c115b1a7751eddf6b1e528af04 100644 (file)
@@ -103,29 +103,14 @@ static int snapshot_lookup_subvol(struct btree_trans *trans, u32 snapshot,
 static int __subvol_lookup(struct btree_trans *trans, u32 subvol,
                           u32 *snapshot, u64 *inum)
 {
-       struct btree_iter iter;
-       struct bkey_s_c k;
+       struct bch_subvolume s;
        int ret;
 
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_subvolumes,
-                            POS(0, subvol), 0);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto err;
+       ret = bch2_subvolume_get(trans, subvol, false, 0, &s);
 
-       if (k.k->type != KEY_TYPE_subvolume) {
-               bch_err(trans->c, "subvolume %u not fonud", subvol);
-               ret = -ENOENT;
-               goto err;
-       }
-
-       *snapshot = le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot);
-       *inum = le64_to_cpu(bkey_s_c_to_subvolume(k).v->inode);
-err:
-       bch2_trans_iter_exit(trans, &iter);
+       *snapshot = le32_to_cpu(s.snapshot);
+       *inum = le64_to_cpu(s.inode);
        return ret;
-
 }
 
 static int subvol_lookup(struct btree_trans *trans, u32 subvol,
@@ -1065,6 +1050,8 @@ static int inode_backpointer_exists(struct btree_trans *trans,
 {
        struct btree_iter iter;
        struct bkey_s_c k;
+       u32 target_subvol, target_snapshot;
+       u64 target_inum;
        int ret;
 
        bch2_trans_iter_init(trans, &iter, BTREE_ID_dirents,
@@ -1076,7 +1063,15 @@ static int inode_backpointer_exists(struct btree_trans *trans,
        if (k.k->type != KEY_TYPE_dirent)
                goto out;
 
-       ret = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum) == inode->bi_inum;
+       ret = __bch2_dirent_read_target(trans, bkey_s_c_to_dirent(k),
+                                       &target_subvol,
+                                       &target_snapshot,
+                                       &target_inum,
+                                       true);
+       if (ret)
+               goto out;
+
+       ret = target_inum == inode->bi_inum;
 out:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
@@ -1769,7 +1764,17 @@ static int check_path(struct btree_trans *trans,
        snapshot = snapshot_t(c, snapshot)->equiv;
        p->nr = 0;
 
-       while (inode->bi_inum != BCACHEFS_ROOT_INO) {
+       while (!(inode->bi_inum == BCACHEFS_ROOT_INO &&
+                inode->bi_subvol == BCACHEFS_ROOT_SUBVOL)) {
+               if (inode->bi_parent_subvol) {
+                       u64 inum;
+
+                       ret = subvol_lookup(trans, inode->bi_parent_subvol,
+                                           &snapshot, &inum);
+                       if (ret)
+                               break;
+               }
+
                ret = lockrestart_do(trans,
                        inode_backpointer_exists(trans, inode, snapshot));
                if (ret < 0)
@@ -2094,11 +2099,7 @@ static int check_nlinks_update_hardlinks(struct bch_fs *c,
                                bch2_inode_nlink_get(&u), link->count)) {
                        bch2_inode_nlink_set(&u, link->count);
 
-                       ret = __bch2_trans_do(&trans, NULL, NULL,
-                                             BTREE_INSERT_NOFAIL|
-                                             BTREE_INSERT_LAZY_RW,
-                                             bch2_btree_iter_traverse(&iter) ?:
-                                       bch2_inode_write(&trans, &iter, &u));
+                       ret = write_inode(&trans, &u, k.k->p.snapshot);
                        if (ret)
                                bch_err(c, "error in fsck: error %i updating inode", ret);
                }