Re: Upcoming: Notifications, FS notifications and fsinfo()

From: Miklos Szeredi
Date: Wed Apr 01 2020 - 09:34:48 EST


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);