We are going to add one more option of enum type. Let's refactor option parsing so that we can simply work with BlockdevOptionsCbw object.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- block/copy-before-write.c | 66 ++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/block/copy-before-write.c b/block/copy-before-write.c index 0b6d26605c..56aa7577c3 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qapi/qmp/qjson.h" #include "sysemu/block-backend.h" #include "qemu/cutils.h" @@ -328,46 +329,49 @@ static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c, } } -static bool cbw_parse_bitmap_option(QDict *options, BdrvDirtyBitmap **bitmap, - Error **errp) +static BlockdevOptionsCbw *cbw_parse_options(QDict *options, Error **errp) { - QDict *bitmap_qdict = NULL; - BlockDirtyBitmap *bmp_param = NULL; + QDict *cbw_qdict = NULL; + BlockdevOptionsCbw *opts = NULL; Visitor *v = NULL; - bool ret = false; - *bitmap = NULL; + cbw_qdict = qdict_clone_shallow(options); - qdict_extract_subqdict(options, &bitmap_qdict, "bitmap."); - if (!qdict_size(bitmap_qdict)) { - ret = true; - goto out; - } + /* + * Delete BlockdevOptions base fields, that are not part of + * BlockdevOptionsCbw. + */ + qdict_del(cbw_qdict, "driver"); + qdict_del(cbw_qdict, "node-name"); + qdict_del(cbw_qdict, "discard"); + qdict_del(cbw_qdict, "cache"); + qdict_extract_subqdict(cbw_qdict, NULL, "cache."); + qdict_del(cbw_qdict, "read-only"); + qdict_del(cbw_qdict, "auto-read-only"); + qdict_del(cbw_qdict, "force-share"); + qdict_del(cbw_qdict, "detect-zeroes"); - v = qobject_input_visitor_new_flat_confused(bitmap_qdict, errp); + v = qobject_input_visitor_new_flat_confused(cbw_qdict, errp); if (!v) { goto out; } - visit_type_BlockDirtyBitmap(v, NULL, &bmp_param, errp); - if (!bmp_param) { + visit_type_BlockdevOptionsCbw(v, NULL, &opts, errp); + if (!opts) { goto out; } - *bitmap = block_dirty_bitmap_lookup(bmp_param->node, bmp_param->name, NULL, - errp); - if (!*bitmap) { - goto out; - } - - ret = true; + /* + * Delete options which we are going to parse through BlockdevOptionsCbw + * object for original options. + */ + qdict_extract_subqdict(options, NULL, "bitmap"); out: - qapi_free_BlockDirtyBitmap(bmp_param); visit_free(v); - qobject_unref(bitmap_qdict); + qobject_unref(cbw_qdict); - return ret; + return opts; } static int cbw_open(BlockDriverState *bs, QDict *options, int flags, @@ -376,6 +380,12 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, BDRVCopyBeforeWriteState *s = bs->opaque; BdrvDirtyBitmap *bitmap = NULL; int64_t cluster_size; + g_autoptr(BlockdevOptionsCbw) opts = NULL; + + opts = cbw_parse_options(options, errp); + if (!opts) { + return -EINVAL; + } bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, @@ -390,8 +400,12 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, return -EINVAL; } - if (!cbw_parse_bitmap_option(options, &bitmap, errp)) { - return -EINVAL; + if (opts->has_bitmap) { + bitmap = block_dirty_bitmap_lookup(opts->bitmap->node, + opts->bitmap->name, NULL, errp); + if (!bitmap) { + return -EINVAL; + } } bs->total_sectors = bs->file->bs->total_sectors; -- 2.31.1