diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-10-24 00:14:36 +0200 |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2015-04-17 15:51:00 +0800 |
commit | 574c7ef9787b3b3d0513830e40323c34c2f53a39 (patch) | |
tree | 90cc1d09f46e087ea5c53ff55cf5049963a1dccf /fs/namespace.c | |
parent | 96bd0c53e4204392144978e5a40f4699570be22b (diff) |
vfs: introduce clone_private_mount()
Overlayfs needs a private clone of the mount, so create a function for
this and export to modules.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
(cherry picked from commit c771d683a62e5d36bc46036f5c07f4f5bb7dda61)
Signed-off-by: Alex Shi <alex.shi@linaro.org>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 039f3802d70e..c6533ce9cdee 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1586,6 +1586,33 @@ void drop_collected_mounts(struct vfsmount *mnt) namespace_unlock(); } +/** + * clone_private_mount - create a private clone of a path + * + * This creates a new vfsmount, which will be the clone of @path. The new will + * not be attached anywhere in the namespace and will be private (i.e. changes + * to the originating mount won't be propagated into this). + * + * Release with mntput(). + */ +struct vfsmount *clone_private_mount(struct path *path) +{ + struct mount *old_mnt = real_mount(path->mnt); + struct mount *new_mnt; + + if (IS_MNT_UNBINDABLE(old_mnt)) + return ERR_PTR(-EINVAL); + + down_read(&namespace_sem); + new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); + up_read(&namespace_sem); + if (IS_ERR(new_mnt)) + return ERR_CAST(new_mnt); + + return &new_mnt->mnt; +} +EXPORT_SYMBOL_GPL(clone_private_mount); + int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, struct vfsmount *root) { |