docs: transport generality and the media-presence event
The NVMe/SATA assessment folded into the storage discussion: what transfers untouched (the block contract and everything above it — one driver binary plus one devices.csv row per transport), NVMe as the shorter stack whose namespaces are the reserved multi-volume case, AHCI as an open shape choice (leaning per-port processes, the matrix-proven granularity), and the three pressure points named honestly: multi-volume is reserved-not-implemented, synchronous call/reply bottlenecks NVMe until the shm-ring data plane, and media lifecycle is not device lifecycle. That last one becomes decision 7 and enters the architecture doc: the removal path has TWO TRIGGERS, ONE LIFECYCLE — channel death (device leaves) and a planned pushed medium_changed event (medium leaves, device stays: card readers and trays, USB ones today), translated by the storage driver from its transport's native signal, presence never content, consumed by the volume manager into the same kill-retire-remount path. Without it a swapped card would be served with the previous card's filesystem state.
This commit is contained in:
@@ -112,6 +112,48 @@ with everything else), and the 8-slot mount table gets a declared bound or
|
||||
growth once volumes multiply. The mount table stays the router; per-process
|
||||
namespaces (Plan 9's extra) remain separable future work.
|
||||
|
||||
## Transport generality: NVMe and SATA against this design
|
||||
|
||||
The layering was chosen transport-agnostic on purpose (the 9front lesson:
|
||||
filesystem services cannot tell a USB stick from an ATA disk); NVMe and AHCI
|
||||
are the test of that claim, and they fit — with three named pressure points.
|
||||
|
||||
**What transfers untouched:** the block protocol (nothing USB in it), the
|
||||
volume manager, partitions/ranges, filesystems, mounts, and the whole
|
||||
enforcement stack — delegation, IOMMU confinement (these are first-party PCI
|
||||
DMA masters, so confinement applies even more directly than USB),
|
||||
reap-and-rebuild, the hot-plug lifecycle. Integration cost per transport is
|
||||
what the architecture promises: one driver binary plus one `devices.csv` row.
|
||||
|
||||
**NVMe** shortens the stack — no bus/class split; the driver IS the
|
||||
controller driver, one hop fewer than USB. Its structural novelty,
|
||||
**namespaces** (hardware-native multiple volumes behind one controller), is
|
||||
exactly the case the block protocol reserved on day one and decision 4 below
|
||||
settles as endpoint-per-volume. **AHCI** is a shape choice, not a problem: an
|
||||
HBA fronts up to 32 ports plus port multipliers — structurally a bus — so
|
||||
either mirror USB (ahci-bus + a per-port disk driver: maximum restart
|
||||
granularity, the proven shape) or mirror NVMe (one driver per controller, one
|
||||
block channel per port). Leaning per-port processes for consistency with the
|
||||
matrix-proven shape; genuinely open.
|
||||
|
||||
**The pressure points, honestly:**
|
||||
|
||||
1. **Multi-volume providers are reserved, not implemented.** The volume
|
||||
manager flow assumes one provider, one volume; NVMe namespaces make
|
||||
endpoint-per-volume real work with hardware demanding it.
|
||||
2. **The current transport will bottleneck NVMe.** Synchronous call/reply,
|
||||
one operation in flight, one bounce buffer — fine for a USB2 stick,
|
||||
forfeits an NVMe drive's queue depth and per-queue MSI-X. Correctness
|
||||
needs nothing; performance is gated on the shm-ring data plane
|
||||
communication.md already names (Fuchsia's FIFO+VMO is the precedent).
|
||||
NVMe is not worth building before that milestone.
|
||||
3. **Media lifecycle ≠ device lifecycle.** ATAPI trays and SD card readers
|
||||
(USB ones too, today) keep the DEVICE present while the MEDIUM comes and
|
||||
goes — a removal trigger our channel-death lifecycle does not carry. The
|
||||
fix is decision 7 below. (Related small item: fat's bounce sizing
|
||||
hardcodes 512-byte sectors; 4Kn drives need the geometry honored
|
||||
throughout.)
|
||||
|
||||
## The decisions on the table
|
||||
|
||||
1. **Partitions as driver-side sub-ranges** (mechanism in usb-storage, parsing
|
||||
@@ -136,3 +178,15 @@ namespaces (Plan 9's extra) remain separable future work.
|
||||
names it as the 256-byte ceiling's unlock — Fuchsia's FIFO+VMO is the
|
||||
precedent); format-level crash honesty (a Power-Safe-style journaling or COW
|
||||
filesystem) once danos outgrows FAT; per-process namespaces.
|
||||
7. **The media-presence event** (settled in principle; lands with the volume
|
||||
manager): the block protocol gains a pushed event — `medium_changed`, with
|
||||
present/absent and a change counter — produced by the storage driver from
|
||||
its transport's native signal (SCSI UNIT ATTENTION / TEST UNIT READY for
|
||||
USB and ATAPI, PxSSTS for AHCI, namespace-change AER for NVMe) and
|
||||
consumed by the volume manager, which runs the SAME kill-retire-remount
|
||||
path it runs on channel death — one lifecycle, two triggers. The driver
|
||||
reports presence, never content; a pushed event carries no capability,
|
||||
which the kernel already guarantees. The device staying while its medium
|
||||
leaves is the one removable-media case the channel-death trigger cannot
|
||||
see; without this event a swapped SD card would be served with the old
|
||||
card's filesystem state.
|
||||
|
||||
Reference in New Issue
Block a user