raid56 write-hole crash harness

Stage 0 of the btrfs raid56 write-hole allocator project: a reproducer that must demonstrate the write hole on a stock kernel (red) before any allocator patch is trusted to make it go green.

Method

Each raid5 member is a dm-log-writes target over a loop device, so every write to every member (from mkfs onward) is recorded. The workload runs N committed phases -- create small files, delete a fraction of the previous phase's files, occasional fsyncs -- with btrfs filesystem sync and a per-member log mark after each phase. Phase N+1 exists only to provide post-mark write entries.

No crash timing is needed at run time: tearing is synthesized at replay time. For each case, every member's log is replayed up to the cut-phase mark, then (for armed cases) a different pseudo-random number of extra entries per member -- a torn multi-device write. One member's image is then withheld and the rest are mounted -o degraded,ro; verify.py reads every committed file and compares sha256 against the manifest.

Expectations:

case expectation
tail=any, drop=none clean (cow+csums survive torn writes undegraded)
tail=clean, drop=any clean (consistent image minus one device)
tail=seed, drop=i stock kernel: committed-file damage = write hole

Control failures indicate a harness or baseline bug and invalidate the run. eio on committed files is csum-detected loss; mismatch is silent corruption (worse). Files fsynced during the torn phase are tracked separately (verify.py --report-fsync): under the project's amended log-tree spec they may be lost after crash+degraded, but only detectably.

Usage (as root, in a VM)

./setup-replay-log.sh          # build replay-log from ~/share/xfstests
./run-workload.sh              # build array, run phases, save logs
./replay-matrix.sh             # replay cut x tail x drop, verify, report

Results: /var/tmp/raid56-wh/results.csv plus per-case verify JSON.

Tunables (env): WH_NDEV (4), WH_DEV_SIZE_MB (2048), WH_PHASES (3), WH_TAILS (3), WH_TAIL_MAX (64), WH_SEED, WH_WORKDIR (/var/tmp/raid56-wh -- keep it off the slow share), WH_DATA_PROFILE (raid5), WH_META_PROFILE (raid1), WH_XFSTESTS (~/share/xfstests).

Requires: dm-log-writes (CONFIG_DM_LOG_WRITES), loop, btrfs-progs, python3, cc. Disk: sparse images, ~a few GB actually written per run.

Notes