+ QCryptoBlockCreateOptions *create_opts = NULL;
+ BlockDriverState *bs = NULL;
+ QDict *cryptoopts;
+ int64_t size;
+ int ret;
+
+ /* Parse options */
+ size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+
+ cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
+ &block_crypto_create_opts_luks,
+ true);
+
+ 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) {
+ goto fail;
+ }
+
+ bs = bdrv_open(filename, NULL, NULL,
+ BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
+ if (!bs) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ /* Create format layer */
+ ret = block_crypto_co_create_generic(bs, size, create_opts, errp);
+ if (ret < 0) {
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ bdrv_unref(bs);
+ qapi_free_QCryptoBlockCreateOptions(create_opts);
+ qobject_unref(cryptoopts);
+ return ret;