diff options
Diffstat (limited to 'linux-aio.c')
-rw-r--r-- | linux-aio.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/linux-aio.c b/linux-aio.c index 50da75db19..1c635ef12d 100644 --- a/linux-aio.c +++ b/linux-aio.c @@ -31,6 +31,8 @@ struct qemu_laiocb { struct iocb iocb; ssize_t ret; size_t nbytes; + QEMUIOVector *qiov; + bool is_read; QLIST_ENTRY(qemu_laiocb) node; }; @@ -57,10 +59,17 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s, ret = laiocb->ret; if (ret != -ECANCELED) { - if (ret == laiocb->nbytes) + if (ret == laiocb->nbytes) { ret = 0; - else if (ret >= 0) - ret = -EINVAL; + } else if (ret >= 0) { + /* Short reads mean EOF, pad with zeros. */ + if (laiocb->is_read) { + qemu_iovec_memset_skip(laiocb->qiov, 0, + laiocb->qiov->size - ret, ret); + } else { + ret = -EINVAL; + } + } laiocb->common.cb(laiocb->common.opaque, ret); } @@ -162,6 +171,8 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, laiocb->nbytes = nb_sectors * 512; laiocb->ctx = s; laiocb->ret = -EINPROGRESS; + laiocb->is_read = (type == QEMU_AIO_READ); + laiocb->qiov = qiov; iocbs = &laiocb->iocb; |