Plan a production-grade, highly concurrent architecture for fully wiring the 9P2000.L protocol into the NinePFSKit FSKit extension(NinePFSKit/NinePFSKitExtension). The design must eliminate the current single-NSLock bottleneck that serializes all FSKit operations behind TCP round-trips.
Current state:
- NinePFSKit is a fully functional in-memory FSKit filesystem (Volume.swift, Item.swift) with PoC 9P wiring limited to:
activate()(TCP connect) andcreateItem()(mkdir only, non-fatal). - All other operations (read, write, lookup, enumerate, getAttributes, setAttributes, remove, rename, open, close) run purely in-memory.
- A single
NSLockprotects all mutable state. The PoC holds this lock during blocking 9P I/O calls, serializing everything. It was only for PoC. We should get rid of it for production-grade implementation AsyncNineP9Client(Rust FFI via UniFFI) exposes both high-level path-based API (walk→op→clunk per call) and low-level FID-based API (walk, open, read, write, clunk independently).
Requirements:
- Server-authoritative: 9P server is source of truth for all file content and metadata.
- No global lock held during network I/O.
- Concurrent reads on unrelated files must not block each other.
- FID caching on Items (open once at
openItem, reuse for read/write/fsync, clunk atcloseItem). - Per-item or per-operation granularity for synchronization — not per-volume.
- Safe handling of rename/remove races (item accessed while being moved/deleted).
- Study the Linux kernel v9fs client (
linux/v9fs/) for design decisions — FID lifecycle, caching strategy, lock granularity, and error handling patterns are battle-tested references. - Server address (
127.0.0.1:5564) is hardcoded inConstants.swift— keep it as-is, do not make it configurable. - Do not change the current mount approach — the existing
fskit-ctlbuild/mount/cleanup cycle and FSKit container/volume registration must remain as-is. - Use
fsctlwherever appropriate for control operations — prefer the system-providedfsctlinterface over custom solutions.
Research these references before designing:
- Linux kernel v9fs client (
linux/v9fs/): Local copy of the kernel's 9P filesystem. Key files:fid.c/fid.h(FID caching on dentries),vfs_file.c(read/write/fsync),vfs_inode.c/vfs_inode_dotl.c(inode ops, per-inode locking),vfs_dir.c(readdir),cache.c(caching layer),xattr.c(extended attributes). Study how it uses per-inodei_rwseminstead of global locks, and adapt these patterns to FSKit's single-process model. NinePFSKit/FSKit-LLMS.md: FSKit API reference — operation signatures, FSItem.Attributes, FSDirectoryEntryPacker, FSMutableFileDataBuffer, reply handler contracts.NinePFSKit/README.md: Project architecture, build/mount/test workflow via fskit-ctl.NinePFSKit/fskit-ctl: The control tool script — build, mount, cleanup, server management, log streaming commands. Study it to understand the exact build/test cycle and use its commands in dual-log validation.- 9P filesystem documentation: Official Linux kernel docs for the 9P client — mount options, cache modes, transport types, and protocol semantics.
Iterative testing strategy — dual-log validation per operation:
Every operation wired to 9P must be validated with dual-log verification before moving to the next. After implementing each operation (e.g., lookup, read, write, enumerate, remove, rename, getAttributes, setAttributes, open, close, xattr), follow this cycle:
- Ensure server is running — check if the 9P server is already started(
./NinePFSKit/fskit-ctl server-status); if not, start it with./NinePFSKit/fskit-ctl server-start. - Build & mount —
./NinePFSKit/fskit-ctl build && ./NinePFSKit/fskit-ctl mount - Open dual logs — server logs (
./NinePFSKit/fskit-ctl server-tee 50) and client logs (./NinePFSKit/fskit-ctl logstream) side by side. - Exercise the specific operation from the shell (e.g.,
catfor read,echo >for write,lsfor enumerate,mkdirfor createItem,rmfor remove). - Verify correlation — every client-side FSKit callback must produce a matching 9P T-message in the server log and a matching R-message back. — latest server logs (
./NinePFSKit/fskit-ctl server-tee 50) - Verify error propagation — trigger error cases (e.g., ENOENT, EEXIST, EACCES) and confirm
Rlerrorerrno flows from server log → client log → correct POSIX error returned to caller. - Cleanup —
./NinePFSKit/fskit-ctl cleanup
Do NOT batch-implement multiple operations and test at the end. Each operation is a discrete commit with its own dual-log evidence. The plan must specify the implementation order and the exact shell commands + expected log patterns for each operation's validation.
A concrete design with data structures, synchronization primitives, FID lifecycle management, and the wiring for every FSKit operation. Include the concurrency model, error propagation strategy, and migration path from the current NSLock PoC.