From: Christian Brauner <christian.brauner@xxxxxxxxxx> We're about to switch all filesystems that stack on top or otherwise use a struct path of another filesystem to use clone_private_mount() in the following commits. Most of these filesystems like ecryptfs and cachefiles don't need the MS_UNBDINDABLE check that overlayfs currently wants. So move the check out of clone_private_mount() and into overlayfs itself. Note that overlayfs can probably be switched to not rely on the MS_UNBDINDABLE check too but for now keep it. [1]: df820f8de4e4 ("ovl: make private mounts longterm") Cc: Amir Goldstein <amir73il@xxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Miklos Szeredi <mszeredi@xxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: linux-fsdevel@xxxxxxxxxxxxxxx Signed-off-by: Christian Brauner <christian.brauner@xxxxxxxxxx> --- fs/namespace.c | 3 --- fs/overlayfs/super.c | 13 +++++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 7ffefa8b3980..f6efe1272b9d 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1976,9 +1976,6 @@ struct vfsmount *clone_private_mount(const 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); - new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); if (IS_ERR(new_mnt)) return ERR_CAST(new_mnt); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index fdd72f1a9c5e..c942bb1073f6 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -15,6 +15,7 @@ #include <linux/seq_file.h> #include <linux/posix_acl_xattr.h> #include <linux/exportfs.h> +#include "../pnode.h" #include "overlayfs.h" MODULE_AUTHOR("Miklos Szeredi <miklos@xxxxxxxxxx>"); @@ -1175,6 +1176,14 @@ static int ovl_report_in_use(struct ovl_fs *ofs, const char *name) } } +static inline struct vfsmount *ovl_clone_private_mount(const struct path *path) +{ + if (IS_MNT_UNBINDABLE(real_mount(path->mnt))) + return ERR_PTR(-EINVAL); + + return clone_private_mount(path); +} + static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs, struct ovl_layer *upper_layer, struct path *upperpath) { @@ -1201,7 +1210,7 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs, if (err) goto out; - upper_mnt = clone_private_mount(upperpath); + upper_mnt = ovl_clone_private_mount(upperpath); err = PTR_ERR(upper_mnt); if (IS_ERR(upper_mnt)) { pr_err("failed to clone upperpath\n"); @@ -1700,7 +1709,7 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, } } - mnt = clone_private_mount(&stack[i]); + mnt = ovl_clone_private_mount(&stack[i]); err = PTR_ERR(mnt); if (IS_ERR(mnt)) { pr_err("failed to clone lowerpath\n"); -- 2.27.0