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(+)Reviewed-by: Stefan Hajnoczi <[email protected]>
signature.asc
Description: PGP signature
