mirror of
https://github.com/qemu/qemu.git
synced 2024-11-23 19:03:38 +08:00
block: distinguish between bdrv_create running in coroutine and not
Call two different functions depending on whether bdrv_create is in coroutine or not, following the same pattern as generated_co_wrapper functions. This allows to also call the coroutine function directly, without using CreateCo or relying in bdrv_create(). Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Message-Id: <20221128142337.657646-8-eesposit@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
a212e675cd
commit
84bdf21f97
71
block.c
71
block.c
@ -526,63 +526,62 @@ typedef struct CreateCo {
|
||||
Error *err;
|
||||
} CreateCo;
|
||||
|
||||
static int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
|
||||
QemuOpts *opts, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
GLOBAL_STATE_CODE();
|
||||
ERRP_GUARD();
|
||||
|
||||
if (!drv->bdrv_co_create_opts) {
|
||||
error_setg(errp, "Driver '%s' does not support image creation",
|
||||
drv->format_name);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ret = drv->bdrv_co_create_opts(drv, filename, opts, errp);
|
||||
if (ret < 0 && !*errp) {
|
||||
error_setg_errno(errp, -ret, "Could not create image");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
CreateCo *cco = opaque;
|
||||
assert(cco->drv);
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
ret = cco->drv->bdrv_co_create_opts(cco->drv,
|
||||
cco->filename, cco->opts, &local_err);
|
||||
error_propagate(&cco->err, local_err);
|
||||
cco->ret = ret;
|
||||
cco->ret = bdrv_co_create(cco->drv, cco->filename, cco->opts, &cco->err);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||
QemuOpts *opts, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
Coroutine *co;
|
||||
CreateCo cco = {
|
||||
.drv = drv,
|
||||
.filename = filename,
|
||||
.opts = opts,
|
||||
.ret = NOT_DONE,
|
||||
.err = NULL,
|
||||
};
|
||||
|
||||
if (!drv->bdrv_co_create_opts) {
|
||||
error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (qemu_in_coroutine()) {
|
||||
/* Fast-path if already in coroutine context */
|
||||
bdrv_create_co_entry(&cco);
|
||||
return bdrv_co_create(drv, filename, opts, errp);
|
||||
} else {
|
||||
Coroutine *co;
|
||||
CreateCo cco = {
|
||||
.drv = drv,
|
||||
.filename = filename,
|
||||
.opts = opts,
|
||||
.ret = NOT_DONE,
|
||||
.err = NULL,
|
||||
};
|
||||
|
||||
co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
|
||||
qemu_coroutine_enter(co);
|
||||
while (cco.ret == NOT_DONE) {
|
||||
aio_poll(qemu_get_aio_context(), true);
|
||||
}
|
||||
error_propagate(errp, cco.err);
|
||||
return cco.ret;
|
||||
}
|
||||
|
||||
ret = cco.ret;
|
||||
if (ret < 0) {
|
||||
if (cco.err) {
|
||||
error_propagate(errp, cco.err);
|
||||
} else {
|
||||
error_setg_errno(errp, -ret, "Could not create image");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user