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>
This commit is contained in:
Alberto Garcia 2018-09-06 12:37:09 +03:00 committed by Kevin Wolf
parent 593b307197
commit 543770bd2e
2 changed files with 41 additions and 24 deletions

64
block.c
View File

@ -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() */

View File

@ -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;