aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ioctl.c40
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 2911out:
2897 return 0; 2912 mnt_drop_write_file(file);
2913 return ret;
2898} 2914}
2899 2915
2900void btrfs_get_block_group_info(struct list_head *groups_list, 2916void btrfs_get_block_group_info(struct list_head *groups_list,