The day after Linux 7.2's release, a series of VFS pull requests for Linux 7.3 landed in Torvalds' mainline. What disappeared here were EFS, which reads old SGI IRIX on-disk formats, and FreeVxFS, which handled 1990s Unix compatibility. Added on the same day was FailFS, which makes name resolution fail entirely, tying processes to file descriptors they already hold. NILFS2 also received a change moving its O_DIRECT read path to iomap, the common I/O layer.

Developers did not declare these three changes as a single unified policy. But when placed alongside the new filesystem acceptance documentation that was put together for Linux 7.2, a pattern emerges for how code retained in the kernel gets chosen: compatibility implementations whose usage and maintenance have thinned to the point where testing becomes difficult are removed. Isolation semantics that cannot be expressed through normal pathname access get a small, dedicated implementation. Active niche implementations are brought closer to shared I/O infrastructure.

AD

Removing 3,724 Lines, Adding 931

The merge removing EFS and FreeVxFS touched 30 files with 3,724 lines deleted and none added. EFS is a read-only driver for reading the pre-XFS SGI IRIX format, and it was marked as Orphan in MAINTAINERS. FreeVxFS was also read-only, and according to Christian Brauner's pull description, only one user-cum-contributor had been identified over the past 15 years. The FreeVxFS removal alone accounted for 19 files and 2,432 lines.

What's being lost here is the path for directly mounting and reading the corresponding disk formats within the Linux kernel itself. The existing disks themselves remain intact. For EFS, there's also a userspace tool called efsextract for extracting data outside the kernel. Organizations that continue to handle old media going forward need to weigh the value of what's archived against the maintenance burden of keeping it in the kernel.

By contrast, the FailFS merge added 931 lines and removed 5 across 44 files, including self-tests and documentation. Beyond the line counts, what's striking is the difference in the role the code plays. Where EFS and FreeVxFS provided functionality for reading past data formats, FailFS adds a new isolation boundary for how processes currently reference filesystems.

"Empty" and "Refused" Are Different Things

FailFS is a pseudo-filesystem strictly internal to the kernel that cannot be mounted from userspace. A single instance is created at boot time via kern_mount(), placed logically separate from each mount namespace. Every filesystem operation that reaches it fails with EOPNOTSUPP. This is neither EACCES nor EPERM, which could be read as suggesting success might follow with different permissions, nor EIO, which would suggest media failure. It's a deliberate choice to explicitly signal "this operation is not supported."

The comparable nullfs provides an empty, immutable directory. Looking up a name yields ENOENT, but you can open the root, perform reads and stats, and mount on top of it. FailFS, however, doesn't allow opening the root inode even with O_PATH, and statfs() and fstatfs() also fail. It doesn't appear in /proc/filesystems, mountinfo, or statmount/listmount either. Rather than providing an empty location, this is a design that closes off the operational surface of being a filesystem entirely.

This distinction matters for sandboxing. There's a difference between having nothing to explore and the act of exploring itself not being viable. The former leaves room for later mounts or operations against an existing root to slip in. FailFS deliberately eliminates that possibility.

AD

Discarding Implicit root/cwd, Anchoring on Directory FDs

The entry point into FailFS is a sentinel called FD_FAILFS_ROOT, interpreted by fchdir(2) and the new fchroot(2). Moving the current working directory (cwd) to FailFS causes relative path lookups anchored on AT_FDCWD to fail, and getcwd() indicates unreachability. Moving root to FailFS causes resolution of absolute paths, absolute symlinks, and the PT_INTERP referenced by dynamically linked executables to all fail.

However, lookups such as openat() anchored on directory file descriptors (directory FDs) that a process already holds explicitly continue to work. Programs cannot walk from the implicit anchors of root or cwd, but they can use FDs handed to them in advance as capabilities. This is why FailFS's documentation describes it as equivalent to RESOLVE_BENEATH for filesystem state.

It's not a feature you can enter unconditionally, either. Calling fchroot(FD_FAILFS_ROOT, 0) with privileges requires CAP_SYS_CHROOT in the caller's user namespace. Entering without privileges requires that no_new_privs already be set, that the process not already be chrooted, and that fs_struct not be shared with other processes. These respectively guard against paths reaching setuid binaries through inherited FDs, escapes outside an existing chroot via .., and mismatched conditions with sibling processes sharing root/cwd through CLONE_FS.

Exiting FailFS can be strongly constrained at present, but the documentation makes no ABI guarantee that escape is permanently impossible. FailFS is also not a feature that replaces seccomp, Landlock, mount namespaces, or ordinary chroot. It should be read as an additional primitive for discarding implicit filesystem state and narrowing access down to explicit directory FDs.

Criteria Separating Removal, Addition, and Modernization

Linux's new filesystem acceptance documentation positions implementations that enter the kernel as a joint responsibility shared between VFS maintainers and the broader filesystem community. Unmaintained implementations become difficult to test, accumulate the burden of preserving old APIs along with unfixed bugs, and impede changes to underlying infrastructure. New filesystems are required to connect to current VFS interfaces and to provide any necessary userspace utilities. They also need to establish meaningful testing and documentation, along with clear maintainers and a sustained maintenance structure. Implementations that fail to keep pace become candidates for deprecation and eventual removal.

Applying this criterion directly to FailFS wouldn't quite be appropriate. FailFS isn't a filesystem implementing an on-disk format—it's an internal kernel isolation mechanism. Even so, reading the documentation alongside this round of changes makes clear that Linux isn't simply retaining everything within the kernel; rather, it demands semantics that cannot be expressed through common infrastructure, along with the verification that supports maintaining them. FailFS comes accompanied by documentation and self-tests.

NILFS2's treatment shows a third path. In the update headed for Linux 7.3, the O_DIRECT read path was moved to iomap. iomap is a layer that unifies block mapping and I/O, and the new filesystem documentation also calls for block-type filesystems to use iomap rather than buffer heads. Rather than removing NILFS2, the direction taken is to bring it closer to common infrastructure and maintain it.

AD

What to Watch for in Linux 7.3

These changes were integrated into mainline on August 17, but the formal release of Linux 7.3 is still to come. What needs verification during the release candidate (RC) period is how much the removals affect existing builds and operations involving old media, and how FailFS's new paths behave across various architectures and self-tests.

The userspace side matters as well. Whether fchroot() gets a libc wrapper, gets documented in man-pages, and whether container runtimes or sandboxes adopt this primitive are all things that remain undecided at this point. FailFS's value can't be measured merely by having landed in the kernel. Its practical shape will be determined by where execution environments designed around FDs choose to use this boundary that severs implicit root/cwd.