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