On Mon, Jun 24, 2024 at 03:40:51PM GMT, Josef Bacik wrote: > In order to add the ability to export the mount options via statmount() > we need a helper to combine all the various mount option things we do > for /proc/mounts and /proc/$PID/mountinfo. The helper for /proc/mounts > can use this helper, however mountinfo is slightly (and infuriatingly) > different, so it can only be used in one place. This helper will be > used in a followup patch to export mount options via statmount(). > > Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx> > --- > fs/internal.h | 5 +++++ > fs/proc_namespace.c | 25 ++++++++++++++++++------- > 2 files changed, 23 insertions(+), 7 deletions(-) > > diff --git a/fs/internal.h b/fs/internal.h > index 84f371193f74..dc40c9d4173f 100644 > --- a/fs/internal.h > +++ b/fs/internal.h > @@ -321,3 +321,8 @@ struct stashed_operations { > int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, > struct path *path); > void stashed_dentry_prune(struct dentry *dentry); > + > +/* > + * fs/proc_namespace.c > + */ > +int show_mount_opts(struct seq_file *seq, struct vfsmount *mnt); > diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c > index e133b507ddf3..19bffd9d80dc 100644 > --- a/fs/proc_namespace.c > +++ b/fs/proc_namespace.c > @@ -84,6 +84,22 @@ static void show_vfsmnt_opts(struct seq_file *m, struct vfsmount *mnt) > seq_puts(m, ",idmapped"); > } > > +int show_mount_opts(struct seq_file *seq, struct vfsmount *mnt) > +{ > + struct dentry *dentry = mnt->mnt_root; > + struct super_block *sb = dentry->d_sb; > + int ret; > + > + seq_puts(seq, __mnt_is_readonly(mnt) ? "ro" : "rw"); > + ret = show_sb_opts(seq, sb); > + if (ret) > + return ret; > + show_vfsmnt_opts(seq, mnt); > + if (sb->s_op->show_options) > + ret = sb->s_op->show_options(seq, dentry); > + return ret; > +} > + > static inline void mangle(struct seq_file *m, const char *s) > { > seq_escape(m, s, " \t\n\\#"); > @@ -120,13 +136,8 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt) > goto out; > seq_putc(m, ' '); > show_type(m, sb); > - seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); > - err = show_sb_opts(m, sb); > - if (err) > - goto out; > - show_vfsmnt_opts(m, mnt); > - if (sb->s_op->show_options) > - err = sb->s_op->show_options(m, mnt_path.dentry); > + seq_putc(m, ' '); > + err = show_mount_opts(m, mnt); > seq_puts(m, " 0 0\n"); > out: > return err; > -- > 2.43.0 > So Karel just made me aware of this. You're using the old /proc/mounts format here and you're mixing generic sb options, mount options, and fs specific mount options. For example, the mount options you're currently passing contain "ro" and "rw". But these can be either per-mount setting or superblock settings and that isn't distinguiable based on "ro" and "rw". That information is also already contained and differentiated in statmount->sb_flags vs statmount->mnt_attr. Neither should or does show_vfsmnt_opts() need to be called as all that information is present in statmount->mnt_attr. Please only call ->show_options().