diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 38 |
1 files changed, 6 insertions, 32 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8bd9d6d0e07a..17ee7fc5e64e 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -825,13 +825,9 @@ static char *setup_root_args(char *args) | |||
825 | static struct dentry *mount_subvol(const char *subvol_name, int flags, | 825 | static struct dentry *mount_subvol(const char *subvol_name, int flags, |
826 | const char *device_name, char *data) | 826 | const char *device_name, char *data) |
827 | { | 827 | { |
828 | struct super_block *s; | ||
829 | struct dentry *root; | 828 | struct dentry *root; |
830 | struct vfsmount *mnt; | 829 | struct vfsmount *mnt; |
831 | struct mnt_namespace *ns_private; | ||
832 | char *newargs; | 830 | char *newargs; |
833 | struct path path; | ||
834 | int error; | ||
835 | 831 | ||
836 | newargs = setup_root_args(data); | 832 | newargs = setup_root_args(data); |
837 | if (!newargs) | 833 | if (!newargs) |
@@ -842,39 +838,17 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags, | |||
842 | if (IS_ERR(mnt)) | 838 | if (IS_ERR(mnt)) |
843 | return ERR_CAST(mnt); | 839 | return ERR_CAST(mnt); |
844 | 840 | ||
845 | ns_private = create_mnt_ns(mnt); | 841 | root = mount_subtree(mnt, subvol_name); |
846 | if (IS_ERR(ns_private)) { | ||
847 | mntput(mnt); | ||
848 | return ERR_CAST(ns_private); | ||
849 | } | ||
850 | 842 | ||
851 | /* | 843 | if (!IS_ERR(root) && !is_subvolume_inode(root->d_inode)) { |
852 | * This will trigger the automount of the subvol so we can just | 844 | struct super_block *s = root->d_sb; |
853 | * drop the mnt we have here and return the dentry that we | 845 | dput(root); |
854 | * found. | 846 | root = ERR_PTR(-EINVAL); |
855 | */ | 847 | deactivate_locked_super(s); |
856 | error = vfs_path_lookup(mnt->mnt_root, mnt, subvol_name, | ||
857 | LOOKUP_FOLLOW, &path); | ||
858 | put_mnt_ns(ns_private); | ||
859 | if (error) | ||
860 | return ERR_PTR(error); | ||
861 | |||
862 | if (!is_subvolume_inode(path.dentry->d_inode)) { | ||
863 | path_put(&path); | ||
864 | mntput(mnt); | ||
865 | error = -EINVAL; | ||
866 | printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n", | 848 | printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n", |
867 | subvol_name); | 849 | subvol_name); |
868 | return ERR_PTR(-EINVAL); | ||
869 | } | 850 | } |
870 | 851 | ||
871 | /* Get a ref to the sb and the dentry we found and return it */ | ||
872 | s = path.mnt->mnt_sb; | ||
873 | atomic_inc(&s->s_active); | ||
874 | root = dget(path.dentry); | ||
875 | path_put(&path); | ||
876 | down_write(&s->s_umount); | ||
877 | |||
878 | return root; | 852 | return root; |
879 | } | 853 | } |
880 | 854 | ||