mirror of https://gitee.com/openkylin/qemu.git
block: make bdrv_create adopt coroutine
The current qemu.git introduces failure with preallocation and some sizes: qemu-img create -f qcow2 new.img 976563K -o preallocation=metadata qemu-img: qemu-coroutine-lock.c:111: qemu_co_mutex_unlock: Assertion `mutex->locked == 1' failed. And lock needs to work in coroutine context. So to fix this issue, we need to make bdrv_create adopt coroutine at first. Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
54e6814360
commit
5b7e1542cf
46
block.c
46
block.c
|
@ -341,13 +341,53 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
|
||||||
return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
|
return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct CreateCo {
|
||||||
|
BlockDriver *drv;
|
||||||
|
char *filename;
|
||||||
|
QEMUOptionParameter *options;
|
||||||
|
int ret;
|
||||||
|
} CreateCo;
|
||||||
|
|
||||||
|
static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
||||||
|
{
|
||||||
|
CreateCo *cco = opaque;
|
||||||
|
assert(cco->drv);
|
||||||
|
|
||||||
|
cco->ret = cco->drv->bdrv_create(cco->filename, cco->options);
|
||||||
|
}
|
||||||
|
|
||||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||||
QEMUOptionParameter *options)
|
QEMUOptionParameter *options)
|
||||||
{
|
{
|
||||||
if (!drv->bdrv_create)
|
int ret;
|
||||||
return -ENOTSUP;
|
|
||||||
|
|
||||||
return drv->bdrv_create(filename, options);
|
Coroutine *co;
|
||||||
|
CreateCo cco = {
|
||||||
|
.drv = drv,
|
||||||
|
.filename = g_strdup(filename),
|
||||||
|
.options = options,
|
||||||
|
.ret = NOT_DONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!drv->bdrv_create) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemu_in_coroutine()) {
|
||||||
|
/* Fast-path if already in coroutine context */
|
||||||
|
bdrv_create_co_entry(&cco);
|
||||||
|
} else {
|
||||||
|
co = qemu_coroutine_create(bdrv_create_co_entry);
|
||||||
|
qemu_coroutine_enter(co, &cco);
|
||||||
|
while (cco.ret == NOT_DONE) {
|
||||||
|
qemu_aio_wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cco.ret;
|
||||||
|
g_free(cco.filename);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
|
int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
|
||||||
|
|
Loading…
Reference in New Issue