Il 23/07/2012 18:35, Blue Swirl ha scritto: >> > +struct qemu_paiocb { > QEMUPAIOCB
RawWin32AIOData. :) >> > + BlockDriverState *bs; >> > + HANDLE hfile; >> > + struct iovec *aio_iov; >> > + int aio_niov; >> > + size_t aio_nbytes; >> > + off_t aio_offset; >> > + int aio_type; >> > +}; >> > + >> > typedef struct BDRVRawState { >> > HANDLE hfile; >> > int type; >> > char drive_path[16]; /* format: "d:\" */ >> > } BDRVRawState; >> > >> > +/* >> > + * Read/writes the data to/from a given linear buffer. >> > + * >> > + * Returns the number of bytes handles or -errno in case of an error. >> > Short >> > + * reads are only returned if the end of the file is reached. >> > + */ >> > +static size_t handle_aiocb_rw(struct qemu_paiocb *aiocb) >> > +{ >> > + size_t offset = 0; >> > + int i; >> > + >> > + for (i = 0; i < aiocb->aio_niov; i++) { >> > + OVERLAPPED ov; >> > + DWORD ret, ret_count, len; >> > + >> > + memset(&ov, 0, sizeof(ov)); >> > + ov.Offset = (aiocb->aio_offset + offset); >> > + ov.OffsetHigh = (aiocb->aio_offset + offset) >> 32; >> > + len = aiocb->aio_iov[i].iov_len; >> > + if (aiocb->aio_type & QEMU_AIO_WRITE) { >> > + ret = WriteFile(aiocb->hfile, aiocb->aio_iov[i].iov_base, >> > + len, &ret_count, &ov); >> > + } else { >> > + ret = ReadFile(aiocb->hfile, aiocb->aio_iov[i].iov_base, >> > + len, &ret_count, &ov); >> > + } >> > + if (!ret) { >> > + ret_count = 0; >> > + } >> > + if (ret_count != len) { >> > + break; >> > + } >> > + offset += len; >> > + } >> > + >> > + return offset; >> > +} >> > + >> > +static int aio_worker(void *arg) >> > +{ >> > + struct qemu_paiocb *aiocb = arg; >> > + ssize_t ret = 0; >> > + size_t count; >> > + >> > + switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { >> > + case QEMU_AIO_READ: >> > + count = handle_aiocb_rw(aiocb); >> > + if (count < aiocb->aio_nbytes && aiocb->bs->growable) { >> > + /* A short read means that we have reached EOF. Pad the buffer >> > + * with zeros for bytes after EOF. */ >> > + QEMUIOVector qiov; >> > + >> > + qemu_iovec_init_external(&qiov, aiocb->aio_iov, >> > + aiocb->aio_niov); >> > + qemu_iovec_memset_skip(&qiov, 0, aiocb->aio_nbytes - count, >> > count); >> > + >> > + count = aiocb->aio_nbytes; >> > + } >> > + if (count == aiocb->aio_nbytes) { >> > + ret = 0; >> > + } else { >> > + ret = -EINVAL; >> > + } >> > + break; >> > + case QEMU_AIO_WRITE: >> > + count = handle_aiocb_rw(aiocb); >> > + if (count == aiocb->aio_nbytes) { >> > + count = 0; >> > + } else { >> > + count = -EINVAL; >> > + } >> > + break; >> > + case QEMU_AIO_FLUSH: >> > + if (!FlushFileBuffers(aiocb->hfile)) { >> > + return -EIO; >> > + } >> > + break; >> > + default: >> > + fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type); > Assert instead? Yeah, this is cut-and-pasted from posix-aio-compat.c, I'll fix both. Paolo