Commit c1c050f9 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba
Browse files

btrfs: fix reservation leak in some error paths when inserting inline extent



If we fail to allocate a path or join a transaction, we return from
__cow_file_range_inline() without freeing the reserved qgroup data,
resulting in a leak. Fix this by ensuring we call btrfs_qgroup_free_data()
in such cases.

Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent f8da41de
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -617,19 +617,22 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode,
	struct btrfs_drop_extents_args drop_args = { 0 };
	struct btrfs_root *root = inode->root;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_trans_handle *trans;
	struct btrfs_trans_handle *trans = NULL;
	u64 data_len = (compressed_size ?: size);
	int ret;
	struct btrfs_path *path;

	path = btrfs_alloc_path();
	if (!path)
		return -ENOMEM;
	if (!path) {
		ret = -ENOMEM;
		goto out;
	}

	trans = btrfs_join_transaction(root);
	if (IS_ERR(trans)) {
		btrfs_free_path(path);
		return PTR_ERR(trans);
		ret = PTR_ERR(trans);
		trans = NULL;
		goto out;
	}
	trans->block_rsv = &inode->block_rsv;

@@ -680,6 +683,7 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode,
	if (ret <= 0)
		btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL);
	btrfs_free_path(path);
	if (trans)
		btrfs_end_transaction(trans);
	return ret;
}