From a7fefb63dd58687afcefe066e00baade1ef5db55 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 16 Mar 2026 17:02:39 +0100 Subject: [PATCH] virtio-devices: block: Populate discard and write zeroes config When VIRTIO_BLK_F_DISCARD or VIRTIO_BLK_F_WRITE_ZEROES features are advertised, the virtio spec v1.2, sections 5.2.4 and 5.2.6.1, requires the corresponding VirtioBlockConfig fields to contain valid, non zero values. Leaving them at zero causes strictly behaved drivers to either reject the features or crash. Populate max_discard_sectors, max_discard_seg, discard_sector_alignment, max_write_zeroes_sectors, max_write_zeroes_seg and write_zeroes_may_unmap after feature advertisement so drivers can safely negotiate these features. Fixes: #7849 Signed-off-by: Anatol Belski --- virtio-devices/src/block.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/virtio-devices/src/block.rs b/virtio-devices/src/block.rs index 166856534..af6d638dd 100644 --- a/virtio-devices/src/block.rs +++ b/virtio-devices/src/block.rs @@ -777,10 +777,12 @@ impl Block { // - Always advertise WRITE_ZEROES // - Advertise DISCARD only if sparse=true OR format supports marking // clusters as zero without deallocating + 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() { avail_features |= 1u64 << VIRTIO_BLK_F_DISCARD; + discard_supported = true; } } else if sparse { warn!("sparse=on requested but backend does not support sparse operations"); @@ -823,6 +825,17 @@ impl Block { ..Default::default() }; + if avail_features & (1u64 << VIRTIO_BLK_F_WRITE_ZEROES) != 0 { + config.max_write_zeroes_sectors = u32::MAX; + config.max_write_zeroes_seg = 1; + config.write_zeroes_may_unmap = if discard_supported { 1 } else { 0 }; + } + if avail_features & (1u64 << VIRTIO_BLK_F_DISCARD) != 0 { + config.max_discard_sectors = u32::MAX; + config.max_discard_seg = 1; + config.discard_sector_alignment = 1; + } + if num_queues > 1 { avail_features |= 1u64 << VIRTIO_BLK_F_MQ; config.num_queues = num_queues as u16;