block: use aio_bh_schedule_oneshot
This simplifies bottom half handlers by removing calls to qemu_bh_delete and thus removing the need to stash the bottom half pointer in the opaque datum. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
5b8bb3595a
commit
fffb6e1223
|
@ -87,7 +87,6 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct ArchipelagoAIOCB {
|
typedef struct ArchipelagoAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
struct BDRVArchipelagoState *s;
|
struct BDRVArchipelagoState *s;
|
||||||
QEMUIOVector *qiov;
|
QEMUIOVector *qiov;
|
||||||
ARCHIPCmd cmd;
|
ARCHIPCmd cmd;
|
||||||
|
@ -154,11 +153,10 @@ static void archipelago_finish_aiocb(AIORequestData *reqdata)
|
||||||
} else if (reqdata->aio_cb->ret == reqdata->segreq->total) {
|
} else if (reqdata->aio_cb->ret == reqdata->segreq->total) {
|
||||||
reqdata->aio_cb->ret = 0;
|
reqdata->aio_cb->ret = 0;
|
||||||
}
|
}
|
||||||
reqdata->aio_cb->bh = aio_bh_new(
|
aio_bh_schedule_oneshot(
|
||||||
bdrv_get_aio_context(reqdata->aio_cb->common.bs),
|
bdrv_get_aio_context(reqdata->aio_cb->common.bs),
|
||||||
qemu_archipelago_complete_aio, reqdata
|
qemu_archipelago_complete_aio, reqdata
|
||||||
);
|
);
|
||||||
qemu_bh_schedule(reqdata->aio_cb->bh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_reply(struct xseg *xseg, xport srcport, struct xseg_port *port,
|
static int wait_reply(struct xseg *xseg, xport srcport, struct xseg_port *port,
|
||||||
|
@ -313,7 +311,6 @@ static void qemu_archipelago_complete_aio(void *opaque)
|
||||||
AIORequestData *reqdata = (AIORequestData *) opaque;
|
AIORequestData *reqdata = (AIORequestData *) opaque;
|
||||||
ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) reqdata->aio_cb;
|
ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) reqdata->aio_cb;
|
||||||
|
|
||||||
qemu_bh_delete(aio_cb->bh);
|
|
||||||
aio_cb->common.cb(aio_cb->common.opaque, aio_cb->ret);
|
aio_cb->common.cb(aio_cb->common.opaque, aio_cb->ret);
|
||||||
aio_cb->status = 0;
|
aio_cb->status = 0;
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ typedef struct BDRVBlkdebugState {
|
||||||
|
|
||||||
typedef struct BlkdebugAIOCB {
|
typedef struct BlkdebugAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
int ret;
|
int ret;
|
||||||
} BlkdebugAIOCB;
|
} BlkdebugAIOCB;
|
||||||
|
|
||||||
|
@ -410,7 +409,6 @@ out:
|
||||||
static void error_callback_bh(void *opaque)
|
static void error_callback_bh(void *opaque)
|
||||||
{
|
{
|
||||||
struct BlkdebugAIOCB *acb = opaque;
|
struct BlkdebugAIOCB *acb = opaque;
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
acb->common.cb(acb->common.opaque, acb->ret);
|
acb->common.cb(acb->common.opaque, acb->ret);
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
@ -421,7 +419,6 @@ static BlockAIOCB *inject_error(BlockDriverState *bs,
|
||||||
BDRVBlkdebugState *s = bs->opaque;
|
BDRVBlkdebugState *s = bs->opaque;
|
||||||
int error = rule->options.inject.error;
|
int error = rule->options.inject.error;
|
||||||
struct BlkdebugAIOCB *acb;
|
struct BlkdebugAIOCB *acb;
|
||||||
QEMUBH *bh;
|
|
||||||
bool immediately = rule->options.inject.immediately;
|
bool immediately = rule->options.inject.immediately;
|
||||||
|
|
||||||
if (rule->options.inject.once) {
|
if (rule->options.inject.once) {
|
||||||
|
@ -436,9 +433,7 @@ static BlockAIOCB *inject_error(BlockDriverState *bs,
|
||||||
acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque);
|
acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque);
|
||||||
acb->ret = -error;
|
acb->ret = -error;
|
||||||
|
|
||||||
bh = aio_bh_new(bdrv_get_aio_context(bs), error_callback_bh, acb);
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), error_callback_bh, acb);
|
||||||
acb->bh = bh;
|
|
||||||
qemu_bh_schedule(bh);
|
|
||||||
|
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ typedef struct {
|
||||||
typedef struct BlkverifyAIOCB BlkverifyAIOCB;
|
typedef struct BlkverifyAIOCB BlkverifyAIOCB;
|
||||||
struct BlkverifyAIOCB {
|
struct BlkverifyAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
|
|
||||||
/* Request metadata */
|
/* Request metadata */
|
||||||
bool is_write;
|
bool is_write;
|
||||||
|
@ -175,7 +174,6 @@ static BlkverifyAIOCB *blkverify_aio_get(BlockDriverState *bs, bool is_write,
|
||||||
{
|
{
|
||||||
BlkverifyAIOCB *acb = qemu_aio_get(&blkverify_aiocb_info, bs, cb, opaque);
|
BlkverifyAIOCB *acb = qemu_aio_get(&blkverify_aiocb_info, bs, cb, opaque);
|
||||||
|
|
||||||
acb->bh = NULL;
|
|
||||||
acb->is_write = is_write;
|
acb->is_write = is_write;
|
||||||
acb->sector_num = sector_num;
|
acb->sector_num = sector_num;
|
||||||
acb->nb_sectors = nb_sectors;
|
acb->nb_sectors = nb_sectors;
|
||||||
|
@ -191,7 +189,6 @@ static void blkverify_aio_bh(void *opaque)
|
||||||
{
|
{
|
||||||
BlkverifyAIOCB *acb = opaque;
|
BlkverifyAIOCB *acb = opaque;
|
||||||
|
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
if (acb->buf) {
|
if (acb->buf) {
|
||||||
qemu_iovec_destroy(&acb->raw_qiov);
|
qemu_iovec_destroy(&acb->raw_qiov);
|
||||||
qemu_vfree(acb->buf);
|
qemu_vfree(acb->buf);
|
||||||
|
@ -218,9 +215,8 @@ static void blkverify_aio_cb(void *opaque, int ret)
|
||||||
acb->verify(acb);
|
acb->verify(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
|
||||||
blkverify_aio_bh, acb);
|
blkverify_aio_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,6 @@ struct BlockBackend {
|
||||||
|
|
||||||
typedef struct BlockBackendAIOCB {
|
typedef struct BlockBackendAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
int ret;
|
int ret;
|
||||||
} BlockBackendAIOCB;
|
} BlockBackendAIOCB;
|
||||||
|
@ -898,7 +897,6 @@ int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
|
||||||
static void error_callback_bh(void *opaque)
|
static void error_callback_bh(void *opaque)
|
||||||
{
|
{
|
||||||
struct BlockBackendAIOCB *acb = opaque;
|
struct BlockBackendAIOCB *acb = opaque;
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
acb->common.cb(acb->common.opaque, acb->ret);
|
acb->common.cb(acb->common.opaque, acb->ret);
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
@ -908,16 +906,12 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
|
||||||
void *opaque, int ret)
|
void *opaque, int ret)
|
||||||
{
|
{
|
||||||
struct BlockBackendAIOCB *acb;
|
struct BlockBackendAIOCB *acb;
|
||||||
QEMUBH *bh;
|
|
||||||
|
|
||||||
acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
|
acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
|
||||||
acb->blk = blk;
|
acb->blk = blk;
|
||||||
acb->ret = ret;
|
acb->ret = ret;
|
||||||
|
|
||||||
bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb);
|
aio_bh_schedule_oneshot(blk_get_aio_context(blk), error_callback_bh, acb);
|
||||||
acb->bh = bh;
|
|
||||||
qemu_bh_schedule(bh);
|
|
||||||
|
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,7 +920,6 @@ typedef struct BlkAioEmAIOCB {
|
||||||
BlkRwCo rwco;
|
BlkRwCo rwco;
|
||||||
int bytes;
|
int bytes;
|
||||||
bool has_returned;
|
bool has_returned;
|
||||||
QEMUBH* bh;
|
|
||||||
} BlkAioEmAIOCB;
|
} BlkAioEmAIOCB;
|
||||||
|
|
||||||
static const AIOCBInfo blk_aio_em_aiocb_info = {
|
static const AIOCBInfo blk_aio_em_aiocb_info = {
|
||||||
|
@ -935,10 +928,6 @@ static const AIOCBInfo blk_aio_em_aiocb_info = {
|
||||||
|
|
||||||
static void blk_aio_complete(BlkAioEmAIOCB *acb)
|
static void blk_aio_complete(BlkAioEmAIOCB *acb)
|
||||||
{
|
{
|
||||||
if (acb->bh) {
|
|
||||||
assert(acb->has_returned);
|
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
}
|
|
||||||
if (acb->has_returned) {
|
if (acb->has_returned) {
|
||||||
acb->common.cb(acb->common.opaque, acb->rwco.ret);
|
acb->common.cb(acb->common.opaque, acb->rwco.ret);
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
|
@ -947,7 +936,10 @@ static void blk_aio_complete(BlkAioEmAIOCB *acb)
|
||||||
|
|
||||||
static void blk_aio_complete_bh(void *opaque)
|
static void blk_aio_complete_bh(void *opaque)
|
||||||
{
|
{
|
||||||
blk_aio_complete(opaque);
|
BlkAioEmAIOCB *acb = opaque;
|
||||||
|
|
||||||
|
assert(acb->has_returned);
|
||||||
|
blk_aio_complete(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
||||||
|
@ -967,7 +959,6 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
||||||
.ret = NOT_DONE,
|
.ret = NOT_DONE,
|
||||||
};
|
};
|
||||||
acb->bytes = bytes;
|
acb->bytes = bytes;
|
||||||
acb->bh = NULL;
|
|
||||||
acb->has_returned = false;
|
acb->has_returned = false;
|
||||||
|
|
||||||
co = qemu_coroutine_create(co_entry, acb);
|
co = qemu_coroutine_create(co_entry, acb);
|
||||||
|
@ -975,8 +966,8 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
||||||
|
|
||||||
acb->has_returned = true;
|
acb->has_returned = true;
|
||||||
if (acb->rwco.ret != NOT_DONE) {
|
if (acb->rwco.ret != NOT_DONE) {
|
||||||
acb->bh = aio_bh_new(blk_get_aio_context(blk), blk_aio_complete_bh, acb);
|
aio_bh_schedule_oneshot(blk_get_aio_context(blk),
|
||||||
qemu_bh_schedule(acb->bh);
|
blk_aio_complete_bh, acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
|
|
|
@ -96,7 +96,6 @@ struct BDRVCURLState;
|
||||||
|
|
||||||
typedef struct CURLAIOCB {
|
typedef struct CURLAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
QEMUIOVector *qiov;
|
QEMUIOVector *qiov;
|
||||||
|
|
||||||
int64_t sector_num;
|
int64_t sector_num;
|
||||||
|
@ -739,9 +738,6 @@ static void curl_readv_bh_cb(void *p)
|
||||||
CURLAIOCB *acb = p;
|
CURLAIOCB *acb = p;
|
||||||
BDRVCURLState *s = acb->common.bs->opaque;
|
BDRVCURLState *s = acb->common.bs->opaque;
|
||||||
|
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
acb->bh = NULL;
|
|
||||||
|
|
||||||
size_t start = acb->sector_num * SECTOR_SIZE;
|
size_t start = acb->sector_num * SECTOR_SIZE;
|
||||||
size_t end;
|
size_t end;
|
||||||
|
|
||||||
|
@ -805,8 +801,7 @@ static BlockAIOCB *curl_aio_readv(BlockDriverState *bs,
|
||||||
acb->sector_num = sector_num;
|
acb->sector_num = sector_num;
|
||||||
acb->nb_sectors = nb_sectors;
|
acb->nb_sectors = nb_sectors;
|
||||||
|
|
||||||
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), curl_readv_bh_cb, acb);
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), curl_readv_bh_cb, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
typedef struct GlusterAIOCB {
|
typedef struct GlusterAIOCB {
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int ret;
|
int ret;
|
||||||
QEMUBH *bh;
|
|
||||||
Coroutine *coroutine;
|
Coroutine *coroutine;
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
} GlusterAIOCB;
|
} GlusterAIOCB;
|
||||||
|
@ -622,8 +621,6 @@ static void qemu_gluster_complete_aio(void *opaque)
|
||||||
{
|
{
|
||||||
GlusterAIOCB *acb = (GlusterAIOCB *)opaque;
|
GlusterAIOCB *acb = (GlusterAIOCB *)opaque;
|
||||||
|
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
acb->bh = NULL;
|
|
||||||
qemu_coroutine_enter(acb->coroutine);
|
qemu_coroutine_enter(acb->coroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,8 +639,7 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
|
||||||
acb->ret = -EIO; /* Partial read/write - fail it */
|
acb->ret = -EIO; /* Partial read/write - fail it */
|
||||||
}
|
}
|
||||||
|
|
||||||
acb->bh = aio_bh_new(acb->aio_context, qemu_gluster_complete_aio, acb);
|
aio_bh_schedule_oneshot(acb->aio_context, qemu_gluster_complete_aio, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
|
static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
|
||||||
|
|
11
block/io.c
11
block/io.c
|
@ -171,7 +171,6 @@ static void bdrv_drain_recurse(BlockDriverState *bs)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
QEMUBH *bh;
|
|
||||||
bool done;
|
bool done;
|
||||||
} BdrvCoDrainData;
|
} BdrvCoDrainData;
|
||||||
|
|
||||||
|
@ -191,7 +190,6 @@ static void bdrv_co_drain_bh_cb(void *opaque)
|
||||||
BdrvCoDrainData *data = opaque;
|
BdrvCoDrainData *data = opaque;
|
||||||
Coroutine *co = data->co;
|
Coroutine *co = data->co;
|
||||||
|
|
||||||
qemu_bh_delete(data->bh);
|
|
||||||
bdrv_drain_poll(data->bs);
|
bdrv_drain_poll(data->bs);
|
||||||
data->done = true;
|
data->done = true;
|
||||||
qemu_coroutine_enter(co);
|
qemu_coroutine_enter(co);
|
||||||
|
@ -210,9 +208,9 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
|
||||||
.co = qemu_coroutine_self(),
|
.co = qemu_coroutine_self(),
|
||||||
.bs = bs,
|
.bs = bs,
|
||||||
.done = false,
|
.done = false,
|
||||||
.bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_drain_bh_cb, &data),
|
|
||||||
};
|
};
|
||||||
qemu_bh_schedule(data.bh);
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs),
|
||||||
|
bdrv_co_drain_bh_cb, &data);
|
||||||
|
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
/* If we are resumed from some other event (such as an aio completion or a
|
/* If we are resumed from some other event (such as an aio completion or a
|
||||||
|
@ -2095,7 +2093,6 @@ typedef struct BlockAIOCBCoroutine {
|
||||||
bool is_write;
|
bool is_write;
|
||||||
bool need_bh;
|
bool need_bh;
|
||||||
bool *done;
|
bool *done;
|
||||||
QEMUBH* bh;
|
|
||||||
} BlockAIOCBCoroutine;
|
} BlockAIOCBCoroutine;
|
||||||
|
|
||||||
static const AIOCBInfo bdrv_em_co_aiocb_info = {
|
static const AIOCBInfo bdrv_em_co_aiocb_info = {
|
||||||
|
@ -2115,7 +2112,6 @@ static void bdrv_co_em_bh(void *opaque)
|
||||||
BlockAIOCBCoroutine *acb = opaque;
|
BlockAIOCBCoroutine *acb = opaque;
|
||||||
|
|
||||||
assert(!acb->need_bh);
|
assert(!acb->need_bh);
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
bdrv_co_complete(acb);
|
bdrv_co_complete(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2125,8 +2121,7 @@ static void bdrv_co_maybe_schedule_bh(BlockAIOCBCoroutine *acb)
|
||||||
if (acb->req.error != -EINPROGRESS) {
|
if (acb->req.error != -EINPROGRESS) {
|
||||||
BlockDriverState *bs = acb->common.bs;
|
BlockDriverState *bs = acb->common.bs;
|
||||||
|
|
||||||
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,6 @@ typedef struct IscsiTask {
|
||||||
int do_retry;
|
int do_retry;
|
||||||
struct scsi_task *task;
|
struct scsi_task *task;
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
QEMUBH *bh;
|
|
||||||
IscsiLun *iscsilun;
|
IscsiLun *iscsilun;
|
||||||
QEMUTimer retry_timer;
|
QEMUTimer retry_timer;
|
||||||
int err_code;
|
int err_code;
|
||||||
|
@ -167,7 +166,6 @@ static void iscsi_co_generic_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
struct IscsiTask *iTask = opaque;
|
struct IscsiTask *iTask = opaque;
|
||||||
iTask->complete = 1;
|
iTask->complete = 1;
|
||||||
qemu_bh_delete(iTask->bh);
|
|
||||||
qemu_coroutine_enter(iTask->co);
|
qemu_coroutine_enter(iTask->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,9 +297,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (iTask->co) {
|
if (iTask->co) {
|
||||||
iTask->bh = aio_bh_new(iTask->iscsilun->aio_context,
|
aio_bh_schedule_oneshot(iTask->iscsilun->aio_context,
|
||||||
iscsi_co_generic_bh_cb, iTask);
|
iscsi_co_generic_bh_cb, iTask);
|
||||||
qemu_bh_schedule(iTask->bh);
|
|
||||||
} else {
|
} else {
|
||||||
iTask->complete = 1;
|
iTask->complete = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ typedef struct NFSRPC {
|
||||||
QEMUIOVector *iov;
|
QEMUIOVector *iov;
|
||||||
struct stat *st;
|
struct stat *st;
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
QEMUBH *bh;
|
|
||||||
NFSClient *client;
|
NFSClient *client;
|
||||||
} NFSRPC;
|
} NFSRPC;
|
||||||
|
|
||||||
|
@ -103,7 +102,6 @@ static void nfs_co_generic_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
NFSRPC *task = opaque;
|
NFSRPC *task = opaque;
|
||||||
task->complete = 1;
|
task->complete = 1;
|
||||||
qemu_bh_delete(task->bh);
|
|
||||||
qemu_coroutine_enter(task->co);
|
qemu_coroutine_enter(task->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +125,8 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
||||||
error_report("NFS Error: %s", nfs_get_error(nfs));
|
error_report("NFS Error: %s", nfs_get_error(nfs));
|
||||||
}
|
}
|
||||||
if (task->co) {
|
if (task->co) {
|
||||||
task->bh = aio_bh_new(task->client->aio_context,
|
aio_bh_schedule_oneshot(task->client->aio_context,
|
||||||
nfs_co_generic_bh_cb, task);
|
nfs_co_generic_bh_cb, task);
|
||||||
qemu_bh_schedule(task->bh);
|
|
||||||
} else {
|
} else {
|
||||||
task->complete = 1;
|
task->complete = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,6 @@ static coroutine_fn int null_co_flush(BlockDriverState *bs)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
QEMUTimer timer;
|
QEMUTimer timer;
|
||||||
} NullAIOCB;
|
} NullAIOCB;
|
||||||
|
|
||||||
|
@ -136,7 +135,6 @@ static void null_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
NullAIOCB *acb = opaque;
|
NullAIOCB *acb = opaque;
|
||||||
acb->common.cb(acb->common.opaque, 0);
|
acb->common.cb(acb->common.opaque, 0);
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,8 +162,7 @@ static inline BlockAIOCB *null_aio_common(BlockDriverState *bs,
|
||||||
timer_mod_ns(&acb->timer,
|
timer_mod_ns(&acb->timer,
|
||||||
qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + s->latency_ns);
|
qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + s->latency_ns);
|
||||||
} else {
|
} else {
|
||||||
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), null_bh_cb, acb);
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), null_bh_cb, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
}
|
}
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
}
|
}
|
||||||
|
|
|
@ -909,7 +909,6 @@ static void qed_aio_complete_bh(void *opaque)
|
||||||
void *user_opaque = acb->common.opaque;
|
void *user_opaque = acb->common.opaque;
|
||||||
int ret = acb->bh_ret;
|
int ret = acb->bh_ret;
|
||||||
|
|
||||||
qemu_bh_delete(acb->bh);
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
|
|
||||||
/* Invoke callback */
|
/* Invoke callback */
|
||||||
|
@ -934,9 +933,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
|
||||||
|
|
||||||
/* Arrange for a bh to invoke the completion function */
|
/* Arrange for a bh to invoke the completion function */
|
||||||
acb->bh_ret = ret;
|
acb->bh_ret = ret;
|
||||||
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
|
||||||
qed_aio_complete_bh, acb);
|
qed_aio_complete_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
|
|
||||||
/* Start next allocating write request waiting behind this one. Note that
|
/* Start next allocating write request waiting behind this one. Note that
|
||||||
* requests enqueue themselves when they first hit an unallocated cluster
|
* requests enqueue themselves when they first hit an unallocated cluster
|
||||||
|
|
|
@ -130,7 +130,6 @@ enum {
|
||||||
|
|
||||||
typedef struct QEDAIOCB {
|
typedef struct QEDAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
int bh_ret; /* final return status for completion bh */
|
int bh_ret; /* final return status for completion bh */
|
||||||
QSIMPLEQ_ENTRY(QEDAIOCB) next; /* next request */
|
QSIMPLEQ_ENTRY(QEDAIOCB) next; /* next request */
|
||||||
int flags; /* QED_AIOCB_* bits ORed together */
|
int flags; /* QED_AIOCB_* bits ORed together */
|
||||||
|
|
|
@ -71,7 +71,6 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct RBDAIOCB {
|
typedef struct RBDAIOCB {
|
||||||
BlockAIOCB common;
|
BlockAIOCB common;
|
||||||
QEMUBH *bh;
|
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
QEMUIOVector *qiov;
|
QEMUIOVector *qiov;
|
||||||
char *bounce;
|
char *bounce;
|
||||||
|
@ -602,7 +601,6 @@ static const AIOCBInfo rbd_aiocb_info = {
|
||||||
static void rbd_finish_bh(void *opaque)
|
static void rbd_finish_bh(void *opaque)
|
||||||
{
|
{
|
||||||
RADOSCB *rcb = opaque;
|
RADOSCB *rcb = opaque;
|
||||||
qemu_bh_delete(rcb->acb->bh);
|
|
||||||
qemu_rbd_complete_aio(rcb);
|
qemu_rbd_complete_aio(rcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,9 +619,8 @@ static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb)
|
||||||
rcb->ret = rbd_aio_get_return_value(c);
|
rcb->ret = rbd_aio_get_return_value(c);
|
||||||
rbd_aio_release(c);
|
rbd_aio_release(c);
|
||||||
|
|
||||||
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
|
aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
|
||||||
rbd_finish_bh, rcb);
|
rbd_finish_bh, rcb);
|
||||||
qemu_bh_schedule(acb->bh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_aio_discard_wrapper(rbd_image_t image,
|
static int rbd_aio_discard_wrapper(rbd_image_t image,
|
||||||
|
@ -679,7 +676,6 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->error = 0;
|
acb->error = 0;
|
||||||
acb->s = s;
|
acb->s = s;
|
||||||
acb->bh = NULL;
|
|
||||||
|
|
||||||
if (cmd == RBD_AIO_WRITE) {
|
if (cmd == RBD_AIO_WRITE) {
|
||||||
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
||||||
|
|
|
@ -588,7 +588,6 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BlockJob *job;
|
BlockJob *job;
|
||||||
QEMUBH *bh;
|
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
BlockJobDeferToMainLoopFn *fn;
|
BlockJobDeferToMainLoopFn *fn;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
@ -599,8 +598,6 @@ static void block_job_defer_to_main_loop_bh(void *opaque)
|
||||||
BlockJobDeferToMainLoopData *data = opaque;
|
BlockJobDeferToMainLoopData *data = opaque;
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
|
|
||||||
qemu_bh_delete(data->bh);
|
|
||||||
|
|
||||||
/* Prevent race with block_job_defer_to_main_loop() */
|
/* Prevent race with block_job_defer_to_main_loop() */
|
||||||
aio_context_acquire(data->aio_context);
|
aio_context_acquire(data->aio_context);
|
||||||
|
|
||||||
|
@ -624,13 +621,13 @@ void block_job_defer_to_main_loop(BlockJob *job,
|
||||||
{
|
{
|
||||||
BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data));
|
BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data));
|
||||||
data->job = job;
|
data->job = job;
|
||||||
data->bh = qemu_bh_new(block_job_defer_to_main_loop_bh, data);
|
|
||||||
data->aio_context = blk_get_aio_context(job->blk);
|
data->aio_context = blk_get_aio_context(job->blk);
|
||||||
data->fn = fn;
|
data->fn = fn;
|
||||||
data->opaque = opaque;
|
data->opaque = opaque;
|
||||||
job->deferred_to_main_loop = true;
|
job->deferred_to_main_loop = true;
|
||||||
|
|
||||||
qemu_bh_schedule(data->bh);
|
aio_bh_schedule_oneshot(qemu_get_aio_context(),
|
||||||
|
block_job_defer_to_main_loop_bh, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockJobTxn *block_job_txn_new(void)
|
BlockJobTxn *block_job_txn_new(void)
|
||||||
|
|
Loading…
Reference in New Issue