diff options
author | Kevin Wolf <kwolf@redhat.com> | 2018-07-06 18:41:07 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-07-10 10:36:15 +0200 |
commit | b0ddcbbb36a66a605eb232b905cb49b1cc72e74e (patch) | |
tree | 17559d6ee3a6ea34daf7bd50a8174a54d90a4b30 /block | |
parent | b994c5bc515fe611885113e7cfa7e87817bfd4e2 (diff) |
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>
Diffstat (limited to 'block')
-rw-r--r-- | block/io.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/block/io.c b/block/io.c index 038449f81f..4c0831149c 100644 --- a/block/io.c +++ b/block/io.c @@ -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) { |