]> www.infradead.org Git - nvme.git/commitdiff
bcachefs: Fix iterator leak in check_subvol()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 24 Sep 2024 02:05:14 +0000 (22:05 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 28 Sep 2024 01:46:34 +0000 (21:46 -0400)
A couple small error handling fixes

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

index dbe834cb349f4a8e6a1e72d24fafab3acf1186d4..6845dde1b3397a822d3fd2048e70df8df25d3c9f 100644 (file)
@@ -92,34 +92,32 @@ static int check_subvol(struct btree_trans *trans,
        }
 
        struct bch_inode_unpacked inode;
-       struct btree_iter inode_iter = {};
-       ret = bch2_inode_peek_nowarn(trans, &inode_iter, &inode,
+       ret = bch2_inode_find_by_inum_nowarn_trans(trans,
                                    (subvol_inum) { k.k->p.offset, le64_to_cpu(subvol.v->inode) },
-                                   0);
-       bch2_trans_iter_exit(trans, &inode_iter);
-
-       if (ret && !bch2_err_matches(ret, ENOENT))
-               return ret;
-
-       if (fsck_err_on(ret,
-                       trans, subvol_to_missing_root,
-                       "subvolume %llu points to missing subvolume root %llu:%u",
-                       k.k->p.offset, le64_to_cpu(subvol.v->inode),
-                       le32_to_cpu(subvol.v->snapshot))) {
-               ret = bch2_subvolume_delete(trans, iter->pos.offset);
-               bch_err_msg(c, ret, "deleting subvolume %llu", iter->pos.offset);
-               return ret ?: -BCH_ERR_transaction_restart_nested;
-       }
-
-       if (fsck_err_on(inode.bi_subvol != subvol.k->p.offset,
-                       trans, subvol_root_wrong_bi_subvol,
-                       "subvol root %llu:%u has wrong bi_subvol field: got %u, should be %llu",
-                       inode.bi_inum, inode_iter.k.p.snapshot,
-                       inode.bi_subvol, subvol.k->p.offset)) {
-               inode.bi_subvol = subvol.k->p.offset;
-               ret = __bch2_fsck_write_inode(trans, &inode, le32_to_cpu(subvol.v->snapshot));
-               if (ret)
+                                   &inode);
+       if (!ret) {
+               if (fsck_err_on(inode.bi_subvol != subvol.k->p.offset,
+                               trans, subvol_root_wrong_bi_subvol,
+                               "subvol root %llu:%u has wrong bi_subvol field: got %u, should be %llu",
+                               inode.bi_inum, inode.bi_snapshot,
+                               inode.bi_subvol, subvol.k->p.offset)) {
+                       inode.bi_subvol = subvol.k->p.offset;
+                       ret = __bch2_fsck_write_inode(trans, &inode, le32_to_cpu(subvol.v->snapshot));
+                       if (ret)
+                               goto err;
+               }
+       } else if (bch2_err_matches(ret, ENOENT)) {
+               if (fsck_err(trans, subvol_to_missing_root,
+                            "subvolume %llu points to missing subvolume root %llu:%u",
+                            k.k->p.offset, le64_to_cpu(subvol.v->inode),
+                            le32_to_cpu(subvol.v->snapshot))) {
+                       ret = bch2_subvolume_delete(trans, iter->pos.offset);
+                       bch_err_msg(c, ret, "deleting subvolume %llu", iter->pos.offset);
+                       ret = ret ?: -BCH_ERR_transaction_restart_nested;
                        goto err;
+               }
+       } else {
+               goto err;
        }
 
        if (!BCH_SUBVOLUME_SNAP(subvol.v)) {
@@ -137,7 +135,7 @@ static int check_subvol(struct btree_trans *trans,
                                "%s: snapshot tree %u not found", __func__, snapshot_tree);
 
                if (ret)
-                       return ret;
+                       goto err;
 
                if (fsck_err_on(le32_to_cpu(st.master_subvol) != subvol.k->p.offset,
                                trans, subvol_not_master_and_not_snapshot,
@@ -147,7 +145,7 @@ static int check_subvol(struct btree_trans *trans,
                                bch2_bkey_make_mut_typed(trans, iter, &subvol.s_c, 0, subvolume);
                        ret = PTR_ERR_OR_ZERO(s);
                        if (ret)
-                               return ret;
+                               goto err;
 
                        SET_BCH_SUBVOLUME_SNAP(&s->v, true);
                }