Skip to content

Commit

Permalink
Btrfs: fix memory leak of pending_snapshot->inherit
Browse files Browse the repository at this point in the history
The argument "inherit" of btrfs_ioctl_snap_create_transid() was assigned
to NULL during we created the snapshots, so we didn't free it though we
called kfree() in the caller.

But since we are sure the snapshot creation is done after the function -
btrfs_ioctl_snap_create_transid() - completes, it is safe that we don't
assign the pointer "inherit" to NULL, and just free it in the caller of
btrfs_ioctl_snap_create_transid(). In this way, the code can become more
readable.

Reported-by: Alex Lyakas <alex.btrfs@zadarastorage.com>
Cc: Arne Jansen <sensille@gmx.net>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
  • Loading branch information
Miao Xie authored and Josef Bacik committed Feb 20, 2013
1 parent 2b8195b commit 8696c53
Showing 1 changed file with 7 additions and 11 deletions.
18 changes: 7 additions & 11 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static noinline int create_subvol(struct btrfs_root *root,
struct dentry *dentry,
char *name, int namelen,
u64 *async_transid,
struct btrfs_qgroup_inherit **inherit)
struct btrfs_qgroup_inherit *inherit)
{
struct btrfs_trans_handle *trans;
struct btrfs_key key;
Expand Down Expand Up @@ -401,8 +401,7 @@ static noinline int create_subvol(struct btrfs_root *root,
if (IS_ERR(trans))
return PTR_ERR(trans);

ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid,
inherit ? *inherit : NULL);
ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid, inherit);
if (ret)
goto fail;

Expand Down Expand Up @@ -533,7 +532,7 @@ static noinline int create_subvol(struct btrfs_root *root,

static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
char *name, int namelen, u64 *async_transid,
bool readonly, struct btrfs_qgroup_inherit **inherit)
bool readonly, struct btrfs_qgroup_inherit *inherit)
{
struct inode *inode;
struct btrfs_pending_snapshot *pending_snapshot;
Expand All @@ -552,10 +551,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
pending_snapshot->dentry = dentry;
pending_snapshot->root = root;
pending_snapshot->readonly = readonly;
if (inherit) {
pending_snapshot->inherit = *inherit;
*inherit = NULL; /* take responsibility to free it */
}
pending_snapshot->inherit = inherit;

trans = btrfs_start_transaction(root->fs_info->extent_root, 6);
if (IS_ERR(trans)) {
Expand Down Expand Up @@ -695,7 +691,7 @@ static noinline int btrfs_mksubvol(struct path *parent,
char *name, int namelen,
struct btrfs_root *snap_src,
u64 *async_transid, bool readonly,
struct btrfs_qgroup_inherit **inherit)
struct btrfs_qgroup_inherit *inherit)
{
struct inode *dir = parent->dentry->d_inode;
struct dentry *dentry;
Expand Down Expand Up @@ -1458,7 +1454,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
char *name, unsigned long fd, int subvol,
u64 *transid, bool readonly,
struct btrfs_qgroup_inherit **inherit)
struct btrfs_qgroup_inherit *inherit)
{
int namelen;
int ret = 0;
Expand Down Expand Up @@ -1567,7 +1563,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,

ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
vol_args->fd, subvol, ptr,
readonly, &inherit);
readonly, inherit);

if (ret == 0 && ptr &&
copy_to_user(arg +
Expand Down

0 comments on commit 8696c53

Please sign in to comment.