On Fri, Sep 18, 2026 at 04:06:42PM +0200, Niklas Cassel wrote:
> virtblk_read_zoned_limits() reads the write granularity that the device
> reports in virtio_blk_zoned_characteristics and assigns it to the
> physical block size and to io_min, but never to the limit that is named
> after it. queue_limits.zone_write_granularity is left at zero, so
> blk_validate_zoned_limits() raises it to the logical block size:
> 
>       if (lim->zone_write_granularity < lim->logical_block_size)
>               lim->zone_write_granularity = lim->logical_block_size;
> 
> A device that reports a granularity coarser than its logical block size,
> which is what the field exists to express, therefore has it silently
> reduced. A 512e host managed disk passed through to a guest reports a
> logical block size of 512 and a write granularity of 4096, and the guest
> ends up with a zone write granularity of 512.
> 
> bio_split_alignment() returns lim->zone_write_granularity if it is non-zero
> and bio_split_io_at() may split a bio with as per bio_split_alignment().
> This can real to the write getting rejected by the host drive, as the write
> is not aligned to the physical block size.
> 
> zonefs also takes its block size from bdev_zone_write_granularity(), so it
> would incorrectly use 512 on a disk that requires 4096.
> 
> sd_zbc_read_zones() sets the limit from the physical block size for the
> same reason. NVMe ZNS and null_blk leave it unset, but the fallback
> gives the right answer for them, as their write granularity is the
> logical block size. virtio carries a separate value that may exceed it.
> 
> Set the zone write granularity from the value that the device reports.
> 
> Fixes: 95bfec41bd3d ("virtio-blk: add support for zoned block devices")
> Signed-off-by: Niklas Cassel <[email protected]>
> ---
>  drivers/block/virtio_blk.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> index 32bf3ba07a9d..c8bfbf8435ac 100644
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -743,6 +743,7 @@ static int virtblk_read_zoned_limits(struct virtio_blk 
> *vblk,
>               dev_warn(&vdev->dev, "zero write granularity reported\n");
>               return -ENODEV;
>       }
> +     lim->zone_write_granularity = wg;
>       lim->physical_block_size = wg;
>       lim->io_min = wg;
>  
> 
> base-commit: 5dd1818b15d98d4a20806cd00b1b40320b06004f
> -- 
> 2.55.0
> 

Gentle ping

Reply via email to