aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index dcd5aef6b614..629281c65ff5 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -448,6 +448,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
448 token = match_token(p, tokens, args); 448 token = match_token(p, tokens, args);
449 switch (token) { 449 switch (token) {
450 case Opt_subvol: 450 case Opt_subvol:
451 kfree(*subvol_name);
451 *subvol_name = match_strdup(&args[0]); 452 *subvol_name = match_strdup(&args[0]);
452 break; 453 break;
453 case Opt_subvolid: 454 case Opt_subvolid:
@@ -890,7 +891,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
890 struct super_block *s; 891 struct super_block *s;
891 struct dentry *root; 892 struct dentry *root;
892 struct btrfs_fs_devices *fs_devices = NULL; 893 struct btrfs_fs_devices *fs_devices = NULL;
893 struct btrfs_root *tree_root = NULL;
894 struct btrfs_fs_info *fs_info = NULL; 894 struct btrfs_fs_info *fs_info = NULL;
895 fmode_t mode = FMODE_READ; 895 fmode_t mode = FMODE_READ;
896 char *subvol_name = NULL; 896 char *subvol_name = NULL;
@@ -904,8 +904,10 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
904 error = btrfs_parse_early_options(data, mode, fs_type, 904 error = btrfs_parse_early_options(data, mode, fs_type,
905 &subvol_name, &subvol_objectid, 905 &subvol_name, &subvol_objectid,
906 &subvol_rootid, &fs_devices); 906 &subvol_rootid, &fs_devices);
907 if (error) 907 if (error) {
908 kfree(subvol_name);
908 return ERR_PTR(error); 909 return ERR_PTR(error);
910 }
909 911
910 if (subvol_name) { 912 if (subvol_name) {
911 root = mount_subvol(subvol_name, flags, device_name, data); 913 root = mount_subvol(subvol_name, flags, device_name, data);
@@ -917,15 +919,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
917 if (error) 919 if (error)
918 return ERR_PTR(error); 920 return ERR_PTR(error);
919 921
920 error = btrfs_open_devices(fs_devices, mode, fs_type);
921 if (error)
922 return ERR_PTR(error);
923
924 if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
925 error = -EACCES;
926 goto error_close_devices;
927 }
928
929 /* 922 /*
930 * Setup a dummy root and fs_info for test/set super. This is because 923 * Setup a dummy root and fs_info for test/set super. This is because
931 * we don't actually fill this stuff out until open_ctree, but we need 924 * we don't actually fill this stuff out until open_ctree, but we need
@@ -933,28 +926,36 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
933 * then open_ctree will properly initialize everything later. 926 * then open_ctree will properly initialize everything later.
934 */ 927 */
935 fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); 928 fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
936 if (!fs_info) { 929 if (!fs_info)
937 error = -ENOMEM; 930 return ERR_PTR(-ENOMEM);
938 goto error_close_devices; 931
939 } 932 fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
940 tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); 933 if (!fs_info->tree_root) {
941 if (!tree_root) {
942 error = -ENOMEM; 934 error = -ENOMEM;
943 goto error_close_devices; 935 goto error_fs_info;
944 } 936 }
945 fs_info->tree_root = tree_root; 937 fs_info->tree_root->fs_info = fs_info;
946 fs_info->fs_devices = fs_devices; 938 fs_info->fs_devices = fs_devices;
947 tree_root->fs_info = fs_info;
948 939
949 fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); 940 fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
950 fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); 941 fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
951 if (!fs_info->super_copy || !fs_info->super_for_commit) { 942 if (!fs_info->super_copy || !fs_info->super_for_commit) {
952 error = -ENOMEM; 943 error = -ENOMEM;
944 goto error_fs_info;
945 }
946
947 error = btrfs_open_devices(fs_devices, mode, fs_type);
948 if (error)
949 goto error_fs_info;
950
951 if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
952 error = -EACCES;
953 goto error_close_devices; 953 goto error_close_devices;
954 } 954 }
955 955
956 bdev = fs_devices->latest_bdev; 956 bdev = fs_devices->latest_bdev;
957 s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); 957 s = sget(fs_type, btrfs_test_super, btrfs_set_super,
958 fs_info->tree_root);
958 if (IS_ERR(s)) { 959 if (IS_ERR(s)) {
959 error = PTR_ERR(s); 960 error = PTR_ERR(s);
960 goto error_close_devices; 961 goto error_close_devices;
@@ -963,7 +964,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
963 if (s->s_root) { 964 if (s->s_root) {
964 if ((flags ^ s->s_flags) & MS_RDONLY) { 965 if ((flags ^ s->s_flags) & MS_RDONLY) {
965 deactivate_locked_super(s); 966 deactivate_locked_super(s);
966 return ERR_PTR(-EBUSY); 967 error = -EBUSY;
968 goto error_close_devices;
967 } 969 }
968 970
969 btrfs_close_devices(fs_devices); 971 btrfs_close_devices(fs_devices);
@@ -994,6 +996,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
994 996
995error_close_devices: 997error_close_devices:
996 btrfs_close_devices(fs_devices); 998 btrfs_close_devices(fs_devices);
999error_fs_info:
997 free_fs_info(fs_info); 1000 free_fs_info(fs_info);
998 return ERR_PTR(error); 1001 return ERR_PTR(error);
999} 1002}