On Tue, Nov 21, 2023, at 6:28 PM, Ian Kent wrote: > On 22/11/23 04:42, Zack Weinberg wrote: >> On Tue, Nov 21, 2023, at 2:42 PM, Miklos Szeredi wrote: >>> handle = listmount_open(mnt_id, flags); >>> for (;;) { >>> child_id = listmount_next(handle); >>> if (child_id == 0) >>> break; >>> /* do something with child_id */ >>> } >>> listmount_close(handle) >> >> Why can't these be plain old open, read, and close? Starting from a pathname >> in /proc or /sys. Doesn't allow lseek. > > I'm not sure how this would work, there aren't a series of paths in proc > that represent mounts? It would be a new one created for this purpose. listmount_open(mnt_id, flags) == open("/proc/mount_ids", O_RDONLY) + ioctl(fd, LISTMNT_QUERY_ID, mnt_id) + ioctl(fd, LISTMNT_QUERY_FLAGS, flags) and then read(fd, buf, sizeof(buf)) gives you sizeof(buf)/sizeof(mntid_t) mount IDs. Or, if you prefer, keep the new listmount_open() system call but have it return a file descriptor that acts like a pipe filled with all the child mount IDs. The main point of my suggestion is that listmount_next and listmount_close can, and should (IMO), just be read() and close(). Note that I'm _not_ suggesting a text-based interface like most of /proc. What you read is native-endian binary mount IDs. > One is that open() is a fairly high overhead system call and it so it > won't cope well with traversing a large volume of mounts. ... > Second is that, because the mount table lives in a file (actually more > than one with slightly different formats) it needs to be traversed every > time one is looking for a mount which has been shown to be high overhead, Does my clarified explanation address these concerns? zw