Skip to content

Commit c1c050f

Browse files
fdmananakdave
authored andcommitted
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: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent f8da41d commit c1c050f

1 file changed

Lines changed: 10 additions & 6 deletions

File tree

fs/btrfs/inode.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -617,19 +617,22 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode,
617617
struct btrfs_drop_extents_args drop_args = { 0 };
618618
struct btrfs_root *root = inode->root;
619619
struct btrfs_fs_info *fs_info = root->fs_info;
620-
struct btrfs_trans_handle *trans;
620+
struct btrfs_trans_handle *trans = NULL;
621621
u64 data_len = (compressed_size ?: size);
622622
int ret;
623623
struct btrfs_path *path;
624624

625625
path = btrfs_alloc_path();
626-
if (!path)
627-
return -ENOMEM;
626+
if (!path) {
627+
ret = -ENOMEM;
628+
goto out;
629+
}
628630

629631
trans = btrfs_join_transaction(root);
630632
if (IS_ERR(trans)) {
631-
btrfs_free_path(path);
632-
return PTR_ERR(trans);
633+
ret = PTR_ERR(trans);
634+
trans = NULL;
635+
goto out;
633636
}
634637
trans->block_rsv = &inode->block_rsv;
635638

@@ -680,7 +683,8 @@ static noinline int __cow_file_range_inline(struct btrfs_inode *inode,
680683
if (ret <= 0)
681684
btrfs_qgroup_free_data(inode, NULL, 0, fs_info->sectorsize, NULL);
682685
btrfs_free_path(path);
683-
btrfs_end_transaction(trans);
686+
if (trans)
687+
btrfs_end_transaction(trans);
684688
return ret;
685689
}
686690

0 commit comments

Comments
 (0)