aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-02-07 01:02:44 -0500
committerJosef Bacik <jbacik@fusionio.com>2013-02-20 12:59:41 -0500
commit8696c53304f16fde9368b9d5c89a5acb4a815d4c (patch)
tree856777de858d660b2d1c8c38facd5197407ba668 /fs/btrfs
parent2b8195bb5717729e4e94ab4ad73a543feaafb0a2 (diff)
Btrfs: fix memory leak of pending_snapshot->inherit
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>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ioctl.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index daea831f3d36..6d6314406e27 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -367,7 +367,7 @@ static noinline int create_subvol(struct btrfs_root *root,
367 struct dentry *dentry, 367 struct dentry *dentry,
368 char *name, int namelen, 368 char *name, int namelen,
369 u64 *async_transid, 369 u64 *async_transid,
370 struct btrfs_qgroup_inherit **inherit) 370 struct btrfs_qgroup_inherit *inherit)
371{ 371{
372 struct btrfs_trans_handle *trans; 372 struct btrfs_trans_handle *trans;
373 struct btrfs_key key; 373 struct btrfs_key key;
@@ -401,8 +401,7 @@ static noinline int create_subvol(struct btrfs_root *root,
401 if (IS_ERR(trans)) 401 if (IS_ERR(trans))
402 return PTR_ERR(trans); 402 return PTR_ERR(trans);
403 403
404 ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid, 404 ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid, inherit);
405 inherit ? *inherit : NULL);
406 if (ret) 405 if (ret)
407 goto fail; 406 goto fail;
408 407
@@ -533,7 +532,7 @@ fail:
533 532
534static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, 533static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
535 char *name, int namelen, u64 *async_transid, 534 char *name, int namelen, u64 *async_transid,
536 bool readonly, struct btrfs_qgroup_inherit **inherit) 535 bool readonly, struct btrfs_qgroup_inherit *inherit)
537{ 536{
538 struct inode *inode; 537 struct inode *inode;
539 struct btrfs_pending_snapshot *pending_snapshot; 538 struct btrfs_pending_snapshot *pending_snapshot;
@@ -552,10 +551,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
552 pending_snapshot->dentry = dentry; 551 pending_snapshot->dentry = dentry;
553 pending_snapshot->root = root; 552 pending_snapshot->root = root;
554 pending_snapshot->readonly = readonly; 553 pending_snapshot->readonly = readonly;
555 if (inherit) { 554 pending_snapshot->inherit = inherit;
556 pending_snapshot->inherit = *inherit;
557 *inherit = NULL; /* take responsibility to free it */
558 }
559 555
560 trans = btrfs_start_transaction(root->fs_info->extent_root, 6); 556 trans = btrfs_start_transaction(root->fs_info->extent_root, 6);
561 if (IS_ERR(trans)) { 557 if (IS_ERR(trans)) {
@@ -695,7 +691,7 @@ static noinline int btrfs_mksubvol(struct path *parent,
695 char *name, int namelen, 691 char *name, int namelen,
696 struct btrfs_root *snap_src, 692 struct btrfs_root *snap_src,
697 u64 *async_transid, bool readonly, 693 u64 *async_transid, bool readonly,
698 struct btrfs_qgroup_inherit **inherit) 694 struct btrfs_qgroup_inherit *inherit)
699{ 695{
700 struct inode *dir = parent->dentry->d_inode; 696 struct inode *dir = parent->dentry->d_inode;
701 struct dentry *dentry; 697 struct dentry *dentry;
@@ -1458,7 +1454,7 @@ out:
1458static noinline int btrfs_ioctl_snap_create_transid(struct file *file, 1454static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
1459 char *name, unsigned long fd, int subvol, 1455 char *name, unsigned long fd, int subvol,
1460 u64 *transid, bool readonly, 1456 u64 *transid, bool readonly,
1461 struct btrfs_qgroup_inherit **inherit) 1457 struct btrfs_qgroup_inherit *inherit)
1462{ 1458{
1463 int namelen; 1459 int namelen;
1464 int ret = 0; 1460 int ret = 0;
@@ -1567,7 +1563,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
1567 1563
1568 ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, 1564 ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
1569 vol_args->fd, subvol, ptr, 1565 vol_args->fd, subvol, ptr,
1570 readonly, &inherit); 1566 readonly, inherit);
1571 1567
1572 if (ret == 0 && ptr && 1568 if (ret == 0 && ptr &&
1573 copy_to_user(arg + 1569 copy_to_user(arg +