From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:50207) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SRSAH-0007v9-Qk for qemu-devel@nongnu.org; Mon, 07 May 2012 13:56:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SRSAF-00031C-VM for qemu-devel@nongnu.org; Mon, 07 May 2012 13:56:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:4717) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SRSAF-00030k-NE for qemu-devel@nongnu.org; Mon, 07 May 2012 13:56:03 -0400 From: Kevin Wolf Date: Mon, 7 May 2012 19:55:52 +0200 Message-Id: <1336413354-5244-4-git-send-email-kwolf@redhat.com> In-Reply-To: <1336413354-5244-1-git-send-email-kwolf@redhat.com> References: <1336413354-5244-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 3/5] block: make bdrv_create adopt coroutine List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: Zhi Yong Wu 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 Signed-off-by: Kevin Wolf --- block.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 43c794c..ee7d8f2 100644 --- a/block.c +++ b/block.c @@ -341,13 +341,53 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name) 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, QEMUOptionParameter *options) { - if (!drv->bdrv_create) + int ret; + + Coroutine *co; + CreateCo cco = { + .drv = drv, + .filename = g_strdup(filename), + .options = options, + .ret = NOT_DONE, + }; + + if (!drv->bdrv_create) { return -ENOTSUP; + } - return drv->bdrv_create(filename, options); + 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) -- 1.7.6.5