raid56 stripe_alloc — test catalog and revalidation guide

Everything we have run against the stripe-exclusive-allocation (stripe_alloc) series and its supporting fixes, from single-purpose forensic probes to multi-day soak tests, with where each test lives and what it proved. Companion driver: run-rebase-validation.sh (this directory) re-runs the regression-relevant subset after a rebase onto a new upstream revision.

Environments: two test VMs (bhive, dhive), root ssh, kernels built in /mnt/linux/linux on the VM (bhive's tree is the build master), SUT booted via grub-reboot with the full menuentry title ("kernel-only vmlinuz (no initramfs, dm-mod.create root)"). This harness repo is canonical and is deployed to the VMs by git push or rsync; ~/share/raid56-hang-debug/ (the hang/soak kit, not in git) is deployed with rsync to /root/raid56-hang-debug. Push files to VMs with rsync only (atomic rename), never scp/cp.

1. Crash consistency: logged-write replay (Stage 0)

The foundation: every member of a raid5 array is a dm-log-writes target, so the write-hole can be synthesized at replay time instead of by crash timing. run-workload.sh runs committed phases (create/delete/fsync mix) with per-member log marks; replay-matrix.sh replays cut × torn-tail × dropped-device combinations, mounts degraded, and verify.py compares every committed file against a sha256 manifest. See README.md for the full method and expectations table.

2. fsync correctness and torn-log forensics

What survives a crash+degraded mount when the fsync log tree itself is torn.

3. Directed write-hole and parity surgery

Deterministic single-stripe demonstrations replacing statistics with surgery.

4. Corruption-under-load (the "b" EIO cluster and friends)

5. Allocator-specific regression tests

Each of these encodes a bug the series had and must not regrow:

6. Octopus validation suite (T1–T13)

run-6.18-validation.sh — the umbrella acceptance suite for the 6.18 backport octopus: 13 tests (read-after-write, no-visible-IO-errors, scrub, balance, fsstress, ENOSPC, compression, kernel health, nodatacow, fsync durability, fsync-heavy log tree, device replace/rebuild, offline check) run under a fault present for the whole run, across three passes (online stripe_alloc, degraded stripe_alloc, stock allocator), looping for a wall-clock budget. Roles: bhive = FAIL (dm-error member, nodatacow included), dhive = CORRUPT (silent drop + rotating garbage, nodatacow excluded). Plan: ~/share/raid56-wh-harness/6.18-octopus-test-plan.md.

Expected outcomes (the spec; see the plan §4, §7, §8). Every stripe_alloc pass (P1 online, P2 degraded) is expected to PASS all 13 rows: a single device fault is inside the redundancy, so the only acceptable app-visible error is the ENOSPC edge in T6. P3 (stock allocator) may fail and is marked FAIL(exp). T9 is SKIP under CORRUPT (nodatacow loss is undetectable there). Anything else is an unexpected failure and stops the loop. Known shapes that are NOT allocator bugs: T6/T12 metadata ENOSPC on this small geometry (Zygo 2026-09-08) — the suite must keep them from happening (meta_buffer chunks; T6 sizes its shrink from what is stored, 2026-09-12) rather than expect them. History: FAIL/P1 T6 aborted the fs in merge_reloc_roots (-28) from 2026-09-07 (cand22 fill change) through 2026-09-12 — the 09-09 fixed 768M target was never run under FAIL/P1 until the misc-next lane run of 2026-09-12 showed it still impossible.

Directed stage statuses. A script exits 77 when the feature it tests is absent from the kernel (e.g. nocow-strand-test.sh needs the wip stranded-stripe counters): reported as SKIPPED, not a failure. A kernel WARNING/BUG/Oops seen while a script runs fails the stage unless the script declares it in directed-expected-warns.txt (script|pattern|why) — only the two legacy-layout repros declare the rate-limited "incremental stripe_claimable above scanned" WARN, which is what they measure.

7. Deadlock hunts and soak tests (~/share/raid56-hang-debug/)

repro-folio-hang.sh — the workload rig used for every hang: 8 LVs (one removed → degraded), optional dm-crypt under btrfs (CRYPT=1, prod-shaped kcryptd bounce-page stack), mount degraded,compress=zstd:3,flushoncommit,stripe_alloc,discard=async; workers: churn writers, deduper, snapshot loop, balance loop, mass rm; heartbeat loop watches commit progress; ENOSPC aborts recycle the fs and continue; a genuine stall trips a capture (SysRq w/l/t, /proc stacks, ftrace ring, drgn probes folio_probe.py/rbio_walk.py). Quiet "light captures" fire during any >90s commit without stopping the hunt. Env: CRYPT=1 MAX=<secs> VMLINUX=<matching vmlinux>. Real log is /root/folio-repro.log (the script re-execs into it).

Bugs found, fixed, and soak-verified with this rig:

Soak verdict as of 2026-08-19: 48+ hours with no new deadlock on either VM or the production canary. Monitoring pattern: 12h watcher windows polling commit progress, WARN classification (known-benign: WARNING: CPU.*__btrfs_free_extent = ENOSPC abort), recycle count, light captures, ffdefer counter; poll hourly and check D-state/progress, not just liveness.

8. Known-benign signatures (do not re-diagnose)

9. Revalidation on a new upstream base

Run ./run-rebase-validation.sh on each VM (see its header). Order: sanity → Stage 0 replay matrix (both crash models) → fsync suite → directed/regression set → octopus suite → soak. Deploy first: build the rebased SUT on bhive's /mnt/linux/linux, install on both VMs (grub full title), rsync this repo and raid56-hang-debug/ to /root/, and keep a matching vmlinux path for drgn (VMLINUX= env, honored since the 2026-08-19 fix).