What I'm building An FSUnaryFileSystem that projects a large, read-mostly tree of existing on-disk files into a sandbox namespace — a build sandbox that lays out an action's declared inputs and points outputs at host scratch. This is squarely the "replace a third-party kext (macFUSE-style) with FSKit" use case, and it's a projection/overlay filesystem: nearly every file the volume serves is just a view of a regular file that already exists on a local APFS volume.
The problem For file content, the only available path for a file-backed (non-block-device) volume is FSVolumeReadWriteOperations — every read that misses UBC is an XPC round-trip into my extension, where I memcpy from the backing file into the kernel buffer. The kernel already has, or could trivially open, the backing file; instead each page-in becomes: pagein → IPC → extension read → copy → return.
FSVolumeKernelOffloadedIOOperations looks like the intended fast path, but it's built around FSBlockDeviceResource — i.e. it assumes the volume is backed by a block device the kernel can do extent I/O against. A projection over regular files has no block device, so there's no way to say "this item is backed by host file X — kernel, please do I/O directly against X and skip my process."
What I measured In one representative build action my volume serves ~440 files and the kernel issues ~630 read RPCs (cold). A real build runs thousands of such actions, so this is on the order of millions of round-trips and buffer copies per build, for data that is already sitting in the host page cache. UBC absorbs repeats, but cold reads, cache eviction under memory pressure, and large sequential reads all pay the full RPC+copy cost. It dominates the I/O profile.
The ask A passthrough/offload API for file-backed volumes: let the extension associate an FSItem with a backing file descriptor (or vnode) and have the kernel perform reads — and optionally writes — directly against the backing file, bypassing the userspace round-trip. Per-item, opt-in, and read-only-only would already be a huge win for projection/overlay workloads.
This is exactly the model that already exists on other platforms:
Linux FUSE passthrough (FUSE_PASSTHROUGH, backing-id via FUSE_DEV_IOC_BACKING_OPEN, mainline since 6.9): a FUSE daemon registers a backing fd and the kernel routes I/O straight to it. Windows Projected File System (ProjFS): content is hydrated/served from a provider-supplied source without a per-read user-space hop. FSKit is positioned as the supported replacement for kext-based filesystems, and projection/overlay/caching filesystems are a primary motivation for it — yet those are precisely the volumes that need zero-copy passthrough to be viable at scale. The block-device offload path covers disk-image-style filesystems; the gap is the file-backed case.