aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-12 11:19:20 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-12 11:19:20 -0500
commit68556ca1e03d6a35be3b315eba58df2f8176e3a0 (patch)
tree36a390d29a0d03a59a90c0f223b0d98a80f0f6c3 /fs/btrfs/super.c
parent0604ca48f1689ad06144b81f5c08f297b6edd831 (diff)
parent8ab30691826fc05efa47c4ffba19b80496bb3a2c (diff)
Merge branch 'mfd/wm8994' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc into for-3.3
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c87
1 files changed, 33 insertions, 54 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 57080dffdfc6..17ee7fc5e64e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -197,7 +197,7 @@ static match_table_t tokens = {
197 {Opt_subvolrootid, "subvolrootid=%d"}, 197 {Opt_subvolrootid, "subvolrootid=%d"},
198 {Opt_defrag, "autodefrag"}, 198 {Opt_defrag, "autodefrag"},
199 {Opt_inode_cache, "inode_cache"}, 199 {Opt_inode_cache, "inode_cache"},
200 {Opt_no_space_cache, "no_space_cache"}, 200 {Opt_no_space_cache, "nospace_cache"},
201 {Opt_recovery, "recovery"}, 201 {Opt_recovery, "recovery"},
202 {Opt_err, NULL}, 202 {Opt_err, NULL},
203}; 203};
@@ -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:
@@ -710,7 +711,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
710 if (btrfs_test_opt(root, SPACE_CACHE)) 711 if (btrfs_test_opt(root, SPACE_CACHE))
711 seq_puts(seq, ",space_cache"); 712 seq_puts(seq, ",space_cache");
712 else 713 else
713 seq_puts(seq, ",no_space_cache"); 714 seq_puts(seq, ",nospace_cache");
714 if (btrfs_test_opt(root, CLEAR_CACHE)) 715 if (btrfs_test_opt(root, CLEAR_CACHE))
715 seq_puts(seq, ",clear_cache"); 716 seq_puts(seq, ",clear_cache");
716 if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) 717 if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
@@ -824,13 +825,9 @@ static char *setup_root_args(char *args)
824static struct dentry *mount_subvol(const char *subvol_name, int flags, 825static struct dentry *mount_subvol(const char *subvol_name, int flags,
825 const char *device_name, char *data) 826 const char *device_name, char *data)
826{ 827{
827 struct super_block *s;
828 struct dentry *root; 828 struct dentry *root;
829 struct vfsmount *mnt; 829 struct vfsmount *mnt;
830 struct mnt_namespace *ns_private;
831 char *newargs; 830 char *newargs;
832 struct path path;
833 int error;
834 831
835 newargs = setup_root_args(data); 832 newargs = setup_root_args(data);
836 if (!newargs) 833 if (!newargs)
@@ -841,39 +838,17 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags,
841 if (IS_ERR(mnt)) 838 if (IS_ERR(mnt))
842 return ERR_CAST(mnt); 839 return ERR_CAST(mnt);
843 840
844 ns_private = create_mnt_ns(mnt); 841 root = mount_subtree(mnt, subvol_name);
845 if (IS_ERR(ns_private)) {
846 mntput(mnt);
847 return ERR_CAST(ns_private);
848 }
849
850 /*
851 * This will trigger the automount of the subvol so we can just
852 * drop the mnt we have here and return the dentry that we
853 * found.
854 */
855 error = vfs_path_lookup(mnt->mnt_root, mnt, subvol_name,
856 LOOKUP_FOLLOW, &path);
857 put_mnt_ns(ns_private);
858 if (error)
859 return ERR_PTR(error);
860 842
861 if (!is_subvolume_inode(path.dentry->d_inode)) { 843 if (!IS_ERR(root) && !is_subvolume_inode(root->d_inode)) {
862 path_put(&path); 844 struct super_block *s = root->d_sb;
863 mntput(mnt); 845 dput(root);
864 error = -EINVAL; 846 root = ERR_PTR(-EINVAL);
847 deactivate_locked_super(s);
865 printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n", 848 printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n",
866 subvol_name); 849 subvol_name);
867 return ERR_PTR(-EINVAL);
868 } 850 }
869 851
870 /* Get a ref to the sb and the dentry we found and return it */
871 s = path.mnt->mnt_sb;
872 atomic_inc(&s->s_active);
873 root = dget(path.dentry);
874 path_put(&path);
875 down_write(&s->s_umount);
876
877 return root; 852 return root;
878} 853}
879 854
@@ -890,7 +865,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
890 struct super_block *s; 865 struct super_block *s;
891 struct dentry *root; 866 struct dentry *root;
892 struct btrfs_fs_devices *fs_devices = NULL; 867 struct btrfs_fs_devices *fs_devices = NULL;
893 struct btrfs_root *tree_root = NULL;
894 struct btrfs_fs_info *fs_info = NULL; 868 struct btrfs_fs_info *fs_info = NULL;
895 fmode_t mode = FMODE_READ; 869 fmode_t mode = FMODE_READ;
896 char *subvol_name = NULL; 870 char *subvol_name = NULL;
@@ -904,8 +878,10 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
904 error = btrfs_parse_early_options(data, mode, fs_type, 878 error = btrfs_parse_early_options(data, mode, fs_type,
905 &subvol_name, &subvol_objectid, 879 &subvol_name, &subvol_objectid,
906 &subvol_rootid, &fs_devices); 880 &subvol_rootid, &fs_devices);
907 if (error) 881 if (error) {
882 kfree(subvol_name);
908 return ERR_PTR(error); 883 return ERR_PTR(error);
884 }
909 885
910 if (subvol_name) { 886 if (subvol_name) {
911 root = mount_subvol(subvol_name, flags, device_name, data); 887 root = mount_subvol(subvol_name, flags, device_name, data);
@@ -917,15 +893,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
917 if (error) 893 if (error)
918 return ERR_PTR(error); 894 return ERR_PTR(error);
919 895
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 /* 896 /*
930 * Setup a dummy root and fs_info for test/set super. This is because 897 * 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 898 * we don't actually fill this stuff out until open_ctree, but we need
@@ -933,24 +900,36 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
933 * then open_ctree will properly initialize everything later. 900 * then open_ctree will properly initialize everything later.
934 */ 901 */
935 fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); 902 fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
936 tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); 903 if (!fs_info)
937 if (!fs_info || !tree_root) { 904 return ERR_PTR(-ENOMEM);
905
906 fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
907 if (!fs_info->tree_root) {
938 error = -ENOMEM; 908 error = -ENOMEM;
939 goto error_close_devices; 909 goto error_fs_info;
940 } 910 }
941 fs_info->tree_root = tree_root; 911 fs_info->tree_root->fs_info = fs_info;
942 fs_info->fs_devices = fs_devices; 912 fs_info->fs_devices = fs_devices;
943 tree_root->fs_info = fs_info;
944 913
945 fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); 914 fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
946 fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); 915 fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
947 if (!fs_info->super_copy || !fs_info->super_for_commit) { 916 if (!fs_info->super_copy || !fs_info->super_for_commit) {
948 error = -ENOMEM; 917 error = -ENOMEM;
918 goto error_fs_info;
919 }
920
921 error = btrfs_open_devices(fs_devices, mode, fs_type);
922 if (error)
923 goto error_fs_info;
924
925 if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
926 error = -EACCES;
949 goto error_close_devices; 927 goto error_close_devices;
950 } 928 }
951 929
952 bdev = fs_devices->latest_bdev; 930 bdev = fs_devices->latest_bdev;
953 s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); 931 s = sget(fs_type, btrfs_test_super, btrfs_set_super,
932 fs_info->tree_root);
954 if (IS_ERR(s)) { 933 if (IS_ERR(s)) {
955 error = PTR_ERR(s); 934 error = PTR_ERR(s);
956 goto error_close_devices; 935 goto error_close_devices;
@@ -959,12 +938,12 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
959 if (s->s_root) { 938 if (s->s_root) {
960 if ((flags ^ s->s_flags) & MS_RDONLY) { 939 if ((flags ^ s->s_flags) & MS_RDONLY) {
961 deactivate_locked_super(s); 940 deactivate_locked_super(s);
962 return ERR_PTR(-EBUSY); 941 error = -EBUSY;
942 goto error_close_devices;
963 } 943 }
964 944
965 btrfs_close_devices(fs_devices); 945 btrfs_close_devices(fs_devices);
966 free_fs_info(fs_info); 946 free_fs_info(fs_info);
967 kfree(tree_root);
968 } else { 947 } else {
969 char b[BDEVNAME_SIZE]; 948 char b[BDEVNAME_SIZE];
970 949
@@ -991,8 +970,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
991 970
992error_close_devices: 971error_close_devices:
993 btrfs_close_devices(fs_devices); 972 btrfs_close_devices(fs_devices);
973error_fs_info:
994 free_fs_info(fs_info); 974 free_fs_info(fs_info);
995 kfree(tree_root);
996 return ERR_PTR(error); 975 return ERR_PTR(error);
997} 976}
998 977