file-system: extract the serving harness from fat — V1

fat was one binary doing four jobs; the three that are not FAT-specific move
to library/kernel/file-system-harness, a Server(comptime Engine) generic over
the engine type: the badge-scoped open-node table, the nine vfs handlers, the
not-mounted politeness, the exit sweep, mount registration, and durable-on-
close. A filesystem is now an engine plus a main that hands the harness a
mounted volume; a second engine reuses the harness wholesale.

Placement note: the plan said library/file-system, but the harness is a
specialization of `service` (its sibling) and needs nothing from the device
domain, so it lives beside service in library/kernel and stays block-free —
durability rides a caller closure (Volume.flush), no backwards kernel->device
dependency, no new-domain scaffolding. The engine type is inferred from
resolve()'s return, so engine.zig is untouched (its Node stays module-scope).

fat keeps only its FAT-specific bring-up (acquireVolume, DMA, engine.mount,
the attach/detach round trip) and the three mount prefixes as data. Behavior-
neutral: 13/13 across the fat/vfs/logger/IOMMU surface, nothing observable
changed. This lands first so every later phase touches the harness once.
This commit is contained in:
Daniel Samson
2026-08-09 16:55:48 +01:00
parent b59f981c58
commit d63a008148
4 changed files with 409 additions and 318 deletions
+18 -1
View File
@@ -90,7 +90,7 @@ pub fn build(b: *std.Build) void {
// a provider that beat init to the mount needs). It also owns the subscriber
// table and the fan-out, which are expressed in the envelope's vocabulary
// (the reserved subscribe verb, the push floor) — hence envelope.
_ = b.addModule("service", .{
const service = b.addModule("service", .{
.root_source_file = b.path("service.zig"),
.imports = &.{
.{ .name = "channel", .module = channel },
@@ -99,6 +99,23 @@ pub fn build(b: *std.Build) void {
.{ .name = "process", .module = process },
},
});
// The filesystem serving harness (docs/file-system-development/storage-architecture.md):
// the engine-agnostic half of a filesystem service. It specializes `service`
// for the vfs protocol and is block-free (durability rides a caller closure),
// so it needs nothing from the device domain — it sits beside its sibling.
_ = b.addModule("file-system-harness", .{
.root_source_file = b.path("file-system-harness.zig"),
.imports = &.{
.{ .name = "ipc", .module = ipc },
.{ .name = "process", .module = process },
.{ .name = "service", .module = service },
.{ .name = "time", .module = time },
.{ .name = "file-system", .module = file_system },
.{ .name = "envelope", .module = protocol.module("envelope") },
.{ .name = "vfs-protocol", .module = protocol.module("vfs-protocol") },
.{ .name = "logging", .module = logging },
},
});
_ = b.addModule("start", .{
.root_source_file = b.path("start.zig"),
.imports = &.{ .{ .name = "process", .module = process }, .{ .name = "logging", .module = logging } },