Skip to content

Commit

Permalink
linux-aio: Allow reads beyond the end of growable images
Browse files Browse the repository at this point in the history
This is the linux-aio version of commits 22afa7b (raw-posix, synchronous) and
ba1d1af (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>
  • Loading branch information
kevmw committed Oct 14, 2011
1 parent 1a6e115 commit b161e2e
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions linux-aio.c
Expand Up @@ -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;
};

Expand All @@ -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);
}
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit b161e2e

Please sign in to comment.