aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-12-20 17:01:18 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-12-20 17:01:18 -0500
commitcb85f123cd2393581bcffad335bfc6bcdd58569c (patch)
tree7b0de48b2a13ca96251c02245ab906f7efa3ac18 /fs/btrfs/super.c
parentb79d2ff98caee60c07a7598aba3b26acd1655a99 (diff)
parentcaca6a03d365883564885f2c1da3e88dcf65d139 (diff)
Merge commit 'v3.2-rc3' into stable/for-linus-3.3
* commit 'v3.2-rc3': (412 commits) Linux 3.2-rc3 virtio-pci: make reset operation safer virtio-mmio: Correct the name of the guest features selector virtio: add HAS_IOMEM dependency to MMIO platform bus driver eCryptfs: Extend array bounds for all filename chars eCryptfs: Flush file in vma close eCryptfs: Prevent file create race condition regulator: TPS65910: Fix VDD1/2 voltage selector count i2c: Make i2cdev_notifier_call static i2c: Delete ANY_I2C_BUS i2c: Fix device name for 10-bit slave address i2c-algo-bit: Generate correct i2c address sequence for 10-bit target drm: integer overflow in drm_mode_dirtyfb_ioctl() Revert "of/irq: of_irq_find_parent: check for parent equal to child" drivers/gpu/vga/vgaarb.c: add missing kfree drm/radeon/kms/atom: unify i2c gpio table handling drm/radeon/kms: fix up gpio i2c mask bits for r4xx for real ttm: Don't return the bo reserved on error path mount_subtree() pointless use-after-free iio: fix a leak due to improper use of anon_inode_getfd() ...
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c38
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)
825static struct dentry *mount_subvol(const char *subvol_name, int flags, 825static 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