@@ -366,6 +366,7 @@ typedef struct CreateCo {
BlockDriver *drv;
char *filename;
QEMUOptionParameter *options;
+ QemuOpts *opts;
int ret;
} CreateCo;
@@ -425,6 +426,56 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
return bdrv_create(drv, filename, options);
}
+int bdrv_create_new(BlockDriver *drv, const char* filename, QemuOpts *opts)
+{
+ int ret;
+
+ Coroutine *co;
+ CreateCo cco = {
+ .drv = drv,
+ .filename = g_strdup(filename),
+ .opts = opts ?: qemu_opts_create_nofail(drv->bdrv_create_opts),
+ .ret = NOT_DONE,
+ };
+
+ if (!drv->bdrv_create) {
+ ret = -ENOTSUP;
+ goto out;
+ }
+
+ 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;
+
+out:
+ if (!opts) {
+ qemu_opts_del(cco.opts);
+ }
+ g_free(cco.filename);
+ return ret;
+}
+
+int bdrv_create_file_new(const char *filename, QemuOpts *opts)
+{
+ BlockDriver *drv;
+
+ drv = bdrv_find_protocol(filename, true);
+ if (drv == NULL) {
+ return -ENOENT;
+ }
+
+ return bdrv_create_new(drv, filename, opts);
+}
+
/*
* Create a uniquely-named empty temporary file.
* Return 0 upon success, otherwise a negative errno value.
@@ -119,6 +119,8 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
int bdrv_create(BlockDriver *drv, const char* filename,
QEMUOptionParameter *options);
int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
+int bdrv_create_new(BlockDriver *drv, const char* filename, QemuOpts *opts);
+int bdrv_create_file_new(const char *filename, QemuOpts *opts);
BlockDriverState *bdrv_new(const char *device_name);
void bdrv_make_anon(BlockDriverState *bs);
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
@@ -105,6 +105,7 @@ struct BlockDriver {
void (*bdrv_close)(BlockDriverState *bs);
void (*bdrv_rebind)(BlockDriverState *bs);
int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
+ int (*bdrv_create_new)(const char *filename, QemuOpts *opts);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
int (*bdrv_make_empty)(BlockDriverState *bs);
/* aio */
@@ -195,6 +196,7 @@ struct BlockDriver {
/* List of options for creating images, terminated by name == NULL */
QEMUOptionParameter *create_options;
+ QemuOptsList *bdrv_create_opts;
/*
To make patches easy for reviewing, each block format is a single patch. Add a new interface to block layer to make sure origin code can compile and do not change any code logic. Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com> --- block.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ include/block/block.h | 2 ++ include/block/block_int.h | 2 ++ 3 files changed, 55 insertions(+)