linux-aio: Allow reads beyond the end of growable images
This is the linux-aio version of commits 22afa7b5 (raw-posix, synchronous) and ba1d1afd (posix-aio-compat). Reads now produce zeros after the end of file instead of failing or resulting in short reads, making linux-aio compatible with the behaviour of synchronous raw-posix requests and posix-aio-compat. The problem can be reproduced like this: dd if=/dev/zero of=/tmp/test.raw bs=1 count=1234 ./qemu-io -k -n -g -c 'read -p 1024 512' /tmp/test.raw Previously, the result of this was 'read failed: Invalid argument', now the read completes successfully. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
This commit is contained in:
parent
1a6e115b19
commit
b161e2e4b3
17
linux-aio.c
17
linux-aio.c
@ -31,6 +31,8 @@ struct qemu_laiocb {
|
|||||||
struct iocb iocb;
|
struct iocb iocb;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
|
QEMUIOVector *qiov;
|
||||||
|
bool is_read;
|
||||||
QLIST_ENTRY(qemu_laiocb) node;
|
QLIST_ENTRY(qemu_laiocb) node;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,10 +59,17 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
|
|||||||
|
|
||||||
ret = laiocb->ret;
|
ret = laiocb->ret;
|
||||||
if (ret != -ECANCELED) {
|
if (ret != -ECANCELED) {
|
||||||
if (ret == laiocb->nbytes)
|
if (ret == laiocb->nbytes) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else if (ret >= 0)
|
} else if (ret >= 0) {
|
||||||
ret = -EINVAL;
|
/* 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);
|
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->nbytes = nb_sectors * 512;
|
||||||
laiocb->ctx = s;
|
laiocb->ctx = s;
|
||||||
laiocb->ret = -EINPROGRESS;
|
laiocb->ret = -EINPROGRESS;
|
||||||
|
laiocb->is_read = (type == QEMU_AIO_READ);
|
||||||
|
laiocb->qiov = qiov;
|
||||||
|
|
||||||
iocbs = &laiocb->iocb;
|
iocbs = &laiocb->iocb;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user