Commit 951dd86e authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Fix iterator leak in check_subvol()



A couple small error handling fixes

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 2a1df873
Loading
Loading
Loading
Loading
+26 −28
Original line number Diff line number Diff line
@@ -92,35 +92,33 @@ 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;
	}

				    &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_iter.k.p.snapshot,
				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)) {
		u32 snapshot_root = bch2_snapshot_root(c, le32_to_cpu(subvol.v->snapshot));
@@ -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);
		}