Skip to main content

plan_block_allocation_excluding

Function plan_block_allocation_excluding 

Source
pub fn plan_block_allocation_excluding<F>(
    sb: &Superblock,
    groups: &[BlockGroupDescriptor],
    count: u32,
    hint_group: u32,
    reserved: &[u64],
    bitmap_reader: F,
) -> Result<BlockAllocationPlan>
where F: FnMut(u64) -> Result<Vec<u8>>,
Expand description

plan_block_allocation, with blocks that are SPOKEN FOR BUT NOT YET COMMITTED treated as used.

§WHY THE PLANNER HAS TO BE TOLD, RATHER THAN ITS ANSWER FILTERED

A caller that plans several allocations before committing any of them – which is the late-commit ordering the write paths use so a failure half way through leaks no blocks – shows this function the same unchanged bitmap every time, so it returns the same block every time. Measured on a fresh 64 MiB image, three consecutive plans against an uncommitted bitmap: 517 517 517.

The caller that hit this defended itself with one equality test against one reserved block, which is wrong twice: it refuses with NoSpaceLeftOnDevice on a nearly empty filesystem when the block does match, and when it does not it lets the SECOND meta block alias the first, because the test never looked at the ones it had already handed out. Two extent-tree nodes on one physical block is silent corruption; the refusal is at least loud.

EXTENDING THE EQUALITY TEST TO THE WHOLE LIST IS NOT THE FIX. The planner would go on returning the same block, so the list would just turn the aliasing into a second spurious refusal. The reservations have to be in the bitmap the scan reads.

§THE OVERLAY CANNOT LIVE IN THE CALLER’S READER

The obvious smaller change – have the caller’s bitmap_reader return bytes with the reserved bits already set – is not enough, because a BLOCK_UNINIT group never calls the reader at all: the bitmap is fabricated as all-free right here. That is exactly the state a freshly formatted image is in, which is where this is most likely to bite. So the marking happens after the bitmap is obtained, on both paths.