diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ioctl.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7b1f614f51f6..10bc65ed736c 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2843,12 +2843,19 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
2843 | struct btrfs_disk_key disk_key; | 2843 | struct btrfs_disk_key disk_key; |
2844 | u64 objectid = 0; | 2844 | u64 objectid = 0; |
2845 | u64 dir_id; | 2845 | u64 dir_id; |
2846 | int ret; | ||
2846 | 2847 | ||
2847 | if (!capable(CAP_SYS_ADMIN)) | 2848 | if (!capable(CAP_SYS_ADMIN)) |
2848 | return -EPERM; | 2849 | return -EPERM; |
2849 | 2850 | ||
2850 | if (copy_from_user(&objectid, argp, sizeof(objectid))) | 2851 | ret = mnt_want_write_file(file); |
2851 | return -EFAULT; | 2852 | if (ret) |
2853 | return ret; | ||
2854 | |||
2855 | if (copy_from_user(&objectid, argp, sizeof(objectid))) { | ||
2856 | ret = -EFAULT; | ||
2857 | goto out; | ||
2858 | } | ||
2852 | 2859 | ||
2853 | if (!objectid) | 2860 | if (!objectid) |
2854 | objectid = root->root_key.objectid; | 2861 | objectid = root->root_key.objectid; |
@@ -2858,21 +2865,28 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
2858 | location.offset = (u64)-1; | 2865 | location.offset = (u64)-1; |
2859 | 2866 | ||
2860 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | 2867 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); |
2861 | if (IS_ERR(new_root)) | 2868 | if (IS_ERR(new_root)) { |
2862 | return PTR_ERR(new_root); | 2869 | ret = PTR_ERR(new_root); |
2870 | goto out; | ||
2871 | } | ||
2863 | 2872 | ||
2864 | if (btrfs_root_refs(&new_root->root_item) == 0) | 2873 | if (btrfs_root_refs(&new_root->root_item) == 0) { |
2865 | return -ENOENT; | 2874 | ret = -ENOENT; |
2875 | goto out; | ||
2876 | } | ||
2866 | 2877 | ||
2867 | path = btrfs_alloc_path(); | 2878 | path = btrfs_alloc_path(); |
2868 | if (!path) | 2879 | if (!path) { |
2869 | return -ENOMEM; | 2880 | ret = -ENOMEM; |
2881 | goto out; | ||
2882 | } | ||
2870 | path->leave_spinning = 1; | 2883 | path->leave_spinning = 1; |
2871 | 2884 | ||
2872 | trans = btrfs_start_transaction(root, 1); | 2885 | trans = btrfs_start_transaction(root, 1); |
2873 | if (IS_ERR(trans)) { | 2886 | if (IS_ERR(trans)) { |
2874 | btrfs_free_path(path); | 2887 | btrfs_free_path(path); |
2875 | return PTR_ERR(trans); | 2888 | ret = PTR_ERR(trans); |
2889 | goto out; | ||
2876 | } | 2890 | } |
2877 | 2891 | ||
2878 | dir_id = btrfs_super_root_dir(root->fs_info->super_copy); | 2892 | 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) | |||
2883 | btrfs_end_transaction(trans, root); | 2897 | btrfs_end_transaction(trans, root); |
2884 | printk(KERN_ERR "Umm, you don't have the default dir item, " | 2898 | printk(KERN_ERR "Umm, you don't have the default dir item, " |
2885 | "this isn't going to work\n"); | 2899 | "this isn't going to work\n"); |
2886 | return -ENOENT; | 2900 | ret = -ENOENT; |
2901 | goto out; | ||
2887 | } | 2902 | } |
2888 | 2903 | ||
2889 | btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key); | 2904 | 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) | |||
2893 | 2908 | ||
2894 | btrfs_set_fs_incompat(root->fs_info, DEFAULT_SUBVOL); | 2909 | btrfs_set_fs_incompat(root->fs_info, DEFAULT_SUBVOL); |
2895 | btrfs_end_transaction(trans, root); | 2910 | btrfs_end_transaction(trans, root); |
2896 | 2911 | out: | |
2897 | return 0; | 2912 | mnt_drop_write_file(file); |
2913 | return ret; | ||
2898 | } | 2914 | } |
2899 | 2915 | ||
2900 | void btrfs_get_block_group_info(struct list_head *groups_list, | 2916 | void btrfs_get_block_group_info(struct list_head *groups_list, |