int ret;
GLOBAL_STATE_CODE();
ERRP_GUARD();
- assert_bdrv_graph_readable();
if (!drv->bdrv_co_create_opts) {
error_setg(errp, "Driver '%s' does not support image creation",
int ret;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD();
job_progress_set_remaining(&s->common, 1);
ret = s->drv->bdrv_co_create(s->opts, errp);
};
-static int block_crypto_create_write_func(QCryptoBlock *block,
- size_t offset,
- const uint8_t *buf,
- size_t buflen,
- void *opaque,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+block_crypto_create_write_func(QCryptoBlock *block, size_t offset,
+ const uint8_t *buf, size_t buflen, void *opaque,
+ Error **errp)
{
struct BlockCryptoCreateData *data = opaque;
ssize_t ret;
return 0;
}
-static int block_crypto_create_init_func(QCryptoBlock *block,
- size_t headerlen,
- void *opaque,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+block_crypto_create_init_func(QCryptoBlock *block, size_t headerlen,
+ void *opaque, Error **errp)
{
struct BlockCryptoCreateData *data = opaque;
Error *local_error = NULL;
}
-static int coroutine_fn
+static int coroutine_fn GRAPH_UNLOCKED
block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
QCryptoBlockCreateOptions *opts,
PreallocMode prealloc, Error **errp)
bs, options, flags, errp);
}
-static int coroutine_fn
+static int coroutine_fn GRAPH_UNLOCKED
block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
{
BlockdevCreateOptionsLUKS *luks_opts;
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
* beforehand, it has been truncated and corrupted in the process.
*/
if (ret) {
+ bdrv_graph_co_rdlock();
bdrv_co_delete_file_noerr(bs);
+ bdrv_graph_co_rdunlock();
}
bdrv_co_unref(bs);
}
-static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+parallels_co_create(BlockdevCreateOptions* opts, Error **errp)
{
BlockdevCreateOptionsParallels *parallels_opts;
BlockDriverState *bs;
goto out;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
parallels_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
error_free(s->migration_blocker);
}
-static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+qcow_co_create(BlockdevCreateOptions *opts, Error **errp)
{
BlockdevCreateOptionsQcow *qcow_opts;
int header_size, backing_filename_len, l1_size, shift, i;
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
qcow_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
}
-static int qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen,
- void *opaque, Error **errp)
+static int coroutine_fn GRAPH_RDLOCK
+qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen, void *opaque,
+ Error **errp)
{
BlockDriverState *bs = opaque;
BDRVQcow2State *s = bs->opaque;
*/
clusterlen = size_to_clusters(s, headerlen) * s->cluster_size;
assert(qcow2_pre_write_overlap_check(bs, 0, ret, clusterlen, false) == 0);
- ret = bdrv_pwrite_zeroes(bs->file,
- ret,
- clusterlen, 0);
+ ret = bdrv_co_pwrite_zeroes(bs->file, ret, clusterlen, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not zero fill encryption header");
return -1;
}
-static int qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
- const uint8_t *buf, size_t buflen,
- void *opaque, Error **errp)
+/* The graph lock must be held when called in coroutine context */
+static int coroutine_mixed_fn
+qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
+ const uint8_t *buf, size_t buflen,
+ void *opaque, Error **errp)
{
BlockDriverState *bs = opaque;
BDRVQcow2State *s = bs->opaque;
return qcow2_update_header(bs);
}
-static int qcow2_set_up_encryption(BlockDriverState *bs,
- QCryptoBlockCreateOptions *cryptoopts,
- Error **errp)
+static int coroutine_fn GRAPH_RDLOCK
+qcow2_set_up_encryption(BlockDriverState *bs,
+ QCryptoBlockCreateOptions *cryptoopts,
+ Error **errp)
{
BDRVQcow2State *s = bs->opaque;
QCryptoBlock *crypto = NULL;
return refcount_bits;
}
-static int coroutine_fn
+static int coroutine_fn GRAPH_UNLOCKED
qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
{
BlockdevCreateOptionsQcow2 *qcow2_opts;
goto out;
}
+ bdrv_graph_co_rdlock();
ret = qcow2_alloc_clusters(blk_bs(blk), 3 * cluster_size);
if (ret < 0) {
+ bdrv_graph_co_rdunlock();
error_setg_errno(errp, -ret, "Could not allocate clusters for qcow2 "
"header and refcount table");
goto out;
/* Create a full header (including things like feature table) */
ret = qcow2_update_header(blk_bs(blk));
+ bdrv_graph_co_rdunlock();
+
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not update qcow2 header");
goto out;
/* Want encryption? There you go. */
if (qcow2_opts->encrypt) {
+ bdrv_graph_co_rdlock();
ret = qcow2_set_up_encryption(blk_bs(blk), qcow2_opts->encrypt, errp);
+ bdrv_graph_co_rdunlock();
+
if (ret < 0) {
goto out;
}
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
Error **errp)
{
ret = qcow2_co_create(create_options, errp);
finish:
if (ret < 0) {
+ bdrv_graph_co_rdlock();
bdrv_co_delete_file_noerr(bs);
bdrv_co_delete_file_noerr(data_bs);
+ bdrv_graph_co_rdunlock();
} else {
ret = 0;
}
qemu_vfree(s->l1_table);
}
-static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+bdrv_qed_co_create(BlockdevCreateOptions *opts, Error **errp)
{
BlockdevCreateOptionsQed *qed_opts;
BlockBackend *blk = NULL;
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
return bdrv_has_zero_init(bs->file->bs);
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
return ret;
}
-static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
- size_t block_size, Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+vdi_co_do_create(BlockdevCreateOptions *create_options, size_t block_size,
+ Error **errp)
{
BlockdevCreateOptionsVdi *vdi_opts;
int ret = 0;
return ret;
}
-static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+vdi_co_create(BlockdevCreateOptions *create_options, Error **errp)
{
return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vdi_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
* There are 2 headers, and the highest sequence number will represent
* the active header
*/
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vhdx_create_new_headers(BlockBackend *blk, uint64_t image_size,
uint32_t log_size)
{
int ret = 0;
VHDXHeader *hdr = NULL;
+ GRAPH_RDLOCK_GUARD();
+
hdr = g_new0(VHDXHeader, 1);
hdr->signature = VHDX_HEADER_SIGNATURE;
* .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
* 1MB
*/
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vhdx_co_create(BlockdevCreateOptions *opts, Error **errp)
{
BlockdevCreateOptionsVhdx *vhdx_opts;
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vhdx_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
return ret;
}
-static int vmdk_init_extent(BlockBackend *blk,
- int64_t filesize, bool flat,
- bool compress, bool zeroed_grain,
- Error **errp)
+static int GRAPH_UNLOCKED
+vmdk_init_extent(BlockBackend *blk, int64_t filesize, bool flat, bool compress,
+ bool zeroed_grain, Error **errp)
{
int ret, i;
VMDK4Header header;
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vmdk_create_extent(const char *filename, int64_t filesize, bool flat,
bool compress, bool zeroed_grain, BlockBackend **pbb,
QemuOpts *opts, Error **errp)
* non-split format.
* idx >= 1: get the n-th extent if in a split subformat
*/
-typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */
+typedef BlockBackend * coroutine_fn GRAPH_UNLOCKED_PTR
(*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split,
bool compress, bool zeroed_grain, void *opaque,
Error **errp);
g_free(basename);
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vmdk_co_do_create(int64_t size,
BlockdevVmdkSubformat subformat,
BlockdevVmdkAdapterType adapter_type,
QemuOpts *opts;
} VMDKCreateOptsData;
-static BlockBackend * coroutine_fn GRAPH_RDLOCK
+static BlockBackend * coroutine_fn GRAPH_UNLOCKED
vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
bool compress, bool zeroed_grain, void *opaque,
Error **errp)
return blk;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vmdk_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
return ret;
}
-static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
- bool flat, bool split,
- bool compress,
- bool zeroed_grain,
- void *opaque, Error **errp)
+static BlockBackend * coroutine_fn GRAPH_UNLOCKED
+vmdk_co_create_cb(int64_t size, int idx, bool flat, bool split, bool compress,
+ bool zeroed_grain, void *opaque, Error **errp)
{
int ret;
BlockDriverState *bs;
return blk;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp)
{
BlockdevCreateOptionsVmdk *opts;
return 0;
}
-static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
- Error **errp)
+static int coroutine_fn GRAPH_UNLOCKED
+vpc_co_create(BlockdevCreateOptions *opts, Error **errp)
{
BlockdevCreateOptionsVpc *vpc_opts;
BlockBackend *blk = NULL;
return ret;
}
-static int coroutine_fn GRAPH_RDLOCK
+static int coroutine_fn GRAPH_UNLOCKED
vpc_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp)
{
Error **errp);
BlockDriver *bdrv_find_format(const char *format_name);
-int coroutine_fn GRAPH_RDLOCK
+int coroutine_fn GRAPH_UNLOCKED
bdrv_co_create(BlockDriver *drv, const char *filename, QemuOpts *opts,
Error **errp);
-int co_wrapper_bdrv_rdlock bdrv_create(BlockDriver *drv, const char *filename,
- QemuOpts *opts, Error **errp);
+int co_wrapper bdrv_create(BlockDriver *drv, const char *filename,
+ QemuOpts *opts, Error **errp);
-int coroutine_fn GRAPH_RDLOCK
+int coroutine_fn GRAPH_UNLOCKED
bdrv_co_create_file(const char *filename, QemuOpts *opts, Error **errp);
BlockDriverState *bdrv_new(void);
BlockDriverState *bs, QDict *options, int flags, Error **errp);
void (*bdrv_close)(BlockDriverState *bs);
- int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create)(
+ int coroutine_fn GRAPH_UNLOCKED_PTR (*bdrv_co_create)(
BlockdevCreateOptions *opts, Error **errp);
- int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create_opts)(
+ int coroutine_fn GRAPH_UNLOCKED_PTR (*bdrv_co_create_opts)(
BlockDriver *drv, const char *filename, QemuOpts *opts, Error **errp);
int (*bdrv_amend_options)(BlockDriverState *bs,