Revision 9c39be47 block-raw-win32.c

b/block-raw-win32.c
28 28
#include <windows.h>
29 29
#include <winioctl.h>
30 30

  
31
//#define WIN32_AIO
32

  
33 31
#define FTYPE_FILE 0
34 32
#define FTYPE_CD     1
35 33
#define FTYPE_HARDDISK 2
......
40 38
    char drive_path[16]; /* format: "d:\" */
41 39
} BDRVRawState;
42 40

  
43
typedef struct RawAIOCB {
44
    BlockDriverAIOCB common;
45
    HANDLE hEvent;
46
    OVERLAPPED ov;
47
    int count;
48
} RawAIOCB;
49

  
50 41
int qemu_ftruncate64(int fd, int64_t length)
51 42
{
52 43
    LARGE_INTEGER li;
......
100 91
    } else {
101 92
        create_flags = OPEN_EXISTING;
102 93
    }
103
#ifdef WIN32_AIO
104
    overlapped = FILE_FLAG_OVERLAPPED;
105
#else
106 94
    overlapped = FILE_ATTRIBUTE_NORMAL;
107
#endif
108 95
    if ((flags & BDRV_O_NOCACHE))
109 96
        overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
110 97
    else if (!(flags & BDRV_O_CACHE_WB))
......
136 123
    ov.Offset = offset;
137 124
    ov.OffsetHigh = offset >> 32;
138 125
    ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
139
    if (!ret) {
140
#ifdef WIN32_AIO
141
        ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
142
        if (!ret)
143
            return -EIO;
144
        else
145
#endif
146
            return ret_count;
147
    }
126
    if (!ret)
127
        return ret_count;
148 128
    if (ret_count == count)
149 129
        ret_count = 0;
150 130
    return ret_count;
......
164 144
    ov.Offset = offset;
165 145
    ov.OffsetHigh = offset >> 32;
166 146
    ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
167
    if (!ret) {
168
#ifdef WIN32_AIO
169
        ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
170
        if (!ret)
171
            return -EIO;
172
        else
173
#endif
174
            return ret_count;
175
    }
147
    if (!ret)
148
        return ret_count;
176 149
    if (ret_count == count)
177 150
        ret_count = 0;
178 151
    return ret_count;
179 152
}
180 153

  
181
#ifdef WIN32_AIO
182
static void raw_aio_cb(void *opaque)
183
{
184
    RawAIOCB *acb = opaque;
185
    BlockDriverState *bs = acb->common.bs;
186
    BDRVRawState *s = bs->opaque;
187
    DWORD ret_count;
188
    int ret;
189

  
190
    ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
191
    if (!ret || ret_count != acb->count) {
192
        acb->common.cb(acb->common.opaque, -EIO);
193
    } else {
194
        acb->common.cb(acb->common.opaque, 0);
195
    }
196
}
197

  
198
static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
199
        int64_t sector_num, uint8_t *buf, int nb_sectors,
200
        BlockDriverCompletionFunc *cb, void *opaque)
201
{
202
    RawAIOCB *acb;
203
    int64_t offset;
204

  
205
    acb = qemu_aio_get(bs, cb, opaque);
206
    if (acb->hEvent) {
207
        acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
208
        if (!acb->hEvent) {
209
            qemu_aio_release(acb);
210
            return NULL;
211
        }
212
    }
213
    memset(&acb->ov, 0, sizeof(acb->ov));
214
    offset = sector_num * 512;
215
    acb->ov.Offset = offset;
216
    acb->ov.OffsetHigh = offset >> 32;
217
    acb->ov.hEvent = acb->hEvent;
218
    acb->count = nb_sectors * 512;
219
    qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
220
    return acb;
221
}
222

  
223
static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
224
        int64_t sector_num, uint8_t *buf, int nb_sectors,
225
        BlockDriverCompletionFunc *cb, void *opaque)
226
{
227
    BDRVRawState *s = bs->opaque;
228
    RawAIOCB *acb;
229
    int ret;
230

  
231
    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
232
    if (!acb)
233
        return NULL;
234
    ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
235
    if (!ret) {
236
        qemu_aio_release(acb);
237
        return NULL;
238
    }
239
    qemu_aio_release(acb);
240
    return (BlockDriverAIOCB *)acb;
241
}
242

  
243
static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
244
        int64_t sector_num, uint8_t *buf, int nb_sectors,
245
        BlockDriverCompletionFunc *cb, void *opaque)
246
{
247
    BDRVRawState *s = bs->opaque;
248
    RawAIOCB *acb;
249
    int ret;
250

  
251
    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
252
    if (!acb)
253
        return NULL;
254
    ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
255
    if (!ret) {
256
        qemu_aio_release(acb);
257
        return NULL;
258
    }
259
    qemu_aio_release(acb);
260
    return (BlockDriverAIOCB *)acb;
261
}
262

  
263
static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
264
{
265
    RawAIOCB *acb = (RawAIOCB *)blockacb;
266
    BlockDriverState *bs = acb->common.bs;
267
    BDRVRawState *s = bs->opaque;
268

  
269
    qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
270
    /* XXX: if more than one async I/O it is not correct */
271
    CancelIo(s->hfile);
272
    qemu_aio_release(acb);
273
}
274
#endif /* #if WIN32_AIO */
275

  
276 154
static void raw_flush(BlockDriverState *bs)
277 155
{
278 156
    BDRVRawState *s = bs->opaque;
......
361 239
    raw_create,
362 240
    raw_flush,
363 241

  
364
#ifdef WIN32_AIO
365
    .bdrv_aio_read = raw_aio_read,
366
    .bdrv_aio_write = raw_aio_write,
367
    .bdrv_aio_cancel = raw_aio_cancel,
368
    .aiocb_size = sizeof(RawAIOCB);
369
#endif
370 242
    .bdrv_read = raw_read,
371 243
    .bdrv_write = raw_write,
372 244
    .bdrv_truncate = raw_truncate,
......
446 318
    }
447 319
    create_flags = OPEN_EXISTING;
448 320

  
449
#ifdef WIN32_AIO
450
    overlapped = FILE_FLAG_OVERLAPPED;
451
#else
452 321
    overlapped = FILE_ATTRIBUTE_NORMAL;
453
#endif
454 322
    if ((flags & BDRV_O_NOCACHE))
455 323
        overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
456 324
    else if (!(flags & BDRV_O_CACHE_WB))
......
510 378
    .bdrv_close		= raw_close,
511 379
    .bdrv_flush		= raw_flush,
512 380

  
513
#ifdef WIN32_AIO
514
    .bdrv_aio_read	= raw_aio_read,
515
    .bdrv_aio_write	= raw_aio_write,
516
    .bdrv_aio_cancel	= raw_aio_cancel,
517
    .aiocb_size		= sizeof(RawAIOCB);
518
#endif
519 381
    .bdrv_read		= raw_read,
520 382
    .bdrv_write	        = raw_write,
521 383
    .bdrv_getlength	= raw_getlength,

Also available in: Unified diff