diff options
author | Chunqiang Tang <ctang@us.ibm.com> | 2011-02-03 10:12:49 -0500 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-02-10 13:23:44 +0100 |
commit | e0d9c6f93729c9bfc98fcafcd73098bb8e131aeb (patch) | |
tree | 3fb49fe18a687f023bb5eb1e7a662109b625a46c /block | |
parent | 982aa95532a3a7b549695d5b3e18442975eecfb5 (diff) |
QCOW2: bug fix - read base image beyond its size
This patch fixes the following bug in QCOW2. For a QCOW2 image that is larger
than its base image, when handling a read request straddling over the end of the
base image, the QCOW2 driver attempts to read beyond the end of the base image
and the request would fail.
This bug was found by Fast Virtual Disk (FVD)'s fully automated testing tool.
The following test triggered the bug.
dd if=/dev/zero of=/var/ramdisk/truth.raw count=0 bs=1 seek=1098561536
dd if=/dev/zero of=/var/ramdisk/zero-500M.raw count=0 bs=1 seek=593099264
./qemu-img create -f qcow2 -ocluster_size=65536,backing_fmt=blksim -b /var/ramdisk/zero-500M.raw /var/ramdisk/test.qcow2 1098561536
./qemu-io --auto --seed=30477694 --truth=/var/ramdisk/truth.raw --format=qcow2 --test=blksim:/var/ramdisk/test.qcow2 --verify_write=true --compare_before=false --compare_after=true --round=100000 --parallel=100 --io_size=10485760 --fail_prob=0 --cancel_prob=0 --instant_qemubh=true
Signed-off-by: Chunqiang Tang <ctang@us.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/qcow2.c | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/block/qcow2.c b/block/qcow2.c index a1773e4790..28338bf9d0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -355,7 +355,7 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, else n1 = bs->total_sectors - sector_num; - qemu_iovec_memset(qiov, 0, 512 * (nb_sectors - n1)); + qemu_iovec_memset_skip(qiov, 0, 512 * (nb_sectors - n1), 512 * n1); return n1; } @@ -478,8 +478,7 @@ static void qcow2_aio_read_cb(void *opaque, int ret) if (n1 > 0) { BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num, - &acb->hd_qiov, acb->cur_nr_sectors, - qcow2_aio_read_cb, acb); + &acb->hd_qiov, n1, qcow2_aio_read_cb, acb); if (acb->hd_aiocb == NULL) goto done; } else { |