On Sat, May 03, 2025 at 10:29:25PM +0100, Al Viro wrote: > The last remaining user of vfs_submount() (tracefs) is easy to convert > to fs_context_for_submount(); do that and bury that thing, along with > SB_SUBMOUNT > > If nobody objects, I'm going to throw that into the mount-related pile; > alternatively, that could be split into kernel/trace.c part (in invariant > branch, to be pulled by tracefs folks and into the mount pile before > the rest of the patch). Preferences? > > Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> > --- Looks good, Reviewed-by: Christian Brauner <brauner@xxxxxxxxxx> > diff --git a/fs/namespace.c b/fs/namespace.c > index 07f636036b86..293e6f925eff 100644 > --- a/fs/namespace.c > +++ b/fs/namespace.c > @@ -1297,21 +1297,6 @@ struct vfsmount *vfs_kern_mount(struct file_system_type *type, > } > EXPORT_SYMBOL_GPL(vfs_kern_mount); > > -struct vfsmount * > -vfs_submount(const struct dentry *mountpoint, struct file_system_type *type, > - const char *name, void *data) > -{ > - /* Until it is worked out how to pass the user namespace > - * through from the parent mount to the submount don't support > - * unprivileged mounts with submounts. > - */ > - if (mountpoint->d_sb->s_user_ns != &init_user_ns) > - return ERR_PTR(-EPERM); > - > - return vfs_kern_mount(type, SB_SUBMOUNT, name, data); > -} > -EXPORT_SYMBOL_GPL(vfs_submount); > - > static struct mount *clone_mnt(struct mount *old, struct dentry *root, > int flag) > { > diff --git a/fs/super.c b/fs/super.c > index 97a17f9d9023..1886e4c930e0 100644 > --- a/fs/super.c > +++ b/fs/super.c > @@ -823,13 +823,6 @@ struct super_block *sget(struct file_system_type *type, > struct super_block *old; > int err; > > - /* We don't yet pass the user namespace of the parent > - * mount through to here so always use &init_user_ns > - * until that changes. > - */ > - if (flags & SB_SUBMOUNT) > - user_ns = &init_user_ns; Oh thank god this disgusting hack is finally gone. > - > retry: > spin_lock(&sb_lock); > if (test) { > @@ -849,7 +842,7 @@ struct super_block *sget(struct file_system_type *type, > } > if (!s) { > spin_unlock(&sb_lock); > - s = alloc_super(type, (flags & ~SB_SUBMOUNT), user_ns); > + s = alloc_super(type, flags, user_ns); > if (!s) > return ERR_PTR(-ENOMEM); > goto retry; > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 016b0fe1536e..515e702d98ae 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -1240,7 +1240,6 @@ extern int send_sigurg(struct file *file); > /* These sb flags are internal to the kernel */ > #define SB_DEAD BIT(21) > #define SB_DYING BIT(24) > -#define SB_SUBMOUNT BIT(26) > #define SB_FORCE BIT(27) > #define SB_NOSEC BIT(28) > #define SB_BORN BIT(29) > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c > index fa488721019f..7b6248ba4428 100644 > --- a/kernel/trace/trace.c > +++ b/kernel/trace/trace.c > @@ -51,6 +51,7 @@ > #include <linux/workqueue.h> > #include <linux/sort.h> > #include <linux/io.h> /* vmap_page_range() */ > +#include <linux/fs_context.h> > > #include <asm/setup.h> /* COMMAND_LINE_SIZE */ > > @@ -10072,6 +10073,8 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore) > { > struct vfsmount *mnt; > struct file_system_type *type; > + struct fs_context *fc; > + int ret; > > /* > * To maintain backward compatibility for tools that mount > @@ -10081,10 +10084,20 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore) > type = get_fs_type("tracefs"); > if (!type) > return NULL; > - mnt = vfs_submount(mntpt, type, "tracefs", NULL); > + > + fc = fs_context_for_submount(type, mntpt); > + if (IS_ERR(fc)) > + return ERR_CAST(fc); > + > + ret = vfs_parse_fs_string(fc, "source", > + "tracefs", strlen("tracefs")); > + if (!ret) > + mnt = fc_mount(fc); > + else > + mnt = ERR_PTR(ret); > + > + put_fs_context(fc); > put_filesystem(type); > - if (IS_ERR(mnt)) > - return NULL; > return mnt; > } >