On Mon 05-05-25 22:38:29, Al Viro wrote: > On Mon, May 05, 2025 at 12:55:34PM +0200, Jan Kara wrote: > > > 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); > > > > Missing put_filesystem() here? > > Actually, I'd rather have it done unconditionally right after > fc_context_for_submount() - fs_context allocation grabs > a reference and it's held until put_fs_context, so... > > [PATCH] kill vfs_submount() > > 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 > > Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Indeed this works as well. Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > diff --git a/fs/namespace.c b/fs/namespace.c > index 018e95fe5459..0577a9fb6050 100644 > --- a/fs/namespace.c > +++ b/fs/namespace.c > @@ -1329,21 +1329,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; > - > 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/include/linux/mount.h b/include/linux/mount.h > index dcc17ce8a959..d4eb90a367af 100644 > --- a/include/linux/mount.h > +++ b/include/linux/mount.h > @@ -98,9 +98,6 @@ extern struct vfsmount *vfs_create_mount(struct fs_context *fc); > extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, > int flags, const char *name, > void *data); > -extern struct vfsmount *vfs_submount(const struct dentry *mountpoint, > - struct file_system_type *type, > - const char *name, void *data); > > extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list); > extern void mark_mounts_for_expiry(struct list_head *mounts); > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c > index e22aacb0028a..936a615e8c56 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 */ > > @@ -10075,6 +10076,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 > @@ -10084,10 +10087,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); > put_filesystem(type); > - if (IS_ERR(mnt)) > - return NULL; > + 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); > return mnt; > } > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR