fat: long-file-name creation, fast cluster allocation, makePath
createFile/createDirectory now build long-name chains: a mangled STEM~N 8.3 alias (collision-checked per directory), the standard rotate-add checksum, and 13-UCS-2-per-entry pieces written last-logical-first into a contiguous free-slot run (found sector-wise, growing the directory as today). Write order is chain first, 8.3 entry last, so an interrupted create leaves only skippable orphans. Uppercase-compliant 8.3 names keep the bare-entry fast path; lowercase names now get a chain so their exact case survives — matching tools/make-fat-image.py. rename stays 8.3-only (documented; nothing needs more yet). allocateCluster drops its from-cluster-2 rescan (measured ~1 s/cluster on a part-full volume, a 37 s shutdown flush in the lost M19 build): a next-free hint (rewound by frees) plus a FAT-sector LBA cache turn the scan into one device read per FAT sector. mkdir now refuses an existing name (no duplicate entries), and runtime.fs gains makePath (mkdir -p) for the logger's nested per-boot directories. Engine tests cover the log-directory shape, ~N collisions, chain unlink/reuse, the 8.3 fast path, and the checksum.
This commit is contained in:
@@ -236,6 +236,22 @@ pub fn makeDirectory(path: []const u8) bool {
|
||||
return pathOperation(.mkdir, path);
|
||||
}
|
||||
|
||||
/// Create every missing directory along `path` (mkdir -p). Probes each prefix
|
||||
/// with `exists` first — a FAT mkdir of an existing name is refused, and the
|
||||
/// probe keeps the common "already there" case cheap. Returns true when the
|
||||
/// whole path exists afterwards.
|
||||
pub fn makePath(path: []const u8) bool {
|
||||
var end: usize = 0;
|
||||
while (end < path.len) {
|
||||
end += 1;
|
||||
while (end < path.len and path[end] != '/') end += 1;
|
||||
const prefix = path[0..end];
|
||||
if (prefix.len == 0 or (prefix.len == 1 and prefix[0] == '/')) continue;
|
||||
if (!exists(prefix) and !makeDirectory(prefix)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
|
||||
Reference in New Issue
Block a user