diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 28 |
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 | } |
2491 | EXPORT_SYMBOL(create_mnt_ns); | 2491 | EXPORT_SYMBOL(create_mnt_ns); |
2492 | 2492 | ||
2493 | struct 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 | } | ||
2519 | EXPORT_SYMBOL(mount_subtree); | ||
2520 | |||
2493 | SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | 2521 | SYSCALL_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 | { |