Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ab86aed authored by Sage Weil's avatar Sage Weil Committed by Chris Mason
Browse files

Btrfs: fix error cases for ioctl transactions



Fix leak of vfsmount write reference and open_ioctl_trans reference on
ENOMEM.  Clean up the error paths while we're at it.

Signed-off-by: default avatarSage Weil <sage@newdream.net>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 3baf0bed
Loading
Loading
Loading
Loading
+22 −19
Original line number Diff line number Diff line
@@ -1232,15 +1232,15 @@ static long btrfs_ioctl_trans_start(struct file *file)
	struct inode *inode = fdentry(file)->d_inode;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_trans_handle *trans;
	int ret = 0;
	int ret;

	ret = -EPERM;
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
		goto out;

	if (file->private_data) {
	ret = -EINPROGRESS;
	if (file->private_data)
		goto out;
	}

	ret = mnt_want_write(file->f_path.mnt);
	if (ret)
@@ -1250,12 +1250,19 @@ static long btrfs_ioctl_trans_start(struct file *file)
	root->fs_info->open_ioctl_trans++;
	mutex_unlock(&root->fs_info->trans_mutex);

	ret = -ENOMEM;
	trans = btrfs_start_ioctl_transaction(root, 0);
	if (trans)
	if (!trans)
		goto out_drop;

	file->private_data = trans;
	else
		ret = -ENOMEM;
	/*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/
	return 0;

out_drop:
	mutex_lock(&root->fs_info->trans_mutex);
	root->fs_info->open_ioctl_trans--;
	mutex_unlock(&root->fs_info->trans_mutex);
	mnt_drop_write(file->f_path.mnt);
out:
	return ret;
}
@@ -1271,24 +1278,20 @@ long btrfs_ioctl_trans_end(struct file *file)
	struct inode *inode = fdentry(file)->d_inode;
	struct btrfs_root *root = BTRFS_I(inode)->root;
	struct btrfs_trans_handle *trans;
	int ret = 0;

	trans = file->private_data;
	if (!trans) {
		ret = -EINVAL;
		goto out;
	}
	btrfs_end_transaction(trans, root);
	if (!trans)
		return -EINVAL;
	file->private_data = NULL;

	btrfs_end_transaction(trans, root);

	mutex_lock(&root->fs_info->trans_mutex);
	root->fs_info->open_ioctl_trans--;
	mutex_unlock(&root->fs_info->trans_mutex);

	mnt_drop_write(file->f_path.mnt);

out:
	return ret;
	return 0;
}

long btrfs_ioctl(struct file *file, unsigned int