@@ -54,12 +54,6 @@ typedef enum {
} BdrvRequestFlags;
static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *iov);
@@ -280,10 +274,9 @@ void bdrv_register(BlockDriver *bdrv)
/* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
* the block driver lacks aio we need to emulate that too.
*/
- if (!bdrv->bdrv_aio_readv) {
+ if (!bdrv->bdrv_aio_rw_vector) {
/* add AIO emulation layer */
- bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
- bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
+ bdrv->bdrv_aio_rw_vector = bdrv_aio_rw_vector;
}
}
@@ -3180,13 +3173,13 @@ static void bdrv_aio_bh_cb(void *opaque)
qemu_aio_release(acb);
}
-static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
+BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque,
- int is_write)
+ bool is_write)
{
BlockDriverAIOCBSync *acb;
@@ -3207,21 +3200,6 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
return &acb->common;
}
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-}
-
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
-}
-
-
typedef struct BlockDriverAIOCBCoroutine {
BlockDriverAIOCB common;
BlockRequest req;
@@ -3404,13 +3382,8 @@ static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
};
BlockDriverAIOCB *acb;
- if (is_write) {
- acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
- bdrv_co_io_em_complete, &co);
- } else {
- acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
- bdrv_co_io_em_complete, &co);
- }
+ acb = bs->drv->bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
+ bdrv_co_io_em_complete, &co, is_write);
trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
if (!acb) {
@@ -189,6 +189,9 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
+BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, int64_t sector_num,
+ QEMUIOVector *iov, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write);
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
@@ -353,24 +353,9 @@ static BlockDriverAIOCB *inject_error(BlockDriverState *bs,
return &acb->common;
}
-static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
+static BlockDriverAIOCB *blkdebug_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVBlkdebugState *s = bs->opaque;
-
- if (s->vars.inject_errno) {
- return inject_error(bs, cb, opaque);
- }
-
- BlockDriverAIOCB *acb =
- bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
- return acb;
-}
-
-static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write)
{
BDRVBlkdebugState *s = bs->opaque;
@@ -379,7 +364,7 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
}
BlockDriverAIOCB *acb =
- bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
+ bdrv_aio_rw_vector(bs->file, sector_num, qiov, nb_sectors, cb, opaque, is_write);
return acb;
}
@@ -450,8 +435,7 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_file_open = blkdebug_open,
.bdrv_close = blkdebug_close,
- .bdrv_aio_readv = blkdebug_aio_readv,
- .bdrv_aio_writev = blkdebug_aio_writev,
+ .bdrv_aio_rw_vector = blkdebug_aio_rw_vector,
.bdrv_aio_flush = blkdebug_aio_flush,
.bdrv_debug_event = blkdebug_debug_event,
@@ -227,27 +227,6 @@ static void blkverify_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src,
}
}
-static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_write,
- int64_t sector_num, QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- BlkverifyAIOCB *acb = qemu_aio_get(&blkverify_aio_pool, bs, cb, opaque);
-
- acb->bh = NULL;
- acb->is_write = is_write;
- acb->sector_num = sector_num;
- acb->nb_sectors = nb_sectors;
- acb->ret = -EINPROGRESS;
- acb->done = 0;
- acb->qiov = qiov;
- acb->buf = NULL;
- acb->verify = NULL;
- acb->finished = NULL;
- return acb;
-}
-
static void blkverify_aio_bh(void *opaque)
{
BlkverifyAIOCB *acb = opaque;
@@ -297,38 +276,34 @@ static void blkverify_verify_readv(BlkverifyAIOCB *acb)
}
}
-static BlockDriverAIOCB *blkverify_aio_readv(BlockDriverState *bs,
+static BlockDriverAIOCB *blkverify_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write)
{
BDRVBlkverifyState *s = bs->opaque;
- BlkverifyAIOCB *acb = blkverify_aio_get(bs, false, sector_num, qiov,
- nb_sectors, cb, opaque);
-
- acb->verify = blkverify_verify_readv;
- acb->buf = qemu_blockalign(bs->file, qiov->size);
- qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
- blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
-
- bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,
- blkverify_aio_cb, acb);
- bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
- blkverify_aio_cb, acb);
- return &acb->common;
-}
+ BlkverifyAIOCB *acb = qemu_aio_get(&blkverify_aio_pool, bs, cb, opaque);
-static BlockDriverAIOCB *blkverify_aio_writev(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVBlkverifyState *s = bs->opaque;
- BlkverifyAIOCB *acb = blkverify_aio_get(bs, true, sector_num, qiov,
- nb_sectors, cb, opaque);
+ acb->bh = NULL;
+ acb->is_write = is_write;
+ acb->sector_num = sector_num;
+ acb->nb_sectors = nb_sectors;
+ acb->ret = -EINPROGRESS;
+ acb->done = 0;
+ acb->qiov = qiov;
+ acb->buf = NULL;
+ acb->verify = NULL;
+ acb->finished = NULL;
- bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors,
- blkverify_aio_cb, acb);
- bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
- blkverify_aio_cb, acb);
+ if (!is_write) {
+ acb->verify = blkverify_verify_readv;
+ acb->buf = qemu_blockalign(bs->file, qiov->size);
+ qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
+ blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
+ }
+ bdrv_aio_rw_vector(s->test_file, sector_num, qiov, nb_sectors,
+ blkverify_aio_cb, acb, is_write);
+ bdrv_aio_rw_vector(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
+ blkverify_aio_cb, acb, is_write);
return &acb->common;
}
@@ -353,8 +328,7 @@ static BlockDriver bdrv_blkverify = {
.bdrv_file_open = blkverify_open,
.bdrv_close = blkverify_close,
- .bdrv_aio_readv = blkverify_aio_readv,
- .bdrv_aio_writev = blkverify_aio_writev,
+ .bdrv_aio_rw_vector = blkverify_aio_rw_vector,
.bdrv_aio_flush = blkverify_aio_flush,
};
@@ -501,12 +501,17 @@ static void curl_readv_bh_cb(void *p)
}
-static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
+static BlockDriverAIOCB *curl_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write)
{
CURLAIOCB *acb;
+ if (is_write) {
+ errno = EROFS;
+ return NULL;
+ }
+
acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque);
acb->qiov = qiov;
@@ -563,7 +568,7 @@ static BlockDriver bdrv_http = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_aio_rw_vector = curl_aio_rw_vector,
};
static BlockDriver bdrv_https = {
@@ -575,7 +580,7 @@ static BlockDriver bdrv_https = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_aio_rw_vector = curl_aio_rw_vector,
};
static BlockDriver bdrv_ftp = {
@@ -587,7 +592,7 @@ static BlockDriver bdrv_ftp = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_aio_rw_vector = curl_aio_rw_vector,
};
static BlockDriver bdrv_ftps = {
@@ -599,7 +604,7 @@ static BlockDriver bdrv_ftps = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_aio_rw_vector = curl_aio_rw_vector,
};
static BlockDriver bdrv_tftp = {
@@ -611,7 +616,7 @@ static BlockDriver bdrv_tftp = {
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
- .bdrv_aio_readv = curl_aio_readv,
+ .bdrv_aio_rw_vector = curl_aio_rw_vector,
};
static void curl_block_init(void)
@@ -161,14 +161,16 @@ iscsi_readv_writev_bh_cb(void *p)
static void
-iscsi_aio_write10_cb(struct iscsi_context *iscsi, int status,
- void *command_data, void *opaque)
+iscsi_aio_rw10_cb(struct iscsi_context *iscsi, int status,
+ void *command_data, void *opaque)
{
IscsiAIOCB *acb = opaque;
- trace_iscsi_aio_write10_cb(iscsi, status, acb, acb->canceled);
+ trace_iscsi_aio_rw10_cb(iscsi, status, acb, acb->canceled);
- g_free(acb->buf);
+ if (acb->buf) {
+ g_free(acb->buf);
+ }
if (acb->canceled != 0) {
qemu_aio_release(acb);
@@ -179,7 +181,7 @@ iscsi_aio_write10_cb(struct iscsi_context *iscsi, int status,
acb->status = 0;
if (status < 0) {
- error_report("Failed to write10 data to iSCSI lun. %s",
+ error_report("Failed to read/write10 data from/to iSCSI lun. %s",
iscsi_get_error(iscsi));
acb->status = -EIO;
}
@@ -194,15 +196,10 @@ static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
}
-static BlockDriverAIOCB *
-iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
+static int
+iscsi_aio_writev(BlockDriverState *bs, IscsiAIOCB *acb, int64_t sector_num, int nb_sectors)
{
- IscsiLun *iscsilun = bs->opaque;
- struct iscsi_context *iscsi = iscsilun->iscsi;
- IscsiAIOCB *acb;
+ IscsiLun *iscsilun = acb->iscsilun;
size_t size;
int fua = 0;
@@ -211,86 +208,32 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
fua = 1;
}
- acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
- trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb);
-
- acb->iscsilun = iscsilun;
- acb->qiov = qiov;
-
- acb->canceled = 0;
-
/* XXX we should pass the iovec to write10 to avoid the extra copy */
/* this will allow us to get rid of 'buf' completely */
size = nb_sectors * BDRV_SECTOR_SIZE;
acb->buf = g_malloc(size);
qemu_iovec_to_buffer(acb->qiov, acb->buf);
- acb->task = iscsi_write10_task(iscsi, iscsilun->lun, acb->buf, size,
+ acb->task = iscsi_write10_task(iscsilun->iscsi, iscsilun->lun, acb->buf, size,
sector_qemu2lun(sector_num, iscsilun),
fua, 0, iscsilun->block_size,
- iscsi_aio_write10_cb, acb);
+ iscsi_aio_rw10_cb, acb);
if (acb->task == NULL) {
- error_report("iSCSI: Failed to send write10 command. %s",
- iscsi_get_error(iscsi));
g_free(acb->buf);
- qemu_aio_release(acb);
- return NULL;
- }
-
- iscsi_set_events(iscsilun);
-
- return &acb->common;
-}
-
-static void
-iscsi_aio_read10_cb(struct iscsi_context *iscsi, int status,
- void *command_data, void *opaque)
-{
- IscsiAIOCB *acb = opaque;
-
- trace_iscsi_aio_read10_cb(iscsi, status, acb, acb->canceled);
-
- if (acb->canceled != 0) {
- qemu_aio_release(acb);
- scsi_free_scsi_task(acb->task);
- acb->task = NULL;
- return;
- }
-
- acb->status = 0;
- if (status != 0) {
- error_report("Failed to read10 data from iSCSI lun. %s",
- iscsi_get_error(iscsi));
- acb->status = -EIO;
+ return -1;
}
-
- iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
- scsi_free_scsi_task(acb->task);
- acb->task = NULL;
+ return 0;
}
-static BlockDriverAIOCB *
-iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
+static int
+iscsi_aio_readv(BlockDriverState *bs, IscsiAIOCB *acb, int64_t sector_num, int nb_sectors)
{
- IscsiLun *iscsilun = bs->opaque;
- struct iscsi_context *iscsi = iscsilun->iscsi;
- IscsiAIOCB *acb;
+ IscsiLun *iscsilun = acb->iscsilun;
size_t qemu_read_size, lun_read_size;
int i;
qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;
- acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
- trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);
-
- acb->iscsilun = iscsilun;
- acb->qiov = qiov;
-
- acb->canceled = 0;
acb->read_size = qemu_read_size;
- acb->buf = NULL;
/* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU
* may be misaligned to the LUN, so we may need to read some extra
@@ -306,15 +249,12 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
lun_read_size = (qemu_read_size + iscsilun->block_size
+ acb->read_offset - 1)
/ iscsilun->block_size * iscsilun->block_size;
- acb->task = iscsi_read10_task(iscsi, iscsilun->lun,
+ acb->task = iscsi_read10_task(iscsilun->iscsi, iscsilun->lun,
sector_qemu2lun(sector_num, iscsilun),
lun_read_size, iscsilun->block_size,
- iscsi_aio_read10_cb, acb);
+ iscsi_aio_rw10_cb, acb);
if (acb->task == NULL) {
- error_report("iSCSI: Failed to send read10 command. %s",
- iscsi_get_error(iscsi));
- qemu_aio_release(acb);
- return NULL;
+ return -1;
}
for (i = 0; i < acb->qiov->niov; i++) {
@@ -323,6 +263,37 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
acb->qiov->iov[i].iov_base);
}
+ return 0;
+}
+
+static BlockDriverAIOCB *
+iscsi_aio_rw_vector(BlockDriverState *bs, int64_t sector_num,
+ QEMUIOVector *qiov, int nb_sectors,
+ BlockDriverCompletionFunc *cb,
+ void *opaque, bool is_write)
+{
+ IscsiLun *iscsilun = bs->opaque;
+ IscsiAIOCB *acb;
+ int ret;
+
+ acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
+ trace_iscsi_aio_rw_vector(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb, is_write);
+
+ acb->iscsilun = iscsilun;
+ acb->qiov = qiov;
+
+ acb->canceled = 0;
+ acb->buf = NULL;
+
+ ret = is_write ? iscsi_aio_writev(bs, acb, sector_num, nb_sectors)
+ : iscsi_aio_readv(bs, acb, sector_num, nb_sectors);
+ if (ret != 0) {
+ error_report("iSCSI: Failed to send read10/write10 command. %s",
+ iscsi_get_error(iscsilun->iscsi));
+ qemu_aio_release(acb);
+ return NULL;
+ }
+
iscsi_set_events(iscsilun);
return &acb->common;
@@ -697,8 +668,7 @@ static BlockDriver bdrv_iscsi = {
.bdrv_getlength = iscsi_getlength,
- .bdrv_aio_readv = iscsi_aio_readv,
- .bdrv_aio_writev = iscsi_aio_writev,
+ .bdrv_aio_rw_vector = iscsi_aio_rw_vector,
.bdrv_aio_flush = iscsi_aio_flush,
};
@@ -1331,23 +1331,14 @@ static BlockDriverAIOCB *qed_aio_setup(BlockDriverState *bs,
return &acb->common;
}
-static BlockDriverAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
+static BlockDriverAIOCB *bdrv_qed_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-}
-
-static BlockDriverAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
+ void *opaque, bool is_write)
{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb,
- opaque, QED_AIOCB_WRITE);
+ return
+ qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, is_write ? QED_AIOCB_WRITE : 0);
}
static BlockDriverAIOCB *bdrv_qed_aio_flush(BlockDriverState *bs,
@@ -1560,8 +1551,7 @@ static BlockDriver bdrv_qed = {
.bdrv_create = bdrv_qed_create,
.bdrv_co_is_allocated = bdrv_qed_co_is_allocated,
.bdrv_make_empty = bdrv_qed_make_empty,
- .bdrv_aio_readv = bdrv_qed_aio_readv,
- .bdrv_aio_writev = bdrv_qed_aio_writev,
+ .bdrv_aio_rw_vector = bdrv_qed_aio_rw_vector,
.bdrv_aio_flush = bdrv_qed_aio_flush,
.bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes,
.bdrv_truncate = bdrv_qed_truncate,
@@ -312,11 +312,12 @@ static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
return 1;
}
-static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
+static BlockDriverAIOCB *raw_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque, int type)
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write)
{
BDRVRawState *s = bs->opaque;
+ int type = is_write ? QEMU_AIO_WRITE : QEMU_AIO_READ;
if (fd_open(bs) < 0)
return NULL;
@@ -341,22 +342,6 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
cb, opaque, type);
}
-static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
- cb, opaque, QEMU_AIO_READ);
-}
-
-static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
- cb, opaque, QEMU_AIO_WRITE);
-}
-
static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
@@ -635,8 +620,7 @@ static BlockDriver bdrv_file = {
.bdrv_create = raw_create,
.bdrv_co_discard = raw_co_discard,
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
+ .bdrv_aio_rw_vector = raw_aio_rw_vector,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_truncate = raw_truncate,
@@ -903,8 +887,7 @@ static BlockDriver bdrv_host_device = {
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
+ .bdrv_aio_rw_vector = raw_aio_rw_vector,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_truncate = raw_truncate,
@@ -1022,8 +1005,7 @@ static BlockDriver bdrv_host_floppy = {
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
+ .bdrv_aio_rw_vector = raw_aio_rw_vector,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_truncate = raw_truncate,
@@ -1121,8 +1103,7 @@ static BlockDriver bdrv_host_cdrom = {
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
+ .bdrv_aio_rw_vector = raw_aio_rw_vector,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_truncate = raw_truncate,
@@ -1240,8 +1221,7 @@ static BlockDriver bdrv_host_cdrom = {
.create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
+ .bdrv_aio_rw_vector = raw_aio_rw_vector,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_truncate = raw_truncate,
@@ -617,12 +617,12 @@ static void rbd_aio_bh_cb(void *opaque)
qemu_aio_release(acb);
}
-static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque, int write)
+static BlockDriverAIOCB *qemu_rbd_aio_rw_vector(BlockDriverState *bs,
+ int64_t sector_num,
+ QEMUIOVector *qiov,
+ int nb_sectors,
+ BlockDriverCompletionFunc *cb,
+ void *opaque, bool is_write)
{
RBDAIOCB *acb;
RADOSCB *rcb;
@@ -634,7 +634,7 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs,
BDRVRBDState *s = bs->opaque;
acb = qemu_aio_get(&rbd_aio_pool, bs, cb, opaque);
- acb->write = write;
+ acb->write = is_write;
acb->qiov = qiov;
acb->bounce = qemu_blockalign(bs, qiov->size);
acb->ret = 0;
@@ -643,7 +643,7 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs,
acb->cancelled = 0;
acb->bh = NULL;
- if (write) {
+ if (is_write) {
qemu_iovec_to_buffer(acb->qiov, acb->bounce);
}
@@ -665,11 +665,8 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs,
goto failed;
}
- if (write) {
- r = rbd_aio_write(s->image, off, size, buf, c);
- } else {
- r = rbd_aio_read(s->image, off, size, buf, c);
- }
+ r = is_write ? rbd_aio_write(s->image, off, size, buf, c)
+ : rbd_aio_read(s->image, off, size, buf, c);
if (r < 0) {
goto failed;
@@ -684,26 +681,6 @@ failed:
return NULL;
}
-static BlockDriverAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-}
-
-static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
-}
-
static int qemu_rbd_co_flush(BlockDriverState *bs)
{
#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
@@ -877,8 +854,7 @@ static BlockDriver bdrv_rbd = {
.bdrv_truncate = qemu_rbd_truncate,
.protocol_name = "rbd",
- .bdrv_aio_readv = qemu_rbd_aio_readv,
- .bdrv_aio_writev = qemu_rbd_aio_writev,
+ .bdrv_aio_rw_vector = qemu_rbd_aio_rw_vector,
.bdrv_co_flush_to_disk = qemu_rbd_co_flush,
.bdrv_snapshot_create = qemu_rbd_snap_create,
@@ -642,15 +642,22 @@ done:
qemu_aio_release(acb);
}
-static BlockDriverAIOCB *vdi_aio_readv(BlockDriverState *bs,
+static BlockDriverAIOCB *vdi_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write)
{
VdiAIOCB *acb;
int ret;
+#if !defined(CONFIG_VDI_WRITE)
+ if (is_write) {
+ errno = ENOSYS;
+ return NULL;
+ }
+#endif
+
logout("\n");
- acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
+ acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, is_write);
ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
if (ret < 0) {
if (acb->qiov->niov > 1) {
@@ -796,27 +803,6 @@ done:
qemu_aio_release(acb);
}
-static BlockDriverAIOCB *vdi_aio_writev(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- VdiAIOCB *acb;
- int ret;
-
- logout("\n");
- acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
- ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
- if (ret < 0) {
- if (acb->qiov->niov > 1) {
- qemu_vfree(acb->orig_buf);
- }
- qemu_aio_release(acb);
- return NULL;
- }
-
- return &acb->common;
-}
-
static int vdi_create(const char *filename, QEMUOptionParameter *options)
{
int fd;
@@ -973,10 +959,7 @@ static BlockDriver bdrv_vdi = {
.bdrv_co_is_allocated = vdi_co_is_allocated,
.bdrv_make_empty = vdi_make_empty,
- .bdrv_aio_readv = vdi_aio_readv,
-#if defined(CONFIG_VDI_WRITE)
- .bdrv_aio_writev = vdi_aio_writev,
-#endif
+ .bdrv_aio_rw_vector = vdi_aio_rw_vector,
.bdrv_get_info = vdi_get_info,
@@ -113,12 +113,9 @@ struct BlockDriver {
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
int (*bdrv_make_empty)(BlockDriverState *bs);
/* aio */
- BlockDriverAIOCB *(*bdrv_aio_readv)(BlockDriverState *bs,
+ BlockDriverAIOCB *(*bdrv_aio_rw_vector)(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- BlockDriverAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
+ BlockDriverCompletionFunc *cb, void *opaque, bool is_write);
BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
@@ -524,10 +524,8 @@ escc_kbd_command(int val) "Command %d"
escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
# block/iscsi.c
-iscsi_aio_write10_cb(void *iscsi, int status, void *acb, int canceled) "iscsi %p status %d acb %p canceled %d"
-iscsi_aio_writev(void *iscsi, int64_t sector_num, int nb_sectors, void *opaque, void *acb) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p acb %p"
-iscsi_aio_read10_cb(void *iscsi, int status, void *acb, int canceled) "iscsi %p status %d acb %p canceled %d"
-iscsi_aio_readv(void *iscsi, int64_t sector_num, int nb_sectors, void *opaque, void *acb) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p acb %p"
+iscsi_aio_rw10_cb(void *iscsi, int status, void *acb, int canceled) "iscsi %p status %d acb %p canceled %d"
+iscsi_aio_rw_vector(void *iscsi, int64_t sector_num, int nb_sectors, void *opaque, void *acb, bool is_write) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p acb %p is_write %d"
# hw/esp.c
esp_raise_irq(void) "Raise IRQ"
iscsi block driver may receive some additional work. For now, some common code has been moved out of iscsi_aio_writev() and iscsi_aio_readv() into iscsi_aio_rw_vector(). Leftovers there can be optimized further, and consolidated into the rw_vector too. Read and write callbacks are consolidated as well, and once the XXX "todo" bounce-buffer change is complete the only difference there should go away too. Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> --- block.c | 39 ++------------- block.h | 3 + block/blkdebug.c | 24 ++-------- block/blkverify.c | 74 +++++++++-------------------- block/curl.c | 19 +++++--- block/iscsi.c | 134 ++++++++++++++++++++-------------------------------- block/qed.c | 20 ++------ block/raw-posix.c | 36 +++----------- block/rbd.c | 46 ++++-------------- block/vdi.c | 39 ++++----------- block_int.h | 7 +-- trace-events | 6 +-- 12 files changed, 140 insertions(+), 307 deletions(-)