mirror of https://github.com/xqemu/xqemu.git
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:
parent
593b307197
commit
543770bd2e
64
block.c
64
block.c
|
@ -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
|
* 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 *driver_name = NULL;
|
||||||
const char *node_name = NULL;
|
const char *node_name = NULL;
|
||||||
const char *discard;
|
const char *discard;
|
||||||
const char *detect_zeroes;
|
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
Error *local_err = NULL;
|
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");
|
bs->detect_zeroes =
|
||||||
if (detect_zeroes) {
|
bdrv_parse_detect_zeroes(opts, bs->open_flags, &local_err);
|
||||||
BlockdevDetectZeroesOptions value =
|
if (local_err) {
|
||||||
qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup,
|
error_propagate(errp, local_err);
|
||||||
detect_zeroes,
|
ret = -EINVAL;
|
||||||
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
|
goto fail_opts;
|
||||||
&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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename != NULL) {
|
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.
|
/* 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
|
* Put them back into the QDict, so that they are checked at the end
|
||||||
* of this function. */
|
* of this function. */
|
||||||
|
@ -3338,6 +3353,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
|
||||||
bs->options = reopen_state->options;
|
bs->options = reopen_state->options;
|
||||||
bs->open_flags = reopen_state->flags;
|
bs->open_flags = reopen_state->flags;
|
||||||
bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
|
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.
|
/* Remove child references from bs->options and bs->explicit_options.
|
||||||
* Child options were already removed in bdrv_reopen_queue_child() */
|
* Child options were already removed in bdrv_reopen_queue_child() */
|
||||||
|
|
|
@ -184,6 +184,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
|
||||||
typedef struct BDRVReopenState {
|
typedef struct BDRVReopenState {
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
int flags;
|
int flags;
|
||||||
|
BlockdevDetectZeroesOptions detect_zeroes;
|
||||||
uint64_t perm, shared_perm;
|
uint64_t perm, shared_perm;
|
||||||
QDict *options;
|
QDict *options;
|
||||||
QDict *explicit_options;
|
QDict *explicit_options;
|
||||||
|
|
Loading…
Reference in New Issue