@samitouri / QOSamiQemu / commits / b4e28c304b

block/io: fallback to bounce buffer if BLKZEROOUT is not supported because of alignment

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: qemu-stable@nongnu.org Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> Message-ID: <20260105143416.737482-1-f.ebner@proxmox.com> [Added TODO comment describing a larger fix that could be implemented in the future. --Stefan] Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

Fiona Ebner committed Jan 5, 2026 at 15:29 UTC b4e28c304bc58325f8f712cb25e5d700826caa25
1 file changed +12 -1
block/io.c
+12 -1
@@ -1918,7 +1918,18 @@ bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
1918 assert(!bs->supported_zero_flags);
1919 }
1920
1921 - if (ret == -ENOTSUP && !(flags & BDRV_REQ_NO_FALLBACK)) {
1921 + /*
1922 + * TODO The ret == -EINVAL && num < alignment case is a workaround for
1923 + * when request_alignment is 1 on files with cache=writeback. The Linux
1924 + * ioctl(BLKZEROOUT) requires block alignment and will fail with
1925 + * EINVAL. The block layer should align the request to
1926 + * write_zeroes_alignment instead of trying the syscall, failing, and
1927 + * falling back to a bounce buffer. Doing that is not easy so for now
1928 + * we use a bounce buffer:
1929 + * https://lore.kernel.org/qemu-devel/20260109120837.2772961-1-f.ebner@proxmox.com/
1930 + */
1931 + if ((ret == -ENOTSUP || (ret == -EINVAL && num < alignment)) &&
1932 + !(flags & BDRV_REQ_NO_FALLBACK)) {
1933 /* Fall back to bounce buffer if write zeroes is unsupported */
1934 BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
1935