Synthetic model / no hardware measurements
RAID write-hole states: an exhaustive one-bit XOR model
32 synthetic states distinguish inconsistent parity, recovery of an untouched missing chunk and preservation of an interrupted update. Not hardware measurements or failure probabilities.
Download CSV32 states / 15 columnsJSON, provenance and all rows / Model code (JavaScript) / Worked explanation
What is enumerated
Enumerate eight initial A/B/C bit triples and four independent persistence masks for a single changed A bit and parity. A durable partial-parity record Q=B XOR C is assumed to precede both member updates. Repaired parity is A_after XOR Q. B is absent at reconstruction; A, C and Q survive.
The missing member is untouched B, not updated A. A, C and the partial-parity log survive. The model does not operate on any real disk.
Results within these assumptions
Naive reconstruction gives the wrong B in 16 of 32 states. With the assumed intact log, the XOR repair recovers B in all 32. The intended A bit is still absent in 16 states.
These are exhaustive case counts, not rates. No workload frequencies or failure-time distribution are assigned to the states.
All modeled states
| Old A | B | C | A persisted | P persisted | Naive B | PPL B | Target A present |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
| 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |
| 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 |
| 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 |
| 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
| 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Reproduce
Download the JavaScript module, then run this command in the directory containing it with Node.js. It prints the complete state enumeration; no dependencies or device access are needed.
node --input-type=module -e 'import { enumerateStates } from "./raid-write-hole-model.mjs"; console.log(JSON.stringify(enumerateStates(), null, 2))'The versioned generator also writes the CSV and metadata. SHA-256 checksums in the metadata identify the model bytes and CSV; generation time is provenance, not an observation period.
Limits
- Synthetic state enumeration, not a sample of devices; state counts are not event probabilities and no confidence interval is applicable.
- Atomic one-bit member writes; no torn sectors, firmware, journal corruption, concurrency, RAID6 or multiple failures.
- The durable PPL record, its integrity and ordering are assumptions. This is not an implementation or verification of Linux MD recovery.
- Missing B was not being written. Missing A is outside the modeled guarantee; PPL does not generally preserve in-flight writes.
- No upper-layer I/O acknowledgement is modeled. a_target_present is not an application durability guarantee.
Column definitions
- a_before
- Initial bit of updated chunk A. Unit: dimensionless bit or 0/1 indicator.
- b_unchanged
- Initial bit of untouched chunk B; B is the missing member during reconstruction. Unit: dimensionless bit or 0/1 indicator.
- c_unchanged
- Bit of surviving untouched chunk C. Unit: dimensionless bit or 0/1 indicator.
- a_target
- Intended new bit in A, always 1 minus a_before in this enumeration. Unit: dimensionless bit or 0/1 indicator.
- data_persisted
- 1 if the A update reached nonvolatile storage before the modeled crash. Unit: dimensionless bit or 0/1 indicator.
- parity_persisted
- 1 if the new parity reached nonvolatile storage before the modeled crash. Unit: dimensionless bit or 0/1 indicator.
- a_after
- A bit available after the modeled crash. Unit: dimensionless bit or 0/1 indicator.
- parity_after
- Possibly stale parity bit available after the modeled crash. Unit: dimensionless bit or 0/1 indicator.
- parity_consistent
- 1 if parity_after equals XOR of the three post-crash data bits. Unit: dimensionless bit or 0/1 indicator.
- naive_recovered_b
- B reconstructed using a_after, c_unchanged and possibly stale parity. Unit: dimensionless bit or 0/1 indicator.
- naive_b_correct
- 1 if naive_recovered_b equals b_unchanged. Unit: dimensionless bit or 0/1 indicator.
- ppl_repaired_parity
- XOR of a_after and durably recorded XOR of untouched B and C. Unit: dimensionless bit or 0/1 indicator.
- ppl_recovered_b
- B reconstructed using the repaired parity. Unit: dimensionless bit or 0/1 indicator.
- ppl_b_correct
- 1 if ppl_recovered_b equals b_unchanged. Unit: dimensionless bit or 0/1 indicator.
- a_target_present
- 1 if A contains the intended new bit; independent of B recovery. Unit: dimensionless bit or 0/1 indicator.
Sources and license
CC0-1.0 for Hesela-generated CSV and numerical rows; model code MIT; cited sources retain their own licenses.
- Linux v6.12: Partial Parity Log (accessed 2026-10-11)
- Linux v6.12: RAID 4/5/6 cache (accessed 2026-10-11)
- Linux v6.12: RAID arrays, dirty/degraded assembly and bitmap metadata (accessed 2026-10-11)
- Linux v6.12: Explicit volatile write back cache control (accessed 2026-10-11)
Definitions: RAID write hole, Partial Parity Log, write-intent bitmap.