audit-038: persistent cache:/* VFS via host-FS backing
Replaces the "Synthesized empty file" stub for cache:/* paths with a
real host-FS HostPathDevice-style mount. Each KernelState gets a fresh
per-process tmpdir under /tmp/xenia-rs-cache-<pid>-<id>/ which is
cleared on init for lockstep determinism (mirrors canary's
xenia_main.cc:649 RegisterSymbolicLink("cache:", "\\CACHE") +
HostPathDevice in xenia-canary/src/xenia/vfs/devices/host_path_device.cc).
NtCreateFile now honours create_disposition for cache: paths:
FILE_OPEN -> NOT_FOUND if missing
FILE_CREATE -> NAME_COLLISION if present
FILE_OPEN_IF -> open or create
FILE_OVERWRITE_IF -> create or truncate
FILE_OVERWRITE -> NOT_FOUND if missing, else truncate
FILE_SUPERSEDE -> create or truncate
NtReadFile / NtWriteFile / NtSetInformationFile (XFileEndOfFileInformation)
/ NtQueryInformationFile / NtQueryFullAttributesFile route through
std::fs against the per-handle host_path; non-cache paths keep their
legacy semantics (read-only disc image, synth-empty stubs).
Verified by audit-037 cascade:
- sub_82459D18 (cache-miss restore): 0 fires (was firing constantly)
- sub_8245D230 (resize/zero-fill): 0 fires (was firing constantly)
- 105+ real cache-file writes per 500M run; 4+ MB of game data persisting
to disk per boot; cache:/recent, cache:/access, cache:/d4ea*.tmp, etc.
- Lockstep deterministic at instructions=100000004 / imports=987485
across 3+ reruns (digest shifted as expected; goldens re-baselined).
- swaps=2 plateau still in place; cluster L1 unactivated. Cascade
dimension D (cluster activation) — UNKNOWN, no L1 fires.
Tests 640 -> 645 (+5 cache-specific unit tests; full workspace green).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
//! Kernel object tracking for HLE.
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use xenia_cpu::ThreadRef;
|
||||
@@ -41,6 +42,15 @@ pub enum KernelObject {
|
||||
/// to emit. Reset to `Some(0)` when the guest passes
|
||||
/// `restart_scan=1`. Unused on non-directory files.
|
||||
dir_enum_pos: Option<usize>,
|
||||
/// AUDIT-038 — when `Some`, this file is backed by a real host-FS
|
||||
/// path (the cache: persistent VFS) rather than the in-memory
|
||||
/// `data` buffer. NtReadFile / NtWriteFile / NtSetInformationFile
|
||||
/// route through `std::fs` against this path. Mirrors canary's
|
||||
/// `HostPathDevice` (xenia-canary/src/xenia/vfs/devices/
|
||||
/// host_path_device.cc) which symlinks `cache:` → `\CACHE`.
|
||||
/// `None` for disc-VFS reads, root-of-device opens, and synth
|
||||
/// stubs (those keep the in-memory zero-byte semantics).
|
||||
host_path: Option<PathBuf>,
|
||||
},
|
||||
Thread {
|
||||
id: u32,
|
||||
|
||||
Reference in New Issue
Block a user