xv6 §10, "File system". "The purpose of a file system is to organize and store data."
Phase 10 gives Glint storage of its own, and a way to use storage that only
Linux can drive, through the pass-through and return paths described in the
plan's Devices and the Linux guest. Everything above the block layer
treats every BLOCK_IO provider the same way, whether it is firmware
(hosted mode), a Zephyr driver, or a device served back by the Linux guest.
That is the plan's one interface, swappable providers principle applied to
disks. The phase starts from Phase 9's vsock channel and event-driven
virtio, and from the virtio-blk device for guests (6.6) and the Zephyr block
provider (6.10). It leaves Phase 11 a writable FAT file system to keep a log
on. Slices run bottom-up, as xv6 builds its file system. Each layer is added
only once the layer beneath it exists, so a reader can follow the stack one
level at a time.
Provisional slices. Each is refined, with its quoted sentence, when the phase starts.
Slices
10.1 The block layer. This slice defines Glint's own BLOCK_IO-shaped
interface. That is a small Crystal module with read-blocks, write-blocks and
flush operations. The in-memory disk from 6.6 and the Zephyr virtio-blk
provider from 6.10 are placed behind it, and in hosted mode the firmware's
own BLOCK_IO protocol is wrapped as one more provider behind it. It opens
the phase because the buffer cache (10.2) and the FAT reader (10.3) must sit
on one interface, not on two different providers. Hailperin §8.8 gives the
principle: "the ability of multiple forms of objects to be treated in a
uniform manner". The slice serves Loose Coupling: everything above it can
use any provider, including the one Linux serves back in 10.7, without
changing.
10.2 A buffer cache. This slice adds a buffer cache above 10.1's interface. It is a fixed set of block-sized buffers that keeps exactly one copy of each disk block in memory, keeps the most recently used blocks there, and writes dirty blocks back through 10.1. It follows 10.1 because a cache needs one interface to cache from, and it comes before 10.3 so that the file system's repeated reads of directory and allocation-table blocks are served from memory rather than refetched. Its passages are xv6 §10.2–10.3 ("Buffer cache layer", "Code: Buffer cache") and MOS4/5 §4.4.4. Holding exactly one copy of each block is the plan's Parsimony test that each thing appears only once. It is also what keeps two writers from diverging on the same block.
10.3 Reading FAT. This slice adds a kernel reader for FAT, the file
system on the EFI system partition (ESP) where Glint's own images live. It
can walk directories, follow cluster chains and read files. It reads through
10.2's cache, which is why it comes after 10.2. MOS4/5 §4.5.1 describes the
format. The reader is ordinary host-testable Crystal (plan principle 3).
Specs check it against ESP images written on the host by Cleave::Fat16,
the same tool Track T and slice 2.1 use to build boot images. Checking one
implementation against another written independently is Demonstrability.
10.4 Writing FAT. This slice extends 10.3's reader with file create,
write and delete on the ESP, updating directory entries and the file
allocation table through 10.2's cache. It exists now because Phase 11's
write-ahead log, and the state it protects, are files on the ESP, so Glint
needs a writable file system before it can keep anything across a reboot. It
also has to come before 10.5, which stores guest disks as files. Specs write
files and confirm the result with Cleave::Fat16's reader on the host
(Demonstrability). The slice adds only the write operations those two users
need, not general file-system features, which is Parsimony.
10.5 Guest disks as files. This slice lets the virtio-blk device that guests have had since 6.6 be backed by a file on the ESP instead of an in-memory image. Guest disks then persist across reboots and can be copied or replaced like any file. MOS4/5 §7.7 treats a guest disk as a file or region on the real disk. It needs 10.4, because the disk file must be created and written before a guest can use it. The guest sees no change: only the provider behind the virtio-blk device differs. That is Loose Coupling between what a guest is offered and how Glint stores it.
10.6 Passing a device to Linux. This slice hands one device to the Linux guest: a devicetree node, its MMIO range and its interrupt. Linux's own driver runs it as if it were native, while Glint still governs the guest's memory map and interrupts. This is the first of the device paths in the plan's Devices and the Linux guest. On QEMU, a second virtio-blk device stands in for a device only Linux can drive. It comes after 10.5 because Glint's own storage path must be complete before a second path, through Linux, is added. Every pass-through is checked against the threat model (2.8). Where no IOMMU guards the device, Glint refuses the pass-through unless the guest is explicitly marked as trusted for unprotected DMA, and it logs the opt-in. Making that trust a stated, visible choice is Clarity.
10.7 Linux serves it back, simply. This slice lets Glint use the device from 10.6 through the Linux guest, carrying a simple block protocol (NBD, the Network Block Device protocol) over the vsock channel from 9.5 to a small daemon inside Linux. It is the driver-domain arrangement MOS4/5 §7.7 describes under Device Domains, as in Xen's domain 0. The device appears to Glint as one more provider behind 10.1's interface. It comes after 10.6 because it needs that hand-off, and it uses vsock first because vsock already exists and the protocol is easy to check. Glint's file code cannot tell that the disk is driven by Linux, which is Loose Coupling.
10.8 Linux serves it back, fast. This slice replaces 10.7's protocol with a virtio device served from inside Linux (a vhost-user style back end sharing a virtqueue with Glint), so block requests cross between guest and Glint without a copy through a socket. It comes last because 10.7 already proves the path end to end, so 10.8 can be measured against it. The plan asks for the performance cost of using Linux to be kept small, and the benchmark against 10.7 and against a native provider is that slice's Demonstrability.
Phase demo: Linux's disk is a file on the ESP, and Glint reads a disk that only the Linux guest drives.
References
- xv6 §10: "The purpose of a file system is to organize and store data"; §10.2 "Buffer cache layer".
- Hailperin §8.1 (persistence); §8.4 "Disk Space Allocation"; §8.8
"Polymorphism in File System Implementations": "the ability of multiple
forms of objects to be treated in a uniform manner". This is the same idea
as Glint's swappable
BLOCK_IOproviders. - Tanenbaum: MOS4 §4.3.7 / MOS5 §4.3.8 "Virtual File Systems"; MOS4/5 §4.4.4 "File-System Performance" [block caching]; MOS4/5 §4.5.1 "The MS-DOS File System" [FAT, the format of the EFI system partition].
- Rationale: xv6 builds the layers bottom-up. Hailperin's polymorphism section is the principle behind provider interchangeability (OCX's Loose Coupling).