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 { diff --git a/cutils.c b/cutils.c index 8d562b28ab..f9a7e3689e 100644 --- a/cutils.c +++ b/cutils.c @@ -267,6 +267,37 @@ void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count) } } +void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count, + size_t skip) +{ + int i; + size_t done; + void *iov_base; + uint64_t iov_len; + + done = 0; + for (i = 0; (i < qiov->niov) && (done != count); i++) { + if (skip >= qiov->iov[i].iov_len) { + /* Skip the whole iov */ + skip -= qiov->iov[i].iov_len; + continue; + } else { + /* Skip only part (or nothing) of the iov */ + iov_base = (uint8_t*) qiov->iov[i].iov_base + skip; + iov_len = qiov->iov[i].iov_len - skip; + skip = 0; + } + + if (done + iov_len > count) { + memset(iov_base, c, count - done); + break; + } else { + memset(iov_base, c, iov_len); + } + done += iov_len; + } +} + #ifndef _WIN32 /* Sets a specific flag */ int fcntl_setfl(int fd, int flag) diff --git a/qemu-common.h b/qemu-common.h index c7ff280b95..cb4b7e0d38 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -322,6 +322,8 @@ void qemu_iovec_reset(QEMUIOVector *qiov); void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count); void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count); +void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count, + size_t skip); struct Monitor; typedef struct Monitor Monitor;