On Mon, Jan 05, 2026 at 03:29:55PM +0100, Fiona Ebner wrote:
> Commit 5634622bcb ("file-posix: allow BLKZEROOUT with -t writeback")
> enables the BLKZEROOUT ioctl when using 'writeback' cache, regressing
> certain 'qemu-img convert' invocations, because of a pre-existing
> issue. Namely, the BLKZEROOUT ioctl might fail with errno EINVAL when
> the request is shorter than the block size of the block device.
> Fallback to the bounce buffer, similar to when the ioctl is not
> supported at all, rather than treating such an error as fatal.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3257
> Resolves: https://bugzilla.proxmox.com/show_bug.cgi?id=7197
> Cc: [email protected]
> Signed-off-by: Fiona Ebner <[email protected]>
> ---
>  block/io.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/block/io.c b/block/io.c
> index cace297f22..e37d9d2417 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -1917,7 +1917,8 @@ bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t 
> offset, int64_t bytes,
>              assert(!bs->supported_zero_flags);
>          }
>  
> -        if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
> +        if ((ret == -ENOTSUP || (ret == -EINVAL && num < alignment)) &&
> +            !(flags & BDRV_REQ_NO_FALLBACK)) {
>              /* Fall back to bounce buffer if write zeroes is unsupported */
>              BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;

This patch invokes the ioctl(BLKZERO) first and then falls back to a
write request. In the bug report this only occurs at the end of qemu-img
convert, so the performance overhead of failing the ioctl first and then
submitting a write doesn't matter.

I would prefer taking advantage of the existing alignment code in
bdrv_co_do_zero_pwritev() instead of falling back like this. The
alignment code currently has no effect because
BlockLimits->request_alignment = 1 for cache=writeback. It is unaware
that ioctl(BLKZERO) requires block alignment. Once that is fixed,
bdrv_co_do_zero_pwritev() will submit a regular write request for the
misaligned tail.

Block drivers with specific alignment requirements for write zeroes
report them in BlockLimits->pwrite_zeroes_alignment. I think
bdrv_co_do_zero_pwritev() should prioritize
bs->bl.pwrite_zeroes_alignment over bs->bl.request_alignment.
file-posix.c already populates pwrite_zeroes_alignment - it's just not
used by bdrv_co_do_zero_pwritev() yet.

Do you want to give that a try?

Thanks,
Stefan

Attachment: signature.asc
Description: PGP signature

Reply via email to