Phase 2b: wire mkdir + unlink through the VFS to runtime.fs
The engine gained mkdir/unlink in Phase 2a; this exposes them as first-class filesystem operations so programs can use them. - vfs protocol: two new path-based operations, mkdir and unlink (appended, so existing opcodes/offsets are unchanged). - VFS router: a forwardPath helper relays a path-based op under a mount to its backend; the mkdir/unlink cases forward to the mounted filesystem (the flat ramfs refuses them — it has no directories). - fat server: mkdir -> engine.createDirectory, unlink -> engine.removeFile, each resolving the parent via a shared splitParent helper (also used by open-create). - runtime.fs: makeDirectory(path) and remove(path). - fat-test now exercises the whole path — mkdir /mnt/usb/TESTDIR, create + write + read a file inside it, then remove it — behind a new `fat-mutations` QEMU case. Verified: zig build, zig build test, zig build check-fat-image, and a sequential QEMU sweep — fat-mount, fat-mutations (mkdir/write/read/unlink through the mount), vfs, vfs-client-death, log-flush, orderly-shutdown, initial-ramdisk, smoke — green.
This commit is contained in:
@@ -218,6 +218,25 @@ pub fn openDirectory(path: []const u8) ?Directory {
|
||||
return .{ .node = file.node };
|
||||
}
|
||||
|
||||
// A path-based request that returns only a status (mkdir, unlink).
|
||||
fn pathOperation(operation: protocol.Operation, path: []const u8) bool {
|
||||
const request = protocol.Request{ .operation = operation, .node = 0, .offset = 0, .len = @intCast(path.len), .flags = 0 };
|
||||
const r = transact(request, path, &.{}) orelse return false;
|
||||
return r.reply.status == 0;
|
||||
}
|
||||
|
||||
/// Create a directory at `path` (its parent must already exist). Returns true on
|
||||
/// success. Only works under a mounted filesystem that supports directories.
|
||||
pub fn makeDirectory(path: []const u8) bool {
|
||||
return pathOperation(.mkdir, path);
|
||||
}
|
||||
|
||||
/// Remove the file at `path`. Returns true on success. Directories are refused
|
||||
/// (a separate directory-removal would have to check emptiness).
|
||||
pub fn remove(path: []const u8) bool {
|
||||
return pathOperation(.unlink, path);
|
||||
}
|
||||
|
||||
/// Mount a filesystem backend (its server endpoint) at absolute path `target`;
|
||||
/// the VFS then routes everything under `target` to that backend. This is the one
|
||||
/// call that hands the VFS a capability (the backend endpoint). Returns true on
|
||||
|
||||
Reference in New Issue
Block a user