|
|
Log in / Subscribe / Register

Topics from the virtual filesystem layer

By Jake Edge
April 16, 2025

LSFMM+BPF

In the first filesystem-track session at the 2025 Linux Storage, Filesystem, Memory Management, and BPF Summit (LSFMM+BPF), virtual filesystem (VFS) layer co-maintainer Christian Brauner had a few different topics he wanted to talk about. Issues on the agenda included iterating through anonymous mount namespaces, a needed feature for ID-mapped mounts, the perennial unprivileged mounts topic, potentially using hazard pointers for file reference counting, and Rust bindings. He did not expect to get through all of them in the 30 minutes allotted, but the session did move along pretty quickly to at least introduce them to the assembled filesystem developers.

$ sudo subscribe today

Subscribe today and elevate your LWN privileges. You’ll have access to all of LWN’s high-quality articles as soon as they’re published, and help support LWN in the process. Act now and you can start with a free trial subscription.

He noted that one of the accomplishments for the filesystem community over the last few years was in reworking the mount process and API. He was hopeful that mount notifications would be merged during the 6.15 merge window that was taking place during the summit—and they were. That feature will be useful for getting notifications of changes to mount trees, rather than having to frequently query the kernel or /proc files to keep track.

Anonymous mount namespaces

[Christian Brauner]

In the VFS, there is a notion of anonymous mount namespaces ("or 'detached mount trees', however you want to look at it") where a mount namespace exists, but processes cannot use setns() to enter it; it is not attached to anything else. Oddly, though, a process can chroot() to a directory in it, but then cannot list the mounts in the namespace. These mount namespaces do not have a representation in /proc/PID/mountinfo, which makes them "completely opaque to user space"; there is no way to interact with them, he said. That is a problem because, for example, a process can have a file descriptor for such a namespace, which pins various things into memory, but there is no way for user space to figure out what is responsible for pinning the memory.

So there is a need to expand the listmount() and statmount() system calls to be able to interact with anonymous mount namespaces. There is now a way to iterate through all mounts in all mount namespaces, except those attached to anonymous mount namespaces. Container workloads, under Kubernetes in particular, can have hundreds of mount namespaces; prior to the addition of listmount() and statmount(), listing all of the mounts would have required concatenating the output from all of the /proc/PID/mountinfo files. Extending that to the anonymous mount namespaces will help complete the API, he said.

Jeff Layton asked if the anonymous mount namespaces are collected onto a list in the kernel somewhere, but Brauner said they are not currently. There is a red-black tree for the mount namespaces, but that is indexed by the sequence number assigned to the namespace; anonymous mount namespaces all have a sequence number of zero. Instead of using the zero to recognize anonymous entries, a flag or something should be used, then a regular sequence number can be assigned and the entries can be added to the tree, Brauner said.

Layton said that he has been running into a similar problem with network namespaces; NFS can take a reference to a disconnected network namespace that then stays alive with no way to track down what has the reference. Brauner said that he had discussed this problem with Josef Bacik recently and they agreed that all namespaces should follow the plan for mount namespaces and assign a sequence number for each; the struct ns_common that holds namespaces would have the sequence number (or some kind of identifier) added to it, so that namespaces can be added to data structures and operated upon. It is a generic problem for namespaces that should be solved in a unified way, Brauner said.

ID-mapped mounts

Another thing he has been working on is a follow-on to the ID-mapped mounts feature that was merged into the 5.12 kernel in 2021. In 6.15, the ability to change UID and GID mappings for an ID-mapped filesystem by performing another ID-mapped mount on it was added. Now there is a need for various squashing options, where, for example, a range of IDs all map to a single ID.

One of the problems with the existing ID-mapping mechanism is that every ID present in the filesystem needs to be explicitly mapped to another ID or a file with an unmapped ID has no ID—it cannot be interacted with at all. For efficiency reasons, there may need to be limits on the number of squashed ranges that can be supported, but some kind of simple range squashing is needed. In addition, a way to say that any unlisted IDs map to a single specific ID should be supported.

