mirror of
https://github.com/freemkv/libfreemkv.git
synced 2026-10-07 18:13:10 +00:00
Complements the wedge-skip backstop (fbdb50c) with proactive avoidance so we don't HIT the wedge in the first place. User's take after seeing the Dune Pt 2 rip wedge at 48%: 'we shouldn't be wedging.' Empirical observations from the 23:09:12-23:09:55 wedge timeline: 5 read errors over 43 s, ~8 s apart (drive's own ECC recovery takes 5-10 s per failure). Not 'hammering' in any usual sense, but cumulative firmware-state buildup over 5 in-cluster errors was enough to tip the BU40N into wedge mode at the 5th error. Damage cluster spanned ~140 MB (LBAs 19.898M-19.965M). Current damage-jump base of 256 sectors × batch=32 = 16 MB first jump, doubling to 32 MB, 64 MB... Each jump landed BACK INSIDE the 140 MB cluster, exposing the drive to MORE in-cluster errors. Two avoidance levers: 1. Inter-error pause on Pass 1 (PASS_1_FAIL_PAUSE_SECS = 5 s): pre-fix Pass 1 ran pause_secs=0 on all errors to 'zoom past' damage zones. Successful reads still zoom at zero pause — the pause applies only to FAILED reads, giving the drive's firmware cool-down between cluster exposures. Cost: ~5 s per scattered failure (~30-60 s total on a damage cluster); trivial vs. crashing the rip at 48%. 2. Larger damage-jump base (JUMP_BASE_SECTORS = 1024, up from 256): first jump at batch=32 now covers 64 MB instead of 16 MB, second jump 128 MB instead of 32 MB. Two jumps clear 192 MB — well past most single-cluster damage patterns. Smaller jumps were landing inside the cluster and adding to the wedge counter. Plus a halt-aware sleep helper (sleep_secs_or_halt) so the new inter-error pause doesn't degrade halt response time. Halt poll granularity 100 ms — halt fires within ~100 ms regardless of remaining pause time. Updated three sleep call sites in disc/mod.rs (SkipBlock pause, JumpAhead post-pause, Retry pause). The wedge-SKIP backstop (fbdb50c) stays — combined with this avoidance work, the flow becomes: damage cluster encountered → pause 5 s, mark NonTrimmed → second failure → pause 5 s, mark NonTrimmed → ... threshold hit → damage-jump 64 MB (clears 95% of clusters) → if jump lands in another cluster: 128 MB next jump → only if drive STILL wedges after all this: wedge-skip kicks in (1 GB jump + 30 s cooldown × 16 budget) Tests: pass_1_pauses_briefly_on_skip_for_wedge_avoidance — locks the new 5 s pause behavior in place (replaces the old pause=0 test). integration test threshold bumped from 5 s to 60 s with comment explaining the new bound is 'not infinite' rather than 'milliseconds-fast'. All 433+ tests green on cargo +1.86 fmt + clippy + test. Precommit green.