aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index aea4b7689840..50ee30345b4f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2490,6 +2490,34 @@ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
2490} 2490}
2491EXPORT_SYMBOL(create_mnt_ns); 2491EXPORT_SYMBOL(create_mnt_ns);
2492 2492
2493struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
2494{
2495 struct mnt_namespace *ns;
2496 struct path path;
2497 int err;
2498
2499 ns = create_mnt_ns(mnt);
2500 if (IS_ERR(ns))
2501 return ERR_CAST(ns);
2502
2503 err = vfs_path_lookup(mnt->mnt_root, mnt,
2504 name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
2505
2506 put_mnt_ns(ns);
2507
2508 if (err)
2509 return ERR_PTR(err);
2510
2511 /* trade a vfsmount reference for active sb one */
2512 atomic_inc(&path.mnt->mnt_sb->s_active);
2513 mntput(path.mnt);
2514 /* lock the sucker */
2515 down_write(&path.mnt->mnt_sb->s_umount);
2516 /* ... and return the root of (sub)tree on it */
2517 return path.dentry;
2518}
2519EXPORT_SYMBOL(mount_subtree);
2520
2493SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, 2521SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2494 char __user *, type, unsigned long, flags, void __user *, data) 2522 char __user *, type, unsigned long, flags, void __user *, data)
2495{ 2523{