The interface for specifying mappings currently follows the model that user namespace mappings use, where mapping information is written to /proc files. That works, but Brauner does not think it will scale to the needs of ID-mapped mounts. His immediate focus is to add a way to squash all of the unmapped IDs to a specified ID; he has a proof-of-concept implementation in his tree that passes all of his tests. It will make things much simpler for use cases like mapping all of the IDs on a filesystem to a single ID as no lookup will be needed.

Unprivileged mounts

Brauner informally polled the audience for which topic the attendees wanted him to talk about next: unprivileged mounts or file reference counts. Several spoke up for the mount topic and any reference-count fans were notably silent. "Dammit, I wanted to pitch hazard pointers", he said with a laugh, though he did eventually get to the topic.

There are two aspects to the unprivileged-mount problem; the first is to allow unprivileged users to mount "a random USB stick", which is "a really terrible idea". The other is to mark a specific filesystem as being mountable inside of a user namespace, "which adds a bit more protection, at least in terms of setuid binaries and all that kind of stuff", he said, but it does not help with the problems of malicious filesystem images. He does not think that there is any solution for allowing unprivileged users to mount random filesystem images; "I don't believe that Rust will solve this problem, I think that's a pipe dream".

Brauner pointed to the solution described in an LSFMM+BPF session from 2023, which allows user space to "safely delegate mounting of filesystems to unprivileged users" using systemd-mountfsd. That solution does not work for network filesystems, but Layton said that was simply a policy decision; the same mechanism could be used but network filesystems would need to add some capabilities to enable it.

For the USB-stick case, Brauner said, the solution should be to use Filesystem in Userspace (FUSE) and "don't mount untrusted stuff". Over the remote link, Jan Kara said that the solution for USB mounts does not lie in the kernel. OpenSUSE has started looking into mounting USB sticks using the Linux Kernel Library (LKL), which is somewhat similar to User Mode Linux; it has a FUSE daemon that uses LKL to mount the filesystem and expose it to the kernel, which "provides additional isolation". For USB sticks, performance is not particularly important, he said, so this "seems like a promising solution"

Reference counts

Last year, Brauner said, he added a reference-count mechanism for struct file; the patch set uses something similar to rcuref with dead zones so that an unconditional increment can be done when taking a reference to an entry in the files table via the file descriptor. It provides a 3-5% performance increase when there is a lot of contention, "which is great obviously", but he thinks the scalability problem has just been pushed out further.

So there is a need to explore other options. There was a patch set implementing hazard pointers for the kernel that he has been experimenting with, but that implementation is not suitable for struct file. It does scanning in the background and memory allocation. If hazard pointers were to be used, though, the file-reference path may need to allocate memory, which would add another possible error path.

He would like to explore the idea further, but it is "a very vague idea" at this point; it might lead to regressions in the single-threaded case, though, which would not be desirable. Amir Goldstein asked where the scalability problem lies; Brauner said that it comes from contention with socket file descriptors in highly threaded workloads. "It's not fantasized, it's actually an issue", but is not likely to be one for highly threaded writes, because there are other synchronization activities present for those workloads.

Wrapping up in his final 30 seconds, Brauner said that the Rust inode bindings should be discussed at some point. He plans to pick up those patches in the hopes of "getting something like that merged" within the next two years.


Index entries for this article
KernelFilesystems/Virtual filesystem layer
ConferenceStorage, Filesystem, Memory-Management and BPF Summit/2025


to post comments

Performance for USB drives matters!

