Two ramdisk fixes exposed by shipping the C++ header tree:
Paths longer than 100 characters (libstdc++'s pb_ds detail headers)
are split by USTAR across the name field and the 155-byte prefix
field at offset 345. The parser only read the name field, so the
tails of 7 deep header paths appeared as bogus root-level entries
while the real paths were missing. The parser now joins
prefix + '/' + name, and MaxNameLen grows to 260 to hold the full
combined path.
SYS_CHDIR validated non-root targets by opening them as files, which
only ever worked because directories used to be openable. It now uses
the ReadDir probe, which fails for nonexistent paths and regular
files on all backends (ext2/fat32 already validate the inode type).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SYS_OPEN succeeded on directory tar entries, so userspace stat() -
which tries open-as-file first - reported every directory as a
regular file. GCC's include-path setup stats each search directory
and rejected all the real ones with "not a directory" warnings.
Directories now fall through Open to -1 and stat() classifies them
via the (recently fixed) ReadDir existence probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ReadDirAt returned 0 (empty listing) for paths that do not exist at
all, so the libc's stat()/access() - which probe directory-ness via
SYS_READDIR - reported every nonexistent path as an existing
directory. Harmless for two years of callers, fatal for GCC's driver:
it access()-tests the optional specs file, got a false positive for
0:/sdk/lib/gcc/x86_64-montauk/14.2.0/specs, then died failing to read
it.
A path now has to have a directory entry or at least one child to
list as a directory; everything else returns -1. Real empty
directories (tar dir entries, runtime Mkdir) still list as empty.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 0:/usr devkit pushed the base image to ~650 files, past the
ramdisk's MaxFiles = 512. The USTAR loader silently dropped the tail
of the archive and, worse, every runtime Create/Mkdir failed once the
table was full - so first-boot account creation could not write the
user database and every login failed with "invalid username or
password".
Raise MaxFiles to 2048 (256 KiB static table) and log loudly both
when archive entries are dropped at load and when Create/Mkdir hit
the cap, so a full table can never masquerade as an auth failure
again.
Verified in QEMU end to end: setup -> create account -> log in ->
desktop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deleting a big file froze the desktop for seconds: ext2 FreeBlock did 4
synchronous disk I/Os per data block (bitmap + BGDT read/write), and the
file manager deleted single files inline on the desktop main thread.
- Ext2: batch block frees per block group; keep the bitmap resident,
clear bits in memory, flush bitmap + BGDT once per group transition.
Also covers the truncate-on-overwrite path.
- Ext2: refuse to mount volumes with block size > 4096; temp buffers
throughout the driver are single 4 KiB pages, so larger blocks would
overflow them (our mkfs always uses 4K).
- Files: route single-file deletes past 4 MiB to the background worker
+ progress dialog; refuse (instead of stalling inline) when another
file operation already owns the worker.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>