Revision c16b5a2c block.c
b/block.c | ||
---|---|---|
48 | 48 |
#define SECTOR_BITS 9 |
49 | 49 |
#define SECTOR_SIZE (1 << SECTOR_BITS) |
50 | 50 |
|
51 |
typedef struct BlockDriverAIOCBSync { |
|
52 |
BlockDriverAIOCB common; |
|
53 |
QEMUBH *bh; |
|
54 |
int ret; |
|
55 |
/* vector translation state */ |
|
56 |
QEMUIOVector *qiov; |
|
57 |
uint8_t *bounce; |
|
58 |
int is_write; |
|
59 |
} BlockDriverAIOCBSync; |
|
60 |
|
|
61 | 51 |
static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, |
62 | 52 |
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, |
63 | 53 |
BlockDriverCompletionFunc *cb, void *opaque); |
64 | 54 |
static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, |
65 | 55 |
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, |
66 | 56 |
BlockDriverCompletionFunc *cb, void *opaque); |
67 |
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb); |
|
68 | 57 |
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, |
69 | 58 |
uint8_t *buf, int nb_sectors); |
70 | 59 |
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, |
... | ... | |
138 | 127 |
} |
139 | 128 |
} |
140 | 129 |
|
141 |
|
|
142 | 130 |
void bdrv_register(BlockDriver *bdrv) |
143 | 131 |
{ |
144 | 132 |
if (!bdrv->bdrv_aio_readv) { |
145 | 133 |
/* add AIO emulation layer */ |
146 | 134 |
bdrv->bdrv_aio_readv = bdrv_aio_readv_em; |
147 | 135 |
bdrv->bdrv_aio_writev = bdrv_aio_writev_em; |
148 |
bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em; |
|
149 |
bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync); |
|
150 | 136 |
} else if (!bdrv->bdrv_read) { |
151 | 137 |
/* add synchronous IO emulation layer */ |
152 | 138 |
bdrv->bdrv_read = bdrv_read_em; |
153 | 139 |
bdrv->bdrv_write = bdrv_write_em; |
154 | 140 |
} |
155 |
aio_pool_init(&bdrv->aio_pool, bdrv->aiocb_size, bdrv->bdrv_aio_cancel); |
|
156 | 141 |
bdrv->next = first_drv; |
157 | 142 |
first_drv = bdrv; |
158 | 143 |
} |
... | ... | |
1369 | 1354 |
/**************************************************************/ |
1370 | 1355 |
/* async block device emulation */ |
1371 | 1356 |
|
1357 |
typedef struct BlockDriverAIOCBSync { |
|
1358 |
BlockDriverAIOCB common; |
|
1359 |
QEMUBH *bh; |
|
1360 |
int ret; |
|
1361 |
/* vector translation state */ |
|
1362 |
QEMUIOVector *qiov; |
|
1363 |
uint8_t *bounce; |
|
1364 |
int is_write; |
|
1365 |
} BlockDriverAIOCBSync; |
|
1366 |
|
|
1367 |
static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) |
|
1368 |
{ |
|
1369 |
BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; |
|
1370 |
qemu_bh_cancel(acb->bh); |
|
1371 |
qemu_aio_release(acb); |
|
1372 |
} |
|
1373 |
|
|
1374 |
static AIOPool bdrv_em_aio_pool = { |
|
1375 |
.aiocb_size = sizeof(BlockDriverAIOCBSync), |
|
1376 |
.cancel = bdrv_aio_cancel_em, |
|
1377 |
}; |
|
1378 |
|
|
1372 | 1379 |
static void bdrv_aio_bh_cb(void *opaque) |
1373 | 1380 |
{ |
1374 | 1381 |
BlockDriverAIOCBSync *acb = opaque; |
... | ... | |
1392 | 1399 |
{ |
1393 | 1400 |
BlockDriverAIOCBSync *acb; |
1394 | 1401 |
|
1395 |
acb = qemu_aio_get(bs, cb, opaque); |
|
1402 |
acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
|
|
1396 | 1403 |
acb->is_write = is_write; |
1397 | 1404 |
acb->qiov = qiov; |
1398 | 1405 |
acb->bounce = qemu_blockalign(bs, qiov->size); |
... | ... | |
1426 | 1433 |
return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); |
1427 | 1434 |
} |
1428 | 1435 |
|
1429 |
|
|
1430 |
static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) |
|
1431 |
{ |
|
1432 |
BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; |
|
1433 |
qemu_bh_cancel(acb->bh); |
|
1434 |
qemu_aio_release(acb); |
|
1435 |
} |
|
1436 |
|
|
1437 | 1436 |
/**************************************************************/ |
1438 | 1437 |
/* sync block device emulation */ |
1439 | 1438 |
|
... | ... | |
1495 | 1494 |
module_call_init(MODULE_INIT_BLOCK); |
1496 | 1495 |
} |
1497 | 1496 |
|
1498 |
void aio_pool_init(AIOPool *pool, int aiocb_size, |
|
1499 |
void (*cancel)(BlockDriverAIOCB *acb)) |
|
1500 |
{ |
|
1501 |
pool->aiocb_size = aiocb_size; |
|
1502 |
pool->cancel = cancel; |
|
1503 |
pool->free_aiocb = NULL; |
|
1504 |
} |
|
1505 |
|
|
1506 |
void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs, |
|
1507 |
BlockDriverCompletionFunc *cb, void *opaque) |
|
1497 |
void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, |
|
1498 |
BlockDriverCompletionFunc *cb, void *opaque) |
|
1508 | 1499 |
{ |
1509 | 1500 |
BlockDriverAIOCB *acb; |
1510 | 1501 |
|
... | ... | |
1521 | 1512 |
return acb; |
1522 | 1513 |
} |
1523 | 1514 |
|
1524 |
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb, |
|
1525 |
void *opaque) |
|
1526 |
{ |
|
1527 |
return qemu_aio_get_pool(&bs->drv->aio_pool, bs, cb, opaque); |
|
1528 |
} |
|
1529 |
|
|
1530 | 1515 |
void qemu_aio_release(void *p) |
1531 | 1516 |
{ |
1532 | 1517 |
BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; |
Also available in: Unified diff