mirror of
https://github.com/qemu/qemu.git
synced 2026-11-12 14:50:50 +00:00
The write granularity that a frontend reports is derived from the logical and the physical block size, which are properties of the device model, while the granularity that the medium requires and the write pointers that it holds belong to the backend. Nothing ties them together, and where they disagree a guest is told about a device it cannot use. A backend can require a coarser granularity than the block sizes express. A 512e host managed disk has a logical block size of 512 and requires writes to a sequential zone to be a multiple of 4096, so attaching it with a finer physical block size reports a granularity that the disk will not accept, and the guest is given a plain I/O error for a request that it was told was valid. The write pointers can disagree in the same way. They outlive any particular use of the device, while the block sizes are chosen afresh every time it is attached, so a zone written with logical_block_size=512 leaves a write pointer that logical_block_size=4096 cannot address. A zone report expresses it in 512 byte sectors, so the guest is told about a position that does not fall on a logical block boundary, which it can neither read nor write, and the zone can then only be recovered by resetting it. The reverse is harmless: a pointer laid down with a larger logical block size is still a multiple of a smaller one. Check both at realize time, along with the zone size and the zone capacity, and refuse to start otherwise. The write pointers are already held in memory by the driver, so this costs no I/O. The check uses blkconf_zone_write_granularity(), the same value that a frontend reports to its guest and validates requests against, so the three cannot disagree. Signed-off-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 20260921142819.2916043-8-cassel@kernel.org Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>