#include "qemu/osdep.h"
#include "block/block_int.h"
+#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "crypto/block.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-visit-crypto.h"
-#include "qapi/qmp/qdict.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/error.h"
#include "qemu/option.h"
-#include "block/crypto.h"
+#include "crypto.h"
typedef struct BlockCrypto BlockCrypto;
QCryptoBlockOpenOptions *
-block_crypto_open_opts_init(QCryptoBlockFormat format,
- QDict *opts,
- Error **errp)
+block_crypto_open_opts_init(QDict *opts, Error **errp)
{
Visitor *v;
- QCryptoBlockOpenOptions *ret = NULL;
- Error *local_err = NULL;
-
- ret = g_new0(QCryptoBlockOpenOptions, 1);
- ret->format = format;
-
- v = qobject_input_visitor_new_keyval(QOBJECT(opts));
-
- visit_start_struct(v, NULL, NULL, 0, &local_err);
- if (local_err) {
- goto out;
- }
-
- switch (format) {
- case Q_CRYPTO_BLOCK_FORMAT_LUKS:
- visit_type_QCryptoBlockOptionsLUKS_members(
- v, &ret->u.luks, &local_err);
- break;
-
- case Q_CRYPTO_BLOCK_FORMAT_QCOW:
- visit_type_QCryptoBlockOptionsQCow_members(
- v, &ret->u.qcow, &local_err);
- break;
+ QCryptoBlockOpenOptions *ret;
- default:
- error_setg(&local_err, "Unsupported block format %d", format);
- break;
- }
- if (!local_err) {
- visit_check_struct(v, &local_err);
+ v = qobject_input_visitor_new_flat_confused(opts, errp);
+ if (!v) {
+ return NULL;
}
- visit_end_struct(v, NULL);
+ visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);
- out:
- if (local_err) {
- error_propagate(errp, local_err);
- qapi_free_QCryptoBlockOpenOptions(ret);
- ret = NULL;
- }
visit_free(v);
return ret;
}
QCryptoBlockCreateOptions *
-block_crypto_create_opts_init(QCryptoBlockFormat format,
- QDict *opts,
- Error **errp)
+block_crypto_create_opts_init(QDict *opts, Error **errp)
{
Visitor *v;
- QCryptoBlockCreateOptions *ret = NULL;
- Error *local_err = NULL;
-
- ret = g_new0(QCryptoBlockCreateOptions, 1);
- ret->format = format;
+ QCryptoBlockCreateOptions *ret;
- v = qobject_input_visitor_new_keyval(QOBJECT(opts));
-
- visit_start_struct(v, NULL, NULL, 0, &local_err);
- if (local_err) {
- goto out;
- }
-
- switch (format) {
- case Q_CRYPTO_BLOCK_FORMAT_LUKS:
- visit_type_QCryptoBlockCreateOptionsLUKS_members(
- v, &ret->u.luks, &local_err);
- break;
-
- case Q_CRYPTO_BLOCK_FORMAT_QCOW:
- visit_type_QCryptoBlockOptionsQCow_members(
- v, &ret->u.qcow, &local_err);
- break;
-
- default:
- error_setg(&local_err, "Unsupported block format %d", format);
- break;
- }
- if (!local_err) {
- visit_check_struct(v, &local_err);
+ v = qobject_input_visitor_new_flat_confused(opts, errp);
+ if (!v) {
+ return NULL;
}
- visit_end_struct(v, NULL);
+ visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);
- out:
- if (local_err) {
- error_propagate(errp, local_err);
- qapi_free_QCryptoBlockCreateOptions(ret);
- ret = NULL;
- }
visit_free(v);
return ret;
}
}
cryptoopts = qemu_opts_to_qdict(opts, NULL);
+ qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));
- open_opts = block_crypto_open_opts_init(format, cryptoopts, errp);
+ open_opts = block_crypto_open_opts_init(cryptoopts, errp);
if (!open_opts) {
goto cleanup;
}
return ret;
}
-static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
- PreallocMode prealloc, Error **errp)
+static int coroutine_fn
+block_crypto_co_truncate(BlockDriverState *bs, int64_t offset,
+ PreallocMode prealloc, Error **errp)
{
BlockCrypto *crypto = bs->opaque;
uint64_t payload_offset =
offset += payload_offset;
- return bdrv_truncate(bs->file, offset, prealloc, errp);
+ return bdrv_co_truncate(bs->file, offset, prealloc, errp);
}
static void block_crypto_close(BlockDriverState *bs)
&block_crypto_create_opts_luks,
true);
- create_opts = block_crypto_create_opts_init(Q_CRYPTO_BLOCK_FORMAT_LUKS,
- cryptoopts, errp);
+ qdict_put_str(cryptoopts, "format", "luks");
+ create_opts = block_crypto_create_opts_init(cryptoopts, errp);
if (!create_opts) {
ret = -EINVAL;
goto fail;
/* Create protocol layer */
ret = bdrv_create_file(filename, opts, errp);
if (ret < 0) {
- return ret;
+ goto fail;
}
bs = bdrv_open(filename, NULL, NULL,
.bdrv_probe = block_crypto_probe_luks,
.bdrv_open = block_crypto_open_luks,
.bdrv_close = block_crypto_close,
- .bdrv_child_perm = bdrv_format_default_perms,
+ /* This driver doesn't modify LUKS metadata except when creating image.
+ * Allow share-rw=on as a special case. */
+ .bdrv_child_perm = bdrv_filter_default_perms,
.bdrv_co_create = block_crypto_co_create_luks,
.bdrv_co_create_opts = block_crypto_co_create_opts_luks,
- .bdrv_truncate = block_crypto_truncate,
+ .bdrv_co_truncate = block_crypto_co_truncate,
.create_opts = &block_crypto_create_opts_luks,
.bdrv_reopen_prepare = block_crypto_reopen_prepare,