diff options
| author | Miklos Szeredi <mszeredi@suse.cz> | 2014-10-23 18:14:36 -0400 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-10-23 18:14:36 -0400 |
| commit | c771d683a62e5d36bc46036f5c07f4f5bb7dda61 (patch) | |
| tree | bd1909f5b62a62d4cc2d88ea659a5d222d81f66f | |
| parent | bd5d08569cc379f8366663a61558a9ce17c2e460 (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>
| -rw-r--r-- | fs/namespace.c | 27 | ||||
| -rw-r--r-- | include/linux/mount.h | 3 |
2 files changed, 30 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index fbba8b17330d..5b66b2b3624d 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -1686,6 +1686,33 @@ void drop_collected_mounts(struct vfsmount *mnt) | |||
| 1686 | namespace_unlock(); | 1686 | namespace_unlock(); |
| 1687 | } | 1687 | } |
| 1688 | 1688 | ||
| 1689 | /** | ||
| 1690 | * clone_private_mount - create a private clone of a path | ||
| 1691 | * | ||
| 1692 | * This creates a new vfsmount, which will be the clone of @path. The new will | ||
| 1693 | * not be attached anywhere in the namespace and will be private (i.e. changes | ||
| 1694 | * to the originating mount won't be propagated into this). | ||
| 1695 | * | ||
| 1696 | * Release with mntput(). | ||
| 1697 | */ | ||
| 1698 | struct vfsmount *clone_private_mount(struct path *path) | ||
| 1699 | { | ||
| 1700 | struct mount *old_mnt = real_mount(path->mnt); | ||
| 1701 | struct mount *new_mnt; | ||
| 1702 | |||
| 1703 | if (IS_MNT_UNBINDABLE(old_mnt)) | ||
| 1704 | return ERR_PTR(-EINVAL); | ||
| 1705 | |||
| 1706 | down_read(&namespace_sem); | ||
| 1707 | new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); | ||
| 1708 | up_read(&namespace_sem); | ||
| 1709 | if (IS_ERR(new_mnt)) | ||
| 1710 | return ERR_CAST(new_mnt); | ||
| 1711 | |||
| 1712 | return &new_mnt->mnt; | ||
| 1713 | } | ||
| 1714 | EXPORT_SYMBOL_GPL(clone_private_mount); | ||
| 1715 | |||
| 1689 | int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, | 1716 | int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, |
| 1690 | struct vfsmount *root) | 1717 | struct vfsmount *root) |
| 1691 | { | 1718 | { |
diff --git a/include/linux/mount.h b/include/linux/mount.h index 9262e4bf0cc3..c2c561dc0114 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
| @@ -81,6 +81,9 @@ extern struct vfsmount *mntget(struct vfsmount *mnt); | |||
| 81 | extern struct vfsmount *mnt_clone_internal(struct path *path); | 81 | extern struct vfsmount *mnt_clone_internal(struct path *path); |
| 82 | extern int __mnt_is_readonly(struct vfsmount *mnt); | 82 | extern int __mnt_is_readonly(struct vfsmount *mnt); |
| 83 | 83 | ||
| 84 | struct path; | ||
| 85 | extern struct vfsmount *clone_private_mount(struct path *path); | ||
| 86 | |||
| 84 | struct file_system_type; | 87 | struct file_system_type; |
| 85 | extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, | 88 | extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, |
| 86 | int flags, const char *name, | 89 | int flags, const char *name, |
