Commit Graph

2 Commits

Author SHA1 Message Date
Daniel Samson 67702fa250
Phase 2d (ii): filesystem modification time (mtime)
Completes Phase 2: the FAT filesystem now stamps and reports a real modification
time, built on the Phase 2d(i) kernel wall-clock. This is the last stat field the
compiler's build cache needs to reason about (source vs cached output).

- on-disk.zig: fatToEpoch / epochToFatDateTime convert between the two 16-bit DOS
  date/time fields and Unix epoch seconds (UTC — FAT has no timezone). Host-tested
  round-trip + an absolute check (1577836800 == 2020-01-01).
- engine: a settable current_time_epoch that create/write stamp into the entry's
  write (and creation) date/time; Node/Listing gained an mtime decoded from those
  fields on read. Host test: a create stamps the mtime, read back through resolve
  and listEntry.
- vfs protocol FileStatus + runtime.fs.Attributes gained an mtime field; the fat
  server sets current_time_epoch from runtime.system.wallClock() per request and
  returns mtime from stat. The flat ramfs reports 0 (it has no timestamps).
- fat-test reads the created file's mtime through stat and checks it is a real
  current time, behind a new `fat-mtime` QEMU case.

Verified against the host: the guest stamped mtime 1783971676 while the host clock
was 1783971680 (boot+test lag) — the file's mtime is real current time. zig build,
zig build test (the epoch<->DOS conversions + the engine mtime test),
zig build check-fat-image, and a sequential QEMU sweep — fat-mount, fat-mutations,
fat-rename, fat-mtime, vfs, vfs-client-death, log-flush, orderly-shutdown,
initial-ramdisk, smoke, wall-clock, usb-storage — all green. mode/inode remain.
2026-07-13 20:43:40 +01:00
Daniel Samson a64a01a6a9
M6: FAT read/write filesystem server, mounted into the VFS
Add a FAT12/16/32 filesystem the VFS mounts at /mnt/usb, reading and writing a
USB stick through the block device. Verified end to end under QEMU: the fat
server mounts the volume, the VFS routes /mnt/usb to it, and a client lists the
root and reads a file (the ELF magic of /mnt/usb/system/kernel).

- engine.zig: the FAT engine over a BlockDevice interface — mount (a bare FAT or,
  as QEMU's VVFAT and most real sticks present it, an MBR-partitioned disk), FAT
  chain walk (12/16/32), cluster allocation, directory traversal with long-name
  read, and file read / write / create. Host-tested against a RAM-backed FAT16
  image (create, cluster-spanning write, mid-file overwrite, read-back, list).
- on-disk.zig: the align(1) boot-sector / directory / long-name / FSInfo structs
  and the cluster-count FAT-type detection.
- fat.zig: the server — wraps the .block device (a DMA bounce buffer) in a
  BlockDevice, mounts the FAT, serves the vfs-protocol as a backend, and mounts
  itself into the VFS at /mnt/usb. Spawned by init as a boot service.
- runtime.block: the block-device client (geometry / read / write by physical
  address, so whole sectors never cross IPC).
- Raise the kernel service-name registry (maximum_services) 8 -> 16: it is
  indexed directly by ServiceId, and fat = 8 was being rejected, so the fat
  server exited before registering.
- VFS: an absolute path with no matching mount is now not-found rather than
  silently created in the flat ramfs — so /mnt/usb fails cleanly until mounted.

Tests: fat-mount (the full stack: block -> FAT -> VFS mount -> list + file read)
passes; host units cover the engine and on-disk structs; the vfs, shutdown, and
USB regression suite stays green (10/10).
2026-07-13 15:05:53 +01:00