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.
This commit is contained in:
@@ -19,7 +19,12 @@ const protocol = @import("vfs-protocol");
|
||||
pub const Kind = protocol.NodeKind;
|
||||
|
||||
/// A node's metadata (the answer to a status request).
|
||||
pub const Attributes = struct { size: u64, kind: Kind };
|
||||
pub const Attributes = struct {
|
||||
size: u64,
|
||||
kind: Kind,
|
||||
/// Modification time — Unix epoch seconds, UTC. 0 if the filesystem has none.
|
||||
mtime: u64 = 0,
|
||||
};
|
||||
|
||||
// Map a wire `NodeKind` value to the enum, defaulting anything unrecognised to
|
||||
// `.regular` (the server is trusted, but a value outside the enum would be
|
||||
@@ -138,7 +143,7 @@ pub const File = struct {
|
||||
const r = transact(request, &.{}, &buffer) orelse return null;
|
||||
if (r.reply.status != 0 or r.payload.len < @sizeOf(protocol.FileStatus)) return null;
|
||||
const status = std.mem.bytesToValue(protocol.FileStatus, buffer[0..@sizeOf(protocol.FileStatus)]);
|
||||
return .{ .size = status.size, .kind = kindFromWire(status.kind) };
|
||||
return .{ .size = status.size, .kind = kindFromWire(status.kind), .mtime = status.mtime };
|
||||
}
|
||||
|
||||
/// Release the VFS's open handle for this file.
|
||||
|
||||
Reference in New Issue
Block a user