filesystem(7)
MILESTONE-QUALIFIED
Rendered from the page's mdoc source at milestone/general-usability-qemu-20260927 (platform ff025b1)
with GNU groff version 1.23.0, using the same command the image build uses; an ABSD session running
man 7 filesystem prints this text. It is dated 2026-09-27; the build commands and
repository files it mentions are in private sources, and later work is not in it.
All pages.
FILESYSTEM(7) Miscellaneous Information Manual FILESYSTEM(7) NAME filesystem -- the ABSD filesystem and its file server DESCRIPTION ABSD has one filesystem, on the second half of its one disk. The kernel knows nothing of files: it gives out a block device handle. In the qualified boot exactly one process, the file server absd-fsd, holds the only read-write handle to the disk, and every other process reaches files through it, over a channel: a pair of kernel pipes to the server. Nothing else links the filesystem code over a writable disk; two writers would corrupt it. Channels are the authority The server keeps, for each channel, a mount list (subtrees, each read- only or read-write) and a table of the files opened through it. A channel is therefore a capability: holding it is what lets a process see files, and it sees exactly what the mount list allows. Paths are resolved by the server, lexically, under the channel's mount list: `..' cannot leave it, anything outside it does not exist for the client ("ABSD path not found"), a read-only mount refuses every change ("ABSD filesystem is mounted read-only"), and the directories leading to a mount point list only the way down. There are no symbolic links, so resolution is exact. The SSH server binds each session's channel to: /home/operator read-write /tmp/session-N read-write, this session only /bin read-only /etc read-only /share read-only /var/log read-only No session's channel may include /ssh; only the SSH server's own control channel reads it. That channel sees /ssh, /bin, and /etc read- only and /var/log read-write, where the SSH server writes its log; the file server writes its own log into the filesystem directly. A process can ask the server to bind a spare channel for a child with its own mounts or fewer, never more; see handles(7). When a session ends its channel is released: whatever the session left running is refused from then on. Objects Files and directories, nothing else. There are no owners, groups, permission bits, timestamps, symbolic or hard links, device nodes, or sparse files. In particular no modification time is recorded, so `ls -l' shows none; the format has no field for one, and adding it is a format change. An object has one flag, read-only (no command sets it yet), and an identity: the filesystem's random id and an object serial that is never reused. The stat command prints them. One namespace for every session The server runs each request to completion before the next, from whatever channel, so every session sees the same files at every moment. Writes land in arrival order, each one whole; where two cover the same bytes the later wins. Creating a file that must not exist has exactly one winner. A rename replaces its target atomically. Locks are advisory, per open file, shared by every channel, and never wait: a contended lock is refused at once. A sequence of requests (look, then create) is not atomic against another session's. Commits A commit writes the whole metadata image to the half of the metadata area not in use, flushes the disk, writes the superblock that selects it, and flushes again. That superblock write is the moment the change becomes durable. Creating, removing, and renaming (files and directories) are committed before the request returns. File data is committed when the file is closed, when sync is run, when the session ends, and at most about 200 ms after a write that was not otherwise committed. sync returns once everything the server has accepted, from every session, is committed and flushed; `sync -v' prints the commit sequence then on the disk, and df shows it too. What survives a crash Two failure models are qualified. First, the machine stops abruptly (QEMU killed, or the kernel's stop) and every sector the disk acknowledged is kept. Second, a device law for power loss: any write not covered by a completed flush may be lost or reordered, per aligned 512-byte or 4 KiB unit. The second was enforced by a model of the device on the host and in the guest; no real power was cut and no real drive's flush was tested. Under either model, after a crash the namespace is the one of the last commit: a rename is never half done, and a committed file is whole. Data written but not yet committed may be partly present or absent. File contents carry no checksum: corruption of file data on the disk is not detected. Refusal and recovery Mounting checks both superblocks, the digest of the selected metadata image, and every structural rule of the namespace. Anything wrong refuses the mount. The mount never repairs and never falls back to the older superblock. A disk that is entirely zero is formatted at first boot; so is a filesystem whose format was interrupted before its first commit. Any other disk without an ABSD layout is refused. In the qualified boot a refused mount, or a disk error while committing, ends the file server (`FSD FAILED ...' on the serial console), and with it the boot. There is no on-target repair tool, no fsck, and no rescue boot. The platform's host-side reader (scripts/absd_fs.py) reads an image the mount would accept; it is a test tool, not a recovery procedure. SEE ALSO absd-sh(1), handles(7), process(7), afterboot(8) In the platform repository: docs/FILESYSTEM.md (format 1 and its operation contract) and docs/POWER-LOSS.md (the device law). A refused filesystem cannot be repaired on ABSD or on the host; the only procedure is to build a new image (afterboot(8)), copying files out first, while the old one still boots, with `ssh host cat FILE'. CAVEATS The format is experimental, with no compatibility promise: a format change means a new filesystem. Every commit writes the whole metadata image, so its cost grows with the number of objects, and the number of objects is bounded by a 64 KiB record budget ("storage full"). df counts data blocks only. There are no quotas: every session shares the space. ABSD September 27, 2026 FILESYSTEM(7)