On Wed, Apr 1, 2020 at 11:05 AM Karel Zak <kzak@xxxxxxxxxx> wrote: > > On Tue, Mar 31, 2020 at 10:52:52PM +0100, David Howells wrote: > > Christian Brauner <christian.brauner@xxxxxxxxxx> wrote: > > > > > querying all properties of a mount atomically all-at-once, > > > > I don't actually offer that, per se. > > > > Having an atomic all-at-once query for a single mount is actually quite a > > burden on the system. There's potentially a lot of state involved, much of > > which you don't necessarily need. > > If all means "all possible attributes" than it is unnecessary, for > example ext4 timestamps or volume uuid/label are rarely necessary. > We usually need together (as consistent set): > > source > mountpoint > FS type > FS root (FSINFO_ATTR_MOUNT_PATH) > FS options (FSINFO_ATTR_CONFIGURATION) > VFS attributes > VFS propagation flags > mount ID > parent ID > devno (or maj:min) This is trivial with mountfs (reuse format of /proc/PID/mountinfo): # cat /mnt/30/info 30 20 0:14 / /mnt rw,relatime - mountfs none rw Attached patch applies against readfile patch. We might want something more generic, and it won't get any simpler: mount.h | 1 + mountfs/super.c | 12 +++++++++++- proc_namespace.c | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) Thanks, Miklos
--- fs/mount.h | 1 + fs/mountfs/super.c | 12 +++++++++++- fs/proc_namespace.c | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) --- a/fs/mount.h +++ b/fs/mount.h @@ -186,3 +186,4 @@ void mountfs_create(struct mount *mnt); extern void mountfs_remove(struct mount *mnt); int mountfs_lookup_internal(struct vfsmount *m, struct path *path); +int show_mountinfo(struct seq_file *m, struct vfsmount *mnt); --- a/fs/mountfs/super.c +++ b/fs/mountfs/super.c @@ -22,7 +22,7 @@ struct mountfs_entry { static const char *mountfs_attrs[] = { "root", "mountpoint", "id", "parent", "options", "children", - "group", "master", "propagate_from", "counter" + "group", "master", "propagate_from", "counter", "info" }; #define MOUNTFS_INO(id) (((unsigned long) id + 1) * \ @@ -126,11 +126,21 @@ static int mountfs_attr_show(struct seq_ if (IS_MNT_SLAVE(mnt)) { get_fs_root(current->fs, &root); tmp = get_dominating_id(mnt, &root); + path_put(&root); if (tmp) seq_printf(sf, "%i\n", tmp); } } else if (strcmp(name, "counter") == 0) { seq_printf(sf, "%u\n", atomic_read(&mnt->mnt_topology_changes)); + } else if (strcmp(name, "info") == 0) { + struct proc_mounts p = {}; + + WARN_ON(sf->private); + sf->private = &p; + get_fs_root(current->fs, &p.root); + err = show_mountinfo(sf, m); + path_put(&p.root); + sf->private = NULL; } else { WARN_ON(1); err = -EIO; --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c @@ -110,7 +110,7 @@ static int show_vfsmnt(struct seq_file * return err; } -static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) +int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) { struct proc_mounts *p = m->private; struct mount *r = real_mount(mnt);