Files
MechaCat02 e645d78a6e fix(disk): the free-space cache stopped caching once a second volume was asked about
`DiskCache` held ONE slot carrying its own key, so a lookup for a different path
was a miss that OVERWROTE the previous reading. The app asks about two paths that
are distinct mounts in production: `MEDIA_PATH=/media` and `EXPORT_PATH=/exports`.

  * the upload gate and the per-user quota ask about the media volume on EVERY
    photo (`handlers::upload`);
  * `host::get_event_status` asks about the exports volume on every host
    dashboard load.

So while a host had the dashboard open the two evicted each other and the hit
rate collapsed to zero, putting an uncached
`sysinfo::Disks::new_with_refreshed_list()` — a synchronous scan of every mount,
on the async runtime — back on the busiest write path in the app. That is
precisely the cost `handlers::upload`'s own comment says this cache exists to
avoid, on the 2-vCPU box it says it matters on, and it degrades hardest exactly
when a host is watching the disk because uploads are failing.

Correctness was never affected — the slot carried its key, so it never returned
the WRONG filesystem's numbers. It missed and re-measured instead, which is the
quieter failure and the one that cost.

Now one entry per path. The key space cannot grow: both paths come from
`AppConfig`, never from request input. `invalidate` clears ALL volumes, since the
e2e TRUNCATE moves free space on every one of them and a survivor would let the
next test compute against the previous test's disk.

Three tests. The one that matters most is `a_stale_entry_is_refreshed_without_
deadlocking`: the hit check holds a READ guard and an expired entry falls through
to a WRITE guard on the same non-reentrant `RwLock`, so whether they overlap
depends on when the `if let` scrutinee's temporary is dropped — edition 2024
drops it before the fall-through, the 2021 rules did not. Too subtle to leave to
a reading of the edition, so it is pinned; it HANGS rather than fails if that
ever regresses.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 17:54:11 +02:00
..