Posted Apr 16, 2025 7:13 UTC (Wed) by Conan_Kudo (subscriber, #103240) [Link] (10 responses)

I wish Linux kernel folks would stop saying performance does not matter for filesystems on removable drives, it's simply not true. There are plenty of use-cases where that performance matters for folks. At least for me, it would be pretty bad if my video games stuttered because my game drive (which is a removable USB drive) was being mounted on a slow path because nobody cares about performance for non-fixed drives. I don't think anyone would reasonably accept a reduction in I/O performance and increase in latency like that just because it's a removable drive.

Performance for USB drives matters!

Posted Apr 16, 2025 7:20 UTC (Wed) by gdiscry (subscriber, #91125) [Link] (6 responses)

While I agree with you, I think that the "for USB sticks, performance is not particularly important" stance mainly applies to automounting random USB drives not trusted by the user.

For your use case, you would probably configure fstab/systemd to mount your USB drive when plugged and not rely on some kind of FUSE automount.

Performance for USB drives matters!

Posted Apr 16, 2025 7:29 UTC (Wed) by Conan_Kudo (subscriber, #103240) [Link] (5 responses)

Sure, I can do that, but most people probably won't even be able to figure it out. What you don't want to do is push Linux distributors to have to make a choice about defaults for performance vs security, because in most cases, security does not win.

Performance for USB drives matters!

Posted Apr 16, 2025 12:26 UTC (Wed) by mokki (subscriber, #33200) [Link] (4 responses)

The kernel just provides the options. Your desktop environment can ask if you trust the USB drive and do you want 1% or 2% cpu consumption when accessing the device. And then either mount as fuse or sudo mount using kernel drivers. The DE can also remember you choice by drive serial number.

Performance for USB drives matters!

Posted Apr 16, 2025 16:25 UTC (Wed) by SLi (subscriber, #53131) [Link] (3 responses)

Drive serial number is device reported. How common is it that you can trust the random USB stick, but not the image on it?

Performance for USB drives matters!

Posted Apr 16, 2025 16:34 UTC (Wed) by gnb (subscriber, #5132) [Link]

True, but if the setup only trusts specific serial numbers an attacker has to guess a suitable SN to fake.

Trusting the USB stick but not the filesystem

Posted Apr 16, 2025 17:09 UTC (Wed) by farnz (subscriber, #17727) [Link]

I would expect the trusted USB stick, unknown image trust level situation to be more common than you might think; it's not completely unknown for people to write filesystem images from an Internet source to a USB stick (to create a bootable device for installing OSes or similar).

As a result, even when you screen all USB hardware for safety (which is required if you need to be worried about the stick, since it could appear as USB-HID or other non-storage classes of device), you still have to worry about users putting untrustworthy images onto trustworthy hardware. This would still apply if, instead of the serial number or similar easy-to-copy data, you used USB device authentication to cryptographically verify that the device is supposed to be trustworthy.

Performance for USB drives matters!

Posted Apr 16, 2025 17:55 UTC (Wed) by pizza (subscriber, #46) [Link]

> Drive serial number is device reported. How common is it that you can trust the random USB stick, but not the image on it?

I had an entire box of USB sticks that reported the same serial number. I might trust the one in my hand, but they were effectively indistinguishable from each other.

(I think they all came preformatted with a completely identical FAT32 image, ie with an identical volume label on top of the same serial number...)

Performance for USB drives matters!

Posted Apr 16, 2025 11:29 UTC (Wed) by koverstreet (subscriber, #4296) [Link] (2 responses)

Often these slowpaths just burn slightly more cpu, and that matters not one bit when the iops rate is in the thousands/tens of thousands.

Performance for USB drives matters!

Posted Apr 16, 2025 12:46 UTC (Wed) by zdzichu (subscriber, #17118) [Link]

Fastest USB drives reach about 1GiB/s speeds with hundreds thousands of IOPS, currently. I suspect slow paths matter for them.

Performance for USB drives matters!

Posted Apr 19, 2025 12:19 UTC (Sat) by LtWorf (subscriber, #124958) [Link]

How much is slighly more? In my experience FUSE is very very slow, and if you are recording multiple audio channels to a USB3 disk, the record might get ruined because of thinking usb performances do not matter.


Copyright © 2025, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds