]> Git Repo - linux.git/commitdiff
btrfs: qgroup: fix quota root leak after quota disable failure
authorFilipe Manana <[email protected]>
Thu, 20 Jun 2024 11:32:00 +0000 (12:32 +0100)
committerDavid Sterba <[email protected]>
Mon, 24 Jun 2024 22:35:50 +0000 (00:35 +0200)
If during the quota disable we fail when cleaning the quota tree or when
deleting the root from the root tree, we jump to the 'out' label without
ever dropping the reference on the quota root, resulting in a leak of the
root since fs_info->quota_root is no longer pointing to the root (we have
set it to NULL just before those steps).

Fix this by always doing a btrfs_put_root() call under the 'out' label.
This is a problem that exists since qgroups were first added in 2012 by
commit bed92eae26cc ("Btrfs: qgroup implementation and prototypes"), but
back then we missed a kfree on the quota root and free_extent_buffer()
calls on its root and commit root nodes, since back then roots were not
yet reference counted.

Reviewed-by: Boris Burkov <[email protected]>
Reviewed-by: Qu Wenruo <[email protected]>
Signed-off-by: Filipe Manana <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
fs/btrfs/qgroup.c

index fc2a7ea263541896ab6577612c3740e736d5bcd0..bf0f81d59b6bca0490e7539ba93a2c65f5d64035 100644 (file)
@@ -1351,7 +1351,7 @@ static int flush_reservations(struct btrfs_fs_info *fs_info)
 
 int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 {
-       struct btrfs_root *quota_root;
+       struct btrfs_root *quota_root = NULL;
        struct btrfs_trans_handle *trans = NULL;
        int ret = 0;
 
@@ -1449,9 +1449,9 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        btrfs_free_tree_block(trans, btrfs_root_id(quota_root),
                              quota_root->node, 0, 1);
 
-       btrfs_put_root(quota_root);
 
 out:
+       btrfs_put_root(quota_root);
        mutex_unlock(&fs_info->qgroup_ioctl_lock);
        if (ret && trans)
                btrfs_end_transaction(trans);
This page took 0.061657 seconds and 4 git commands to generate.