}
}
+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
*
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;
}
}
- 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) {
}
}
+ 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. */
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() */