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



Reply via email to