[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 04/48] qcow2: Add .bdrv_join_options callback
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 04/48] qcow2: Add .bdrv_join_options callback |
Date: |
Fri, 18 Dec 2015 16:07:10 +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 5b59fa3..fda1562 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 66e208d..c2ce965 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-devel] [PULL 06/48] mirror: Error out when a BDS would get two BBs, (continued)
- [Qemu-devel] [PULL 06/48] mirror: Error out when a BDS would get two BBs, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 34/48] iotests: Extend test 112 for qemu-img amend, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 07/48] block: Allow references for backing files, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 27/48] qcow2: Use error_report() in qcow2_amend_options(), Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 36/48] raw-posix: Make aio=native option binding, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 13/48] block: reopen: Document option precedence and refactor accordingly, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 18/48] qemu-iotests: Remove cache mode test without medium, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 25/48] progress: Allow regressing progress, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 08/48] block: Consider all block layer options in append_open_options, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 22/48] qemu-iotests: Try setting cache mode for children, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 04/48] qcow2: Add .bdrv_join_options callback,
Kevin Wolf <=
- [Qemu-devel] [PULL 12/48] block: Allow specifying child options in reopen, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 26/48] block: Add opaque value to the amend CB, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 48/48] block/qapi: allow best-effort query, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 35/48] qcow2: insert assert into qcow2_get_specific_info(), Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 44/48] block/qapi: do not redundantly print "actual path", Kevin Wolf, 2015/12/18
- Re: [Qemu-devel] [PULL 00/48] Block patches, Peter Maydell, 2015/12/18
- [Qemu-devel] [PULL 45/48] block/qapi: always report full_backing_filename, Kevin Wolf, 2015/12/18
- [Qemu-devel] [PULL 33/48] qcow2: Point to amend function in check, Kevin Wolf, 2015/12/18