block: Fix copy-on-read crash with partial final cluster
If the virtual disk size isn't aligned to full clusters, bdrv_co_do_copy_on_readv() may get pnum == 0 before having the full cluster completed, which will let it run into an assertion failure: qemu-io: block/io.c:1203: bdrv_co_do_copy_on_readv: Assertion `skip_bytes < pnum' failed. Check for EOF, assert that we read at least as much as the read request originally wanted to have (which is true at EOF because otherwise bdrv_check_byte_request() would already have returned an error) and return success early even though we couldn't copy the full cluster. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
b994c5bc51
commit
b0ddcbbb36
@ -1200,6 +1200,12 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
||||
pnum = MIN(cluster_bytes, max_transfer);
|
||||
}
|
||||
|
||||
/* Stop at EOF if the image ends in the middle of the cluster */
|
||||
if (ret == 0 && pnum == 0) {
|
||||
assert(progress >= bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(skip_bytes < pnum);
|
||||
|
||||
if (ret <= 0) {
|
||||
|
@ -109,6 +109,15 @@ $QEMU_IO -f qcow2 -c map "$TEST_WRAP"
|
||||
_check_test_img
|
||||
$QEMU_IMG compare -f $IMGFMT -F qcow2 "$TEST_IMG" "$TEST_WRAP"
|
||||
|
||||
echo
|
||||
echo '=== Partial final cluster ==='
|
||||
echo
|
||||
|
||||
_make_test_img 1024
|
||||
$QEMU_IO -f $IMGFMT -C -c 'read 0 1024' "$TEST_IMG" | _filter_qemu_io
|
||||
$QEMU_IO -f $IMGFMT -c map "$TEST_IMG"
|
||||
_check_test_img
|
||||
|
||||
# success, all done
|
||||
echo '*** done'
|
||||
status=0
|
||||
|
@ -23,4 +23,12 @@ can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only dev
|
||||
1023.938 MiB (0x3fff0000) bytes not allocated at offset 3 GiB (0xc0010000)
|
||||
No errors were found on the image.
|
||||
Images are identical.
|
||||
|
||||
=== Partial final cluster ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
|
||||
read 1024/1024 bytes at offset 0
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
1 KiB (0x400) bytes allocated at offset 0 bytes (0x0)
|
||||
No errors were found on the image.
|
||||
*** done
|
||||
|
Loading…
x
Reference in New Issue
Block a user