Capabilities
Capabilities state what a driver supports. Declare facts that mountx cannot infer. Mountx infers the other facts from driver methods. It does not simulate missing features.
import { resolveCapabilities } from "mountx";
import type { FsCapabilities, MountxExtensions, ResolvedCapabilities } from "mountx";#FsCapabilities
interface FsCapabilities {
handles?: boolean; // open() returns real per-open state that survives unlink
hardlinks?: boolean; // link() works and nlink is counted
symlinks?: boolean; // symlink()/readlink() work; lstat differs from stat
permissions?: boolean; // mode and ownership bits are stored and returned
times?: boolean; // utimes() is stored and returned
truncate?: boolean; // truncate() and FileHandle.truncate() work
atomicRename?: boolean; // rename() replaces the destination atomically
caseSensitive?: boolean; // names differing only in case are distinct
statfs?: boolean; // statfs() returns meaningful numbers
readOnly?: boolean; // every mutating operation answers EROFS
durableWrites?: boolean; // a write is durable once its promise resolves
extensions?: readonly (keyof MountxExtensions)[];
}An unset value means "infer this value." It does not mean false. See Writing a driver for each inference rule. Mountx cannot infer handles, atomicRename, readOnly, or durableWrites. These four values default to false.
Declare readOnly when every operation that can change data returns EROFS. The absence of methods such as unlink, mkdir, and rename does not prove that a driver is read-only. The driver can still open files for writing. Therefore, mountx cannot infer this capability.
Declare durableWrites only when no data remains buffered after write() resolves. The memory driver has durable writes. A driver that batches work or uploads in the background does not have durable writes, even if write() resolves quickly.
When durableWrites is true, FUSE does not answer FLUSH.
The kernel sends FLUSH for each close(2).
It is the third most common opcode in an install workload.
A false declaration can silently lose a write error.
The test suite does not cover delayed close(2) errors, so you must verify this declaration from the driver's design.
If a capability is not available, mountx returns ENOSYS or ENOTSUP. Mountx must not report support for a missing capability.
#resolveCapabilities(driver)
function resolveCapabilities(driver: FsDriver): ResolvedCapabilities;Explicit declarations take priority. When no declaration exists, the presence of a method determines the result. ResolvedCapabilities contains a value for every member. createLoopback() exposes this object as fs.capabilities.
#MountxExtensions
Use the optional driver.mountx namespace for operations that node:fs does not provide.
interface MountxExtensions {
// Nanosecond timestamps; fs.utimes takes float seconds and loses them.
utimens?(
path: string,
atimeNs: bigint,
mtimeNs: bigint,
options?: { followSymlinks?: boolean },
): Promise<void>;
// FIFOs, sockets and device nodes.
mknod?(path: string, mode: number, dev: number): Promise<void>;
}Transports check each extension separately. They reduce their feature set when an extension is absent. Both extensions are currently used:
mknodis used by all three mount transports. This is four sessions when NFSv3 and NFSv4.1 are counted separately. The memory driver implements it. Withoutmknod,MKNOD,Tmknod, and NFSv4.1CREATEreturnENOSYSorNOTSUPPfor all types except regular files. S3 and WebDAV cannot represent a first-in, first-out (FIFO) file or device node, so they do not use it.utimensis used by FUSE and 9P. Their protocols carry nanoseconds thatfs.utimeswould round. NFSSETATTRalso carries nanoseconds, but the NFS sessions do not yet use this extension.
This namespace contains only path-based gaps in node:fs. Locks, fallocate, lseek, and cache invalidation apply to an open file or a session. They must be designed in the session layer. The four xattr types had no consumer and were removed. Add them again only with session work that handles the related opcodes.
#Next
- Loopback harness shows how to inspect resolved capabilities.
- Driver interface lists the methods used for inference.