mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
Commitb8bfb1478d("qcow2: Fix corruption on discard during write with COW") added a wait_for_dependencies() at the start of qcow2_subcluster_zeroize(). That fixes the inconsistency it set out to fix, but turns the lock-protected pre-check in the caller, qcow2_co_pwrite_zeroes(), into a stale one: the wait yields s->lock, so an in-flight allocating write whose QCowL2Meta is already on s->cluster_allocs (but whose L2 entry is not yet linked) gets to link its entry during the yield. When the zeroize wakes, the cluster is now NORMAL, and with BDRV_REQ_MAY_UNMAP the free path in zero_in_l2_slice() unmaps the just-written cluster, silently dropping the data write's payload. This is reachable with detect-zeroes=unmap (the default for VirtIO disks with discard on in Proxmox VE), under which the block layer auto-promotes all-zero buffers to BDRV_REQ_ZERO_WRITE | BDRV_REQ_MAY_UNMAP. A memory-constrained Debian guest running 'apt full-upgrade' on such a disk reproduces it as random SIGSEGVs: swapped-out code pages come back as zero. Wait for in-flight dependencies before the lock-protected check in qcow2_co_pwrite_zeroes(). If a write linked its L2 entry during the wait, the type check now fails and the block layer falls back to a bounce-buffered zero write that only touches the requested subrange, preserving the racing write's data. Promote wait_for_dependencies() to qcow2_wait_for_dependencies() so qcow2.c can call it. Fixes:b8bfb1478d("qcow2: Fix corruption on discard during write with COW") Cc: qemu-stable@nongnu.org Tested-by: Fiona Ebner <f.ebner@proxmox.com> Reviewed-by: Fiona Ebner <f.ebner@proxmox.com> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> Message-ID: <20260522151318.238064-1-t.lamprecht@proxmox.com> [kwolf: Reverted unnecessary change to 'nr' assignment] Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>