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

Commit 3c04ce01 authored by Miao Xie's avatar Miao Xie Committed by Chris Mason
Browse files

Btrfs: get write access when setting the default subvolume



When wen want to set the default subvolume, we must get write access, or
we will change the R/O file system.

Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
parent 8cd2807f
Loading
Loading
Loading
Loading
+28 −12
Original line number Original line Diff line number Diff line
@@ -2843,12 +2843,19 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
	struct btrfs_disk_key disk_key;
	struct btrfs_disk_key disk_key;
	u64 objectid = 0;
	u64 objectid = 0;
	u64 dir_id;
	u64 dir_id;
	int ret;


	if (!capable(CAP_SYS_ADMIN))
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
		return -EPERM;


	if (copy_from_user(&objectid, argp, sizeof(objectid)))
	ret = mnt_want_write_file(file);
		return -EFAULT;
	if (ret)
		return ret;

	if (copy_from_user(&objectid, argp, sizeof(objectid))) {
		ret = -EFAULT;
		goto out;
	}


	if (!objectid)
	if (!objectid)
		objectid = root->root_key.objectid;
		objectid = root->root_key.objectid;
@@ -2858,21 +2865,28 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
	location.offset = (u64)-1;
	location.offset = (u64)-1;


	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
	if (IS_ERR(new_root))
	if (IS_ERR(new_root)) {
		return PTR_ERR(new_root);
		ret = PTR_ERR(new_root);
		goto out;
	}


	if (btrfs_root_refs(&new_root->root_item) == 0)
	if (btrfs_root_refs(&new_root->root_item) == 0) {
		return -ENOENT;
		ret = -ENOENT;
		goto out;
	}


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


	trans = btrfs_start_transaction(root, 1);
	trans = btrfs_start_transaction(root, 1);
	if (IS_ERR(trans)) {
	if (IS_ERR(trans)) {
		btrfs_free_path(path);
		btrfs_free_path(path);
		return PTR_ERR(trans);
		ret = PTR_ERR(trans);
		goto out;
	}
	}


	dir_id = btrfs_super_root_dir(root->fs_info->super_copy);
	dir_id = btrfs_super_root_dir(root->fs_info->super_copy);
@@ -2883,7 +2897,8 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
		btrfs_end_transaction(trans, root);
		btrfs_end_transaction(trans, root);
		printk(KERN_ERR "Umm, you don't have the default dir item, "
		printk(KERN_ERR "Umm, you don't have the default dir item, "
		       "this isn't going to work\n");
		       "this isn't going to work\n");
		return -ENOENT;
		ret = -ENOENT;
		goto out;
	}
	}


	btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
	btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
@@ -2893,8 +2908,9 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)


	btrfs_set_fs_incompat(root->fs_info, DEFAULT_SUBVOL);
	btrfs_set_fs_incompat(root->fs_info, DEFAULT_SUBVOL);
	btrfs_end_transaction(trans, root);
	btrfs_end_transaction(trans, root);

out:
	return 0;
	mnt_drop_write_file(file);
	return ret;
}
}


void btrfs_get_block_group_info(struct list_head *groups_list,
void btrfs_get_block_group_info(struct list_head *groups_list,