Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Filesystem stance

Thin VFS with two backends and prefix mounts. memfs (A6 / ADR-027) is in-RAM named buffers. FAT16 on virtio-blk (A7 / ADR-028) is an on-disk volume; write depth is ADR-050; multi-cluster grow is ADR-064; root listing is ADR-056; root delete is ADR-057; root mkdir is ADR-073; nested mkdir + empty rmdir is ADR-077; EL0 fs_mkdir is ADR-075. Path prefixes route through a mount table (ADR-058). Same vfs::open / read / write / close (+ readdir / unlink / mkdir / rmdir for FAT). No POSIX mount / getdents / unlink / rmdir, no FAT32, no xv6-like inode FS. Linux VFS objects vs this thin surface: ADR-034 (Track B B5). Not claiming a Linux filesystem.

Do not say “ctos has files” as if it were a Linux volume. Do not mint a new FR/NFR ID in chat. Frozen Out list already names POSIX / userspace as later (fr-nfr.md). Hub: overview.md. Samples that do run: apps-today.md.

Site source of truth: Filesystem. This page is extra stance. HTTPS at https://ctos.artof.link is Verified (2026-09-11 after #30).

Order

Each step is one milestone → one branch → one PR.

StepWhat it isWhy this orderStatus
1. memfsIn-RAM named buffers on the first-fit heap (src/heap.rs). Create / lookup / read / write of a path without DMA.Same “easiest in-tree” shape as a coop EL1 task.Verified (A6 / ADR-027). Serial fs: ok.
2. virtio-blkQEMU virt virtio-mmio block: virtqueues, DMA, sector R/W.Host -drive is not a probe.Verified when the ledger has blk: ok (A7 / ADR-028).
3. FAT16Host-visible 4 MiB raw image; guest opens /probe (PROBE) and reads fat-hi. Same volume also stores freestanding samples /hello (A9), /fsdemo (ADR-059), /fatdemo (ADR-061), /yldemo (ADR-062), /netdemo (ADR-068), /udpdemo (ADR-071), /mkdemo (ADR-075).Chosen over xv6-like so the host can inspect the image (scripts/mkfat16.py --check). FAT32 / xv6 rejected this mile.Verified when the ledger has fat: ok. Write depth: ADR-050. Multi-cluster grow: ADR-064. Root listing: ADR-056. Root delete: ADR-057. Sample paths are catalog slots, not a second FS.
4. Prefix mountsMount table routes /mem (+ A6 names) → memfs and / → FAT16.Product-depth virtual mounts without a new disk format.Verified when the ledger has vfs: mounts (ADR-058). Not mount(2).

fs: create / fs: write / fs: read / fs: el0 / fs: ok stay fail-closed. A7 adds blk: virtio / blk: cap / blk: rw / blk: ok and fat: mount / fat: read / fat: ok. ADR-050 adds fat: write / fat: rewrite / fat: create. ADR-064 adds fat: grow. ADR-056 adds fat: readdir / fat: entries. ADR-057 adds fat: delete. ADR-073 adds fat: mkdir. ADR-077 adds fat: nested / fat: rmdir. ADR-075 adds EL0 fs_mkdir / libctos: mkdir-ok / mkdemo: ok. ADR-058 adds vfs: mount / vfs: mounts.

QEMU flags (smoke + cargo runner):

-drive if=none,file=target/fat16.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0

What this is not

  • Not POSIX open / stat / mount. Handles are a thin VFS fd, not a Linux fd table (building-or-porting.md).
  • Not virtio-net, 9p, or a Linux rootfs.
  • Not “we have a disk because QEMU can attach one.” Host -drive without guest virtio + a VFS read is not a probe.
  • Not POSIX writeable volumes. Guest FAT write is a thin-VFS depth mile (ADR-050); multi-cluster grow is ADR-064; say “wrote / grew FAT16 bytes” when markers pass. Not a POSIX write API.
  • Not POSIX getdents / opendir. Guest FAT root listing is a thin-VFS depth mile (ADR-056); say “listed FAT16 root entries” when markers pass.
  • Not POSIX unlink / remove. Guest FAT root delete is a thin-VFS depth mile (ADR-057); say “deleted a FAT16 directory entry” when markers pass.
  • Not POSIX mount(2) / Linux vfsmount. Prefix mounts are a thin-VFS depth mile (ADR-058); say “routed path prefixes through a mount table” when markers pass.
  • Not app hosting. A8 is documented sample rebuild recipes (what-can-run.md).

Honesty

ClaimProbeStatus
memfs create/write/read/closeSerial fs: ok + #[test_case]Verified (A6; honesty ledger)
virtio-blk worksSerial blk: ok + sector R/W #[test_case]Verified on this tip when the ledger has the probe
FAT16 on that deviceSerial fat: ok; VFS /probe = fat-hiVerified on this tip when the ledger has the probe
FAT16 write + small createSerial fat: write / fat: create; host --check-writeVerified on this tip when the ledger has the probe (ADR-050)
FAT16 multi-cluster growSerial fat: grow / libctos: fat-growVerified on this tip when the ledger has the probe (ADR-064)
FAT16 root mkdirSerial fat: mkdirVerified on this tip when the ledger has the probe (ADR-073)
EL0 fs_mkdirSerial libctos: mkdir-ok / mkdemo: okVerified on this tip when the ledger has the probe (ADR-075)
FAT16 nested mkdir + empty rmdirSerial fat: nested / fat: rmdirVerified on this tip when the ledger has the probe (ADR-077)
FAT16 root readdirSerial fat: readdir / fat: entriesVerified on this tip when the ledger has the probe (ADR-056)
FAT16 root deleteSerial fat: deleteVerified on this tip when the ledger has the probe (ADR-057)
Thin VFS prefix mountsSerial vfs: mount / vfs: mountsVerified on this tip when the ledger has the probe (ADR-058)

Unprobed stays Unknown. File presence is not that probe. See the honesty ledger.