diff options
author | Alberto Garcia <berto@igalia.com> | 2018-09-06 12:37:09 +0300 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-10-01 12:51:12 +0200 |
commit | 543770bd2e8fbaac286a947dee91675adb3215c7 (patch) | |
tree | bd89b70388a0f78a274719cc0408a9e874f633f5 | |
parent | 593b30719713cfad98b869693095893f8edf76c1 (diff) |
block: Allow changing 'detect-zeroes' on reopen
'detect-zeroes' is one of the basic BlockdevOptions available for all
drivers, but it's not handled by bdrv_reopen_prepare(), so any attempt
to change it results in an error:
(qemu) qemu-io virtio0 "reopen -o detect-zeroes=on"
Cannot change the option 'detect-zeroes'
Since there's no reason why we shouldn't allow changing it and the
implementation is simple let's just do it.
Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | block.c | 64 | ||||
-rw-r--r-- | include/block/block.h | 1 |
2 files changed, 41 insertions, 24 deletions
@@ -764,6 +764,31 @@ static void bdrv_join_options(BlockDriverState *bs, QDict *options, } } +static BlockdevDetectZeroesOptions bdrv_parse_detect_zeroes(QemuOpts *opts, + int open_flags, + Error **errp) +{ + Error *local_err = NULL; + char *value = qemu_opt_get_del(opts, "detect-zeroes"); + BlockdevDetectZeroesOptions detect_zeroes = + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, value, + BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); + g_free(value); + if (local_err) { + error_propagate(errp, local_err); + return detect_zeroes; + } + + if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && + !(open_flags & BDRV_O_UNMAP)) + { + error_setg(errp, "setting detect-zeroes to unmap is not allowed " + "without setting discard operation to unmap"); + } + + return detect_zeroes; +} + /** * Set open flags for a given discard mode * @@ -1328,7 +1353,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, const char *driver_name = NULL; const char *node_name = NULL; const char *discard; - const char *detect_zeroes; QemuOpts *opts; BlockDriver *drv; Error *local_err = NULL; @@ -1417,29 +1441,12 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, } } - detect_zeroes = qemu_opt_get(opts, "detect-zeroes"); - if (detect_zeroes) { - BlockdevDetectZeroesOptions value = - qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, - detect_zeroes, - BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, - &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret = -EINVAL; - goto fail_opts; - } - - if (value == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && - !(bs->open_flags & BDRV_O_UNMAP)) - { - error_setg(errp, "setting detect-zeroes to unmap is not allowed " - "without setting discard operation to unmap"); - ret = -EINVAL; - goto fail_opts; - } - - bs->detect_zeroes = value; + bs->detect_zeroes = + bdrv_parse_detect_zeroes(opts, bs->open_flags, &local_err); + if (local_err) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto fail_opts; } if (filename != NULL) { @@ -3188,6 +3195,14 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, } } + reopen_state->detect_zeroes = + bdrv_parse_detect_zeroes(opts, reopen_state->flags, &local_err); + if (local_err) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto error; + } + /* All other options (including node-name and driver) must be unchanged. * Put them back into the QDict, so that they are checked at the end * of this function. */ @@ -3338,6 +3353,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) bs->options = reopen_state->options; bs->open_flags = reopen_state->flags; bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); + bs->detect_zeroes = reopen_state->detect_zeroes; /* Remove child references from bs->options and bs->explicit_options. * Child options were already removed in bdrv_reopen_queue_child() */ diff --git a/include/block/block.h b/include/block/block.h index 4edc1e8afa..b189cf422e 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -184,6 +184,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue; typedef struct BDRVReopenState { BlockDriverState *bs; int flags; + BlockdevDetectZeroesOptions detect_zeroes; uint64_t perm, shared_perm; QDict *options; QDict *explicit_options; |