Another way, which doesn't pin blocks and prevent their reallocation, is to keep track of
dependencies in the journal: transaction 3 _depends_ on transaction 2, because it uses blocks
which are repurposed in transaction 2. So there should be a note in transaction 3 saying "I
depend on T2".
During replay, if transaction 2 fails due to bad checksum, transaction 3 will be rejected due
to the dependency. Transaction 4 may be fine, etc.
(The same dependencies can be converted to finer-grained barriers too - e.g. to optimise ext4
on software RAID.)
Some RAM is needed to keep track of the dependencies, until commits are known to have hit the
platters. If it's a problem, this can be bounded with some hashed approximation akin to a