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.
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.
./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.
rescue=nologreplay when a torn tail leaves a
log tree that a ro mount refuses; the case record notes this.WH_TAILS, WH_TAIL_MAX, more phases/files) -- the tear must land on
a stripe whose other extents are committed and whose reconstruction is
actually exercised by the dropped device choice.