Files
cloud-hypervisor/block
doge a5e145bdef block: Fix QCOW double allocation after a failed L2 relocation
The relocate-on-write path in update_cluster_addr() pushes the old L2
table cluster onto unref_clusters before allocating the relocation
target. When that allocation fails at allocator exhaustion, the error
unwinds with the still-referenced table on the free list, its deferred
refcount update dropped, the L1 entry unchanged and the cached table
still clean. The next metadata flush publishes the cluster to the
allocator, and a later allocation hands the live L2 table to a new
writer, which overwrites it with a refcount block, another L2 table or
guest data. Retried writes against the same L1 slot re-enter the
clean-table branch and push further duplicates, so one cluster can also
be handed out to two writers at once.

Images holding compressed clusters reach this constantly: writing to a
compressed cluster always takes the decompress -> append_data_cluster
-> update_cluster_addr path, so every such write relocates its L2
table.

Allocate the relocation target first and release the old table only
once the allocation has succeeded. A failed relocation now leaves the
old table referenced, off the free lists and intact.

Add deterministic regression coverage for both entry points: a plain
write that exhausts the allocator at the L2 relocation step, and a
compressed-cluster write that triggers the same relocation.

Signed-off-by: doge <me@crackerben.com>
2026-07-27 11:19:34 +00:00
..