From: Zygo Blaxell Date: Wed, 16 Sep 2026 13:41:07 +0000 (-0400) Subject: covers: stripe-alloc: raid56-metadata fsync tear concluded -- log-only detectable... X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf4de6dde628d794cabb0bf5095ad106def1faa0;p=linux covers: stripe-alloc: raid56-metadata fsync tear concluded -- log-only detectable loss, committed metadata never harmed The characterization finished (four passes, 162 armed cases): zero committed-data damage, no torn stripe held a committed tree block, and no torn stripe mixed a log block with another tree block of the crashed transaction, so the sharpest form of the hazard did not occur. The degraded replay was refused only in the two cases the scan named; the recovery is ro,degraded,rescue=nologreplay (not zero-log, which needs read-write and cannot open a degraded raid56), and it read the committed set back intact. Guarantee shape and Testing updated with the confirmed numbers and the recovery. Assisted-by: Claude:claude-fable-5-1 --- diff --git a/covers/stripe-alloc.txt b/covers/stripe-alloc.txt index 767d38afeb13d..9b96fdabb605a 100644 --- a/covers/stripe-alloc.txt +++ b/covers/stripe-alloc.txt @@ -630,12 +630,16 @@ that later write's read-modify-write rewrites the parity over blocks fsync N had already made durable; a crash plus a missing device can tear them. Found in review; then measured (Testing below): the loss is the log alone. The degraded mount refuses to replay ("Failed to -recover log tree", -EIO), an operator's btrfs rescue zero-log -discards it, the committed state verifies intact and the degraded -array keeps taking writes. Committed metadata is never touched -(every metadata run drains before the super that commits it), and -the recommended pairing -- raid6 data with raid1c3 metadata -- is not -affected at all, since its log tree is mirrored. Whether to settle +recover log tree", -EIO); the recovery is a read-only, degraded +rescue=nologreplay mount, which never writes and reads the +authoritative committed tree (recovered intact in every measured +case). Committed metadata is never touched -- across the whole +characterization no torn stripe held a committed tree block, because +every metadata run drains before the super that commits it -- and no +torn stripe ever held both a log-tree block and another tree block of +the crashed transaction, so the sharpest form of the hazard did not +occur. The recommended pairing -- raid6 data with raid1c3 metadata -- +is not affected at all, since its log tree is mirrored. Whether to settle metadata runs at log commit (with a log-class metadata run to confine the trapped tails, as the per-inode data runs do) or to state the raid56-metadata fsync window as detectable loss is the open decision @@ -1096,21 +1100,26 @@ regression set passes on the fixed candidate on both hosts. The raid56-metadata fsync-window characterization runs the replay matrix on raid5 data + raid5 metadata (5 devices) and raid6 + raid6 (6 devices) in fsync-window mode under the flush-consistent model, -with degraded log replay on, a zero-log fallback when it is refused, -the degraded read-write continuation, an offline check, and a scan of -every metadata stripe the torn tail touched (which tree blocks -- log -or other, committed or not -- it holds, whether its parity still -matches its data, and which members' loss would expose a durable log -block). Result on the current series: raid5, 40 armed cases, zero -committed-data damage, 45 degraded continuations clean; the degraded -replay was refused in 2 of 40 -- both on the member the scan had -named -- and zero-log recovered the committed set with a clean -continuation in both. raid6 (adjacent-pair drops), 48 armed cases, -zero damage, 54 continuations clean, no refusal. No torn stripe held -committed tree blocks in either run. The cuts that land inside the -transaction commit (where log and non-log tree blocks of one -transaction meet in a stripe) are a second pass with late cuts, in -progress on the fixed candidate. +with degraded log replay on, a rescue=nologreplay recovery when it is +refused, the degraded read-write continuation, an offline check, and a +scan of every metadata stripe the torn tail touched (which tree blocks +-- log or other, committed or not -- it holds, whether its parity +still matches its data, and which members' loss would expose a durable +log block). Two passes each: cuts spread over the fsync stream, and +late cuts that land inside the transaction commit, where a log-tree +block and another tree block of the same transaction could meet in a +stripe. Across all four passes -- 162 armed torn-plus-degraded cases +-- zero committed-data damage, zero silent corruption, every degraded +continuation intact, and no torn stripe held a committed tree block or +mixed a log block with a non-log block of the crashed transaction. +The degraded log replay was refused only in the two raid5 cases the +scan had named (a torn log tree); every other case, including the +late-cut passes and all of raid6, replayed cleanly. For the two +refused cases the rescue=nologreplay recovery read the committed set +back intact (825 files, both cases). The hazard scan +over-approximates in the safe direction: several cases it flagged +replayed without a refusal, because the "durable" log blocks it counts +include dead nodes superseded by a later log commit. Fifteen pre-existing, unrelated bugs surfaced along the way. Thirteen are fixed by the standalone patches listed under Prerequisites: the