volume-manager: removal supersedes a pending restart in the poll

Inline V4 review (the boundary-review workflow stalled): the poll ran a due
fat-restart before the presence check and returned, so a fat death followed
by a device removal would respawn fat against the now-dead channel and churn
until the crash cap before the removal was noticed. Reorder: check the
specific device's presence first (unmount if gone), and only fire a due
restart once the device is confirmed present. Neutral: fat-mount,
volume-removal, amd-iommu-usb-storage green.

Noted V4 limitations (not fixed here, edge cases outside the user unplug
case): a usb-storage DRIVER crash (device stays, driver restarts with a new
endpoint) leaves fat holding a dead channel — the device is still present so
removal is not detected; fat would need to observe its channel death and
exit. Deferred with the medium_changed subscription and multi-volume.
This commit is contained in:
Daniel Samson
2026-08-09 20:27:58 +01:00
parent 5e89b111cf
commit af47d41989
@@ -240,17 +240,21 @@ fn removeVolume() void {
fs_failed = false; fs_failed = false;
} }
/// One poll tick: perform a due restart, else reconcile presence — mount a newly /// One poll tick. Removal is checked FIRST and supersedes a pending restart: if
/// present volume, unmount a departed one. /// the device is gone there is nothing to restart fat onto, and respawning it
/// against the dead channel would just churn until the crash cap. Only once the
/// device is confirmed present does a due restart fire.
fn pollTick() void { fn pollTick() void {
if (restart_pending and time.clock() >= restart_due_ns) {
restart_pending = false;
if (volume) |*v| spawnFilesystem(v);
return;
}
if (volume) |v| { if (volume) |v| {
// Serving: watch for the specific device leaving (a pulled stick). // Serving: watch for the specific device leaving (a pulled stick).
if (!isDevicePresent(v.storage_device_id)) removeVolume(); if (!isDevicePresent(v.storage_device_id)) {
removeVolume();
return;
}
if (restart_pending and time.clock() >= restart_due_ns) {
restart_pending = false;
spawnFilesystem(&volume.?);
}
} else { } else {
// Idle: try to bring a present storage device up. // Idle: try to bring a present storage device up.
bringUpVolume(); bringUpVolume();