Re: [RFC PATCH] getting misc stats/attributes via xattr API
From: Dave Chinner <david@fromorbit.com>
Date: 2022-05-10 23:26:25
Also in:
linux-fsdevel, linux-man, linux-security-module, lkml
On Tue, May 10, 2022 at 02:35:12PM +0200, Karel Zak wrote:
On Mon, May 09, 2022 at 02:48:15PM +0200, Christian Brauner wrote:quoted
One comment about this. We really need to have this interface support giving us mount options like "relatime" back in numeric form (I assume this will be possible.). It is royally annoying having to maintain a mapping table in userspace just to do: relatime -> MS_RELATIME/MOUNT_ATTR_RELATIME ro -> MS_RDONLY/MOUNT_ATTR_RDONLY A library shouldn't be required to use this interface. Conservative low-level software that keeps its shared library dependencies minimal will need to be able to use that interface without having to go to an external library that transforms text-based output to binary form (Which I'm very sure will need to happen if we go with a text-based interface.).Sounds like David's fsinfo() :-) We need an interface where the kernel returns a consistent mount table entry (more syscalls to get more key=value could be a way how to get inconsistent data). IMHO all the attempts to make a trivial interface will be unsuccessful because the mount table is complex (tree) and mixes strings, paths, and flags. We will always end with a complex interface or complex strings (like the last xatts attempt). There is no 3rd path to go ... The best would be simplified fsinfo() where userspace defines a request (wanted "keys"), and the kernel fills a buffer with data separated by some header metadata struct. In this case, the kernel can return strings and structs with binary data. I'd love something like: ssize_t sz; fsinfo_query query[] = { { .request = FSINFO_MOUNT_PATH }, { .request = FSINFO_PROPAGATION }, { .request = FSINFO_CHILDREN_IDS }, }; sz = fsinfo(dfd, "", AT_EMPTY_PATH, &query, ARRAY_SIZE(query), buf, sizeof(buf)); for (p = buf; p < buf + sz; ) { { fsinfo_entry *e = (struct fsinfo_entry) p; char *data = p + sizeof(struct fsinfo_entry); switch(e->request) { case FSINFO_MOUNT_PATH: printf("mountpoint %s\n", data); break; case FSINFO_PROPAGATION: printf("propagation %x\n", (uintptr_t) data); break; case FSINFO_CHILDREN_IDS: fsinfo_child *x = (fsinfo_child *) data; for (i = 0; i < e->count; i++) { printf("child: %d\n", x[i].mnt_id); } break; ... } p += sizeof(struct fsinfo_entry) + e->len; }
That's pretty much what a multi-xattr get operation looks like. It's a bit more more intricate in the setup of the request/return buffer, but otherwise the structure of the code is the same. I just don't see why we need special purpose interfaces like this for key/value information when small tweaks to the existing generic key/value interfaces can provide exactly the same functionality.... Cheers, Dave. -- Dave Chinner david@fromorbit.com