From: Kevin Wolf <kwolf@redhat.com>
To: Alberto Garcia <berto@igalia.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org,
Hanna Czenczek <hreitz@redhat.com>,
Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Subject: Re: [PATCH] qemu-img rebase: don't exceed IO_BUF_SIZE in one operation
Date: Fri, 7 Nov 2025 13:31:25 +0100 [thread overview]
Message-ID: <aQ3mnR1RJiaPau6A@redhat.com> (raw)
In-Reply-To: <20251107091834.383781-1-berto@igalia.com>
Am 07.11.2025 um 10:18 hat Alberto Garcia geschrieben:
> During a rebase operation data is copied from the backing chain into
> the target image using a loop, and each iteration looks for a
> contiguous region of allocated data of at most IO_BUF_SIZE (2 MB).
>
> Once that region is found, and in order to avoid partial writes, its
> boundaries are extended so they are aligned to the (sub)clusters of
> the target image (see commit 12df580b).
>
> This operation can however result in a region that exceeds the maximum
> allowed IO_BUF_SIZE, crashing qemu-img.
>
> This can be easily reproduced when the source image has a smaller
> cluster size than the target image:
>
> base <- int <- active
>
> $ qemu-img create -f qcow2 base.qcow2 4M
> $ qemu-img create -f qcow2 -F qcow2 -b base.qcow2 -o cluster_size=1M int.qcow2
> $ qemu-img create -f qcow2 -F qcow2 -b int.qcow2 -o cluster_size=2M active.qcow2
> $ qemu-io -c "write -P 0xff 1M 2M" int.qcow2
> $ qemu-img rebase -F qcow2 -b base.qcow2 active.qcow2
> qemu-img: qemu-img.c:4102: img_rebase: Assertion `written + pnum <= IO_BUF_SIZE' failed.
> Aborted
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3174
> Fixes: 12df580b3b7f ("qemu-img: rebase: avoid unnecessary COW operations")
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> ---
> qemu-img.c | 2 +-
> tests/qemu-iotests/024 | 46 ++++++++++++++++++++++++++++++++++++++
> tests/qemu-iotests/024.out | 27 ++++++++++++++++++++++
> 3 files changed, 74 insertions(+), 1 deletion(-)
>
> diff --git a/qemu-img.c b/qemu-img.c
> index a7791896c1..454da88c73 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -4081,7 +4081,7 @@ static int img_rebase(const img_cmd_t *ccmd, int argc, char **argv)
> n += offset - QEMU_ALIGN_DOWN(offset, write_align);
> offset = QEMU_ALIGN_DOWN(offset, write_align);
> n += QEMU_ALIGN_UP(offset + n, write_align) - (offset + n);
> - n = MIN(n, size - offset);
> + n = MIN(n, MIN(size - offset, IO_BUF_SIZE));
> assert(!bdrv_is_allocated(unfiltered_bs, offset, n, &n_alloc) &&
> n_alloc == n);
The fix itself looks ok.
> +$QEMU_IMG rebase -b "$BASE_NEW" -F $IMGFMT "$OVERLAY"
> +
> +echo "Verifying the data"
> +echo
> +
> +$QEMU_IO "$OVERLAY" -c "read -P 0x00 0 1M" | _filter_qemu_io
> +$QEMU_IO "$OVERLAY" -c "read -P 0xff 1M 2M" | _filter_qemu_io
> +$QEMU_IO "$OVERLAY" -c "read -P 0x00 2M 1M" | _filter_qemu_io
Here you mean 3M instead of 2M...
> +Verifying the data
> +
> +read 1048576/1048576 bytes at offset 0
> +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +read 2097152/2097152 bytes at offset 1048576
> +2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +Pattern verification failed at offset 2097152, 1048576 bytes
...which then fixes this failure.
> +read 1048576/1048576 bytes at offset 2097152
> +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +Offset Length File
> +0 0x400000 TEST_DIR/subdir/t.IMGFMT
> +
> *** done
Thanks, I've fixed it up as below and applied the patch to my block
branch.
Kevin
diff --git a/tests/qemu-iotests/024 b/tests/qemu-iotests/024
index b59d825b42..021169b4a1 100755
--- a/tests/qemu-iotests/024
+++ b/tests/qemu-iotests/024
@@ -357,7 +357,7 @@ echo
$QEMU_IO "$OVERLAY" -c "read -P 0x00 0 1M" | _filter_qemu_io
$QEMU_IO "$OVERLAY" -c "read -P 0xff 1M 2M" | _filter_qemu_io
-$QEMU_IO "$OVERLAY" -c "read -P 0x00 2M 1M" | _filter_qemu_io
+$QEMU_IO "$OVERLAY" -c "read -P 0x00 3M 1M" | _filter_qemu_io
$QEMU_IMG map "$OVERLAY" | _filter_qemu_img_map
diff --git a/tests/qemu-iotests/024.out b/tests/qemu-iotests/024.out
index cc18ee0290..1b7522ba71 100644
--- a/tests/qemu-iotests/024.out
+++ b/tests/qemu-iotests/024.out
@@ -264,8 +264,7 @@ read 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 2097152/2097152 bytes at offset 1048576
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Pattern verification failed at offset 2097152, 1048576 bytes
-read 1048576/1048576 bytes at offset 2097152
+read 1048576/1048576 bytes at offset 3145728
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Offset Length File
0 0x400000 TEST_DIR/subdir/t.IMGFMT
next prev parent reply other threads:[~2025-11-07 12:32 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-07 9:18 [PATCH] qemu-img rebase: don't exceed IO_BUF_SIZE in one operation Alberto Garcia
2025-11-07 12:31 ` Kevin Wolf [this message]
2025-11-07 12:33 ` Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aQ3mnR1RJiaPau6A@redhat.com \
--to=kwolf@redhat.com \
--cc=andrey.drobyshev@virtuozzo.com \
--cc=berto@igalia.com \
--cc=hreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).