Skip to content

Commit

Permalink
Btrfs: get write access when setting the default subvolume
Browse files Browse the repository at this point in the history
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: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
  • Loading branch information
Miao Xie authored and Chris Mason committed Dec 17, 2012
1 parent 8cd2807 commit 3c04ce0
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2843,12 +2843,19 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
struct btrfs_disk_key disk_key;
u64 objectid = 0;
u64 dir_id;
int ret;

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

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

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

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

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

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

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

trans = btrfs_start_transaction(root, 1);
if (IS_ERR(trans)) {
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);
Expand All @@ -2883,7 +2897,8 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
btrfs_end_transaction(trans, root);
printk(KERN_ERR "Umm, you don't have the default dir item, "
"this isn't going to work\n");
return -ENOENT;
ret = -ENOENT;
goto out;
}

btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
Expand All @@ -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_end_transaction(trans, root);

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

void btrfs_get_block_group_info(struct list_head *groups_list,
Expand Down

0 comments on commit 3c04ce0

Please sign in to comment.