[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH v3 01/21] qcow2: Add .bdrv_join_options callback
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PATCH v3 01/21] qcow2: Add .bdrv_join_options callback |
Date: |
Fri, 4 Dec 2015 14:35:04 +0100 |
qcow2 accepts a few driver-specific options that overlap semantically
(e.g. "overlap-check" is an alias of "overlap-check.template", and any
missing cache size option is derived from the given ones).
When bdrv_reopen() merges the set of updated options with left out
options that should be kept at their old value, we need to consider this
and filter out any duplicates (which would generally cause errors
because new and old value would contradict each other).
This patch adds a .bdrv_join_options callback to BlockDriver and
implements it for qcow2.
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
Reviewed-by: Alberto Garcia <address@hidden>
---
block/qcow2.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
include/block/block_int.h | 1 +
2 files changed, 48 insertions(+)
diff --git a/block/qcow2.c b/block/qcow2.c
index 88f56c8..9baaf4d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1282,6 +1282,52 @@ static void qcow2_reopen_abort(BDRVReopenState *state)
g_free(state->opaque);
}
+static void qcow2_join_options(QDict *options, QDict *old_options)
+{
+ bool has_new_overlap_template =
+ qdict_haskey(options, QCOW2_OPT_OVERLAP) ||
+ qdict_haskey(options, QCOW2_OPT_OVERLAP_TEMPLATE);
+ bool has_new_total_cache_size =
+ qdict_haskey(options, QCOW2_OPT_CACHE_SIZE);
+ bool has_all_cache_options;
+
+ /* New overlap template overrides all old overlap options */
+ if (has_new_overlap_template) {
+ qdict_del(old_options, QCOW2_OPT_OVERLAP);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_TEMPLATE);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_MAIN_HEADER);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_ACTIVE_L1);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_ACTIVE_L2);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_REFCOUNT_TABLE);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_REFCOUNT_BLOCK);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_SNAPSHOT_TABLE);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_INACTIVE_L1);
+ qdict_del(old_options, QCOW2_OPT_OVERLAP_INACTIVE_L2);
+ }
+
+ /* New total cache size overrides all old options */
+ if (qdict_haskey(options, QCOW2_OPT_CACHE_SIZE)) {
+ qdict_del(old_options, QCOW2_OPT_L2_CACHE_SIZE);
+ qdict_del(old_options, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
+ }
+
+ qdict_join(options, old_options, false);
+
+ /*
+ * If after merging all cache size options are set, an old total size is
+ * overwritten. Do keep all options, however, if all three are new. The
+ * resulting error message is what we want to happen.
+ */
+ has_all_cache_options =
+ qdict_haskey(options, QCOW2_OPT_CACHE_SIZE) ||
+ qdict_haskey(options, QCOW2_OPT_L2_CACHE_SIZE) ||
+ qdict_haskey(options, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
+
+ if (has_all_cache_options && !has_new_total_cache_size) {
+ qdict_del(options, QCOW2_OPT_CACHE_SIZE);
+ }
+}
+
static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, int *pnum)
{
@@ -3145,6 +3191,7 @@ BlockDriver bdrv_qcow2 = {
.bdrv_reopen_prepare = qcow2_reopen_prepare,
.bdrv_reopen_commit = qcow2_reopen_commit,
.bdrv_reopen_abort = qcow2_reopen_abort,
+ .bdrv_join_options = qcow2_join_options,
.bdrv_create = qcow2_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_get_block_status = qcow2_co_get_block_status,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 4012e36..77dc165 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -121,6 +121,7 @@ struct BlockDriver {
BlockReopenQueue *queue, Error **errp);
void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
+ void (*bdrv_join_options)(QDict *options, QDict *old_options);
int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags,
Error **errp);
--
1.8.3.1
- [Qemu-block] [PATCH v3 00/21] block: Cache mode for children etc., Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 01/21] qcow2: Add .bdrv_join_options callback,
Kevin Wolf <=
- [Qemu-block] [PATCH v3 02/21] block: Fix reopen with semantically overlapping options, Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 03/21] mirror: Error out when a BDS would get two BBs, Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 04/21] block: Allow references for backing files, Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 05/21] block: Consider all block layer options in append_open_options, Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 06/21] block: Exclude nested options only for children in append_open_options(), Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 07/21] block: Pass driver-specific options to .bdrv_refresh_filename(), Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 09/21] block: Allow specifying child options in reopen, Kevin Wolf, 2015/12/04
- [Qemu-block] [PATCH v3 10/21] block: reopen: Document option precedence and refactor accordingly, Kevin Wolf, 2015/12/04