Closed moroten closed 10 months ago
Thanks for the fix, @moroten. Really appreciated! The test case you provided is great.
With regards to the change to the implementation, I took a slightly different route. The problem with your change is that if the call to PushBack()
on line 311 fails, we never end up calling startAllocatingFromBlock()
. This leaves OldCurrentNewLocationBlobMap
in an inconsistent state. We need to account for the case where OldCurrentNewLocationBlobMap
needs to be left behind in a state where the underlying BlockList
has zero blocks.
We already account for this in NewOldCurrentNewLocationBlobMap()
by setting lbm.allocationBlockIndex = -1
and lbm.allocationAttemptsRemaining = 0
. This effectively delays the call to startAllocatingFromBlock(0)
to the very bottom of findBlockWithSpace()
. I have factored this out into a new helper method resetAllocationBlockIndex()
, which we now call in all places where we need to rewind.
Setting lbm.allocationAttemptsRemaining = 0
is a good trigger for the reset. Nice!
If data corruption was found in the newest block, all blocks would be released and trigger a panic when no block was allocated for writing. See the stack trace below where
lbm.newBlocks=0
andi=0
leads tolbm.allocationAttemptsRemaining = 1 << -1
which panics.