diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-11-16 21:43:59 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-11-16 22:00:34 -0500 |
commit | ea441d1104cf1efb471fa81bc91e9fd1e6ae29fd (patch) | |
tree | 32b7c4f7c78af47936a604e3f4e13e8e61f834a0 /fs/nfs | |
parent | c13344958780b4046305ee6235d686c846535529 (diff) |
new helper: mount_subtree()
takes vfsmount and relative path, does lookup within that vfsmount
(possibly triggering automounts) and returns the result as root
of subtree suitable for return by ->mount() (i.e. a reference to
dentry and an active reference to its superblock grabbed, superblock
locked exclusive).
btrfs and nfs switched to it instead of open-coding the sucker.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/super.c | 30 |
1 files changed, 6 insertions, 24 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 46d69f38fd55..134777406ee3 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2787,35 +2787,17 @@ static void nfs_referral_loop_unprotect(void) | |||
2787 | static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt, | 2787 | static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt, |
2788 | const char *export_path) | 2788 | const char *export_path) |
2789 | { | 2789 | { |
2790 | struct mnt_namespace *ns_private; | ||
2791 | struct super_block *s; | ||
2792 | struct dentry *dentry; | 2790 | struct dentry *dentry; |
2793 | struct path path; | 2791 | int ret = nfs_referral_loop_protect(); |
2794 | int ret; | ||
2795 | 2792 | ||
2796 | ns_private = create_mnt_ns(root_mnt); | 2793 | if (ret) { |
2797 | if (IS_ERR(ns_private)) | 2794 | mntput(root_mnt); |
2798 | return ERR_CAST(ns_private); | ||
2799 | |||
2800 | ret = nfs_referral_loop_protect(); | ||
2801 | if (ret == 0) { | ||
2802 | ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, | ||
2803 | export_path, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, | ||
2804 | &path); | ||
2805 | nfs_referral_loop_unprotect(); | ||
2806 | } | ||
2807 | |||
2808 | put_mnt_ns(ns_private); | ||
2809 | |||
2810 | if (ret != 0) | ||
2811 | return ERR_PTR(ret); | 2795 | return ERR_PTR(ret); |
2796 | } | ||
2812 | 2797 | ||
2813 | s = path.mnt->mnt_sb; | 2798 | dentry = mount_subtree(root_mnt, export_path); |
2814 | atomic_inc(&s->s_active); | 2799 | nfs_referral_loop_unprotect(); |
2815 | dentry = dget(path.dentry); | ||
2816 | 2800 | ||
2817 | path_put(&path); | ||
2818 | down_write(&s->s_umount); | ||
2819 | return dentry; | 2801 | return dentry; |
2820 | } | 2802 | } |
2821 | 2803 | ||