diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-05-08 09:38:41 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-05-08 09:38:41 -0500 |
commit | 7c652c1eaf20b9271ebcc92b788d1fe656b3a774 (patch) | |
tree | b82120a0cecc99af4261329bd01e8e914e01a9db /block.c | |
parent | e45bca682ca1b63cdfba9c8a6b164d1838a2eda4 (diff) | |
parent | 21fcf36095939a97fc3df578e12821c3e6c3ba78 (diff) | |
download | qemu-7c652c1eaf20b9271ebcc92b788d1fe656b3a774.zip qemu-7c652c1eaf20b9271ebcc92b788d1fe656b3a774.tar.gz qemu-7c652c1eaf20b9271ebcc92b788d1fe656b3a774.tar.bz2 |
Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony:
fdc: simplify media change handling
qcow2: lock on prealloc
block: make bdrv_create adopt coroutine
qcow2: Limit COW to where it's needed
sheepdog: switch to writethrough mode if cluster doesn't support flush
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 44 |
1 files changed, 42 insertions, 2 deletions
@@ -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) |