block: Restrict DISCARD to explicit sparse=true

PR #7852 fixed the missing VirtioBlockConfig fields but did not
change the feature advertisement logic. The condition
`sparse || disk_image.supports_zero_flag()` causes qcow2 to
advertise DISCARD even with sparse=false, because qcow2 can
mark clusters as zero (supports_zero_flag() returns true).

Windows viostor BSODs (DRIVER_IRQL_NOT_LESS_OR_EQUAL) when
DISCARD is advertised on qcow2 backends, making sparse=off
ineffective as a workaround for qcow2 images.

Restrict DISCARD to explicit sparse=true only. WRITE_ZEROES
remains available for all sparse-capable backends.

Fixes #7849

Signed-off-by: CMGS <ilskdw@gmail.com>
This commit is contained in:
CMGS
2026-03-31 08:50:04 +00:00
committed by Rob Bradford
parent 8ca5210603
commit e4e2a37afa
2 changed files with 35 additions and 35 deletions

View File

@@ -778,13 +778,14 @@ impl Block {
| (1u64 << VIRTIO_RING_F_INDIRECT_DESC);
// When backend supports sparse operations:
// - Always advertise WRITE_ZEROES
// - Advertise DISCARD only if sparse=true OR format supports marking
// clusters as zero without deallocating
// - Always advertise WRITE_ZEROES (safe for all drivers)
// - Advertise DISCARD only when sparse=true, since DISCARD
// deallocates space via punch_hole and should require
// explicit user opt in.
let mut discard_supported = false;
if disk_image.supports_sparse_operations() {
avail_features |= 1u64 << VIRTIO_BLK_F_WRITE_ZEROES;
if sparse || disk_image.supports_zero_flag() {
if sparse {
avail_features |= 1u64 << VIRTIO_BLK_F_DISCARD;
discard_supported = true;
}