BDRVVmdkState *s = bs->opaque;
VmdkExtent *e;
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_wrlock();
for (i = 0; i < s->num_extents; i++) {
e = &s->extents[i];
g_free(e->l1_table);
}
/* Return -ve errno, or 0 on success and write CID into *pcid. */
-static int vmdk_read_cid(BlockDriverState *bs, int parent, uint32_t *pcid)
+static int GRAPH_RDLOCK
+vmdk_read_cid(BlockDriverState *bs, int parent, uint32_t *pcid)
{
char *desc;
uint32_t cid;
BDRVVmdkState *s = bs->opaque;
int ret = 0;
- desc = g_malloc0(DESC_SIZE);
- tmp_desc = g_malloc0(DESC_SIZE);
- ret = bdrv_co_pread(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
+ size_t desc_buf_size;
+
+ if (s->desc_offset == 0) {
+ desc_buf_size = bdrv_getlength(bs->file->bs);
+ if (desc_buf_size > 16ULL << 20) {
+ error_report("VMDK description file too big");
+ return -EFBIG;
+ }
+ } else {
+ desc_buf_size = DESC_SIZE;
+ }
+
+ desc = g_malloc0(desc_buf_size);
+ tmp_desc = g_malloc0(desc_buf_size);
+ ret = bdrv_co_pread(bs->file, s->desc_offset, desc_buf_size, desc, 0);
if (ret < 0) {
goto out;
}
- desc[DESC_SIZE - 1] = '\0';
+ desc[desc_buf_size - 1] = '\0';
tmp_str = strstr(desc, "parentCID");
if (tmp_str == NULL) {
ret = -EINVAL;
goto out;
}
- pstrcpy(tmp_desc, DESC_SIZE, tmp_str);
+ pstrcpy(tmp_desc, desc_buf_size, tmp_str);
p_name = strstr(desc, "CID");
if (p_name != NULL) {
p_name += sizeof("CID");
- snprintf(p_name, DESC_SIZE - (p_name - desc), "%" PRIx32 "\n", cid);
- pstrcat(desc, DESC_SIZE, tmp_desc);
+ snprintf(p_name, desc_buf_size - (p_name - desc), "%" PRIx32 "\n", cid);
+ pstrcat(desc, desc_buf_size, tmp_desc);
}
- ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, DESC_SIZE, desc, 0);
+ ret = bdrv_co_pwrite_sync(bs->file, s->desc_offset, desc_buf_size, desc, 0);
out:
g_free(desc);
return ret;
}
-static int coroutine_fn vmdk_is_cid_valid(BlockDriverState *bs)
+static int coroutine_fn GRAPH_RDLOCK vmdk_is_cid_valid(BlockDriverState *bs)
{
BDRVVmdkState *s = bs->opaque;
uint32_t cur_pcid;
BDRVVmdkReopenState *rs;
int i;
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
assert(state != NULL);
assert(state->bs != NULL);
assert(state->opaque == NULL);
BDRVVmdkReopenState *rs = state->opaque;
int i;
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
for (i = 0; i < s->num_extents; i++) {
if (rs->extents_using_bs_file[i]) {
s->extents[i].file = state->bs->file;
vmdk_reopen_clean(state);
}
-static int vmdk_parent_open(BlockDriverState *bs)
+static int GRAPH_RDLOCK vmdk_parent_open(BlockDriverState *bs)
{
char *p_name;
char *desc;
return 0;
}
-static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent,
- Error **errp)
+static int GRAPH_RDLOCK
+vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent, Error **errp)
{
int ret;
size_t l1_size;
return ret;
}
-static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
- BdrvChild *file,
- int flags, Error **errp)
+static int GRAPH_RDLOCK
+vmdk_open_vmfs_sparse(BlockDriverState *bs, BdrvChild *file, int flags,
+ Error **errp)
{
int ret;
uint32_t magic;
return 0;
}
-static int vmdk_open_se_sparse(BlockDriverState *bs,
- BdrvChild *file,
- int flags, Error **errp)
+static int GRAPH_RDLOCK
+vmdk_open_se_sparse(BlockDriverState *bs, BdrvChild *file, int flags,
+ Error **errp)
{
int ret;
VMDKSESparseConstHeader const_header;
return buf;
}
-static int vmdk_open_vmdk4(BlockDriverState *bs,
- BdrvChild *file,
- int flags, QDict *options, Error **errp)
+static int GRAPH_RDLOCK
+vmdk_open_vmdk4(BlockDriverState *bs, BdrvChild *file, int flags,
+ QDict *options, Error **errp)
{
int ret;
uint32_t magic;
}
/* Open an extent file and append to bs array */
-static int vmdk_open_sparse(BlockDriverState *bs, BdrvChild *file, int flags,
- char *buf, QDict *options, Error **errp)
+static int GRAPH_RDLOCK
+vmdk_open_sparse(BlockDriverState *bs, BdrvChild *file, int flags,
+ char *buf, QDict *options, Error **errp)
{
uint32_t magic;
return s;
}
-static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
- QDict *options, Error **errp)
+static int GRAPH_RDLOCK
+vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
+ Error **errp)
{
int ret;
int matches;
char extent_opt_prefix[32];
Error *local_err = NULL;
+ GLOBAL_STATE_CODE();
+
for (p = desc; *p; p = next_line(p)) {
/* parse extent line in one of below formats:
*
ret = vmdk_add_extent(bs, extent_file, true, sectors,
0, 0, 0, 0, 0, &extent, errp);
if (ret < 0) {
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_graph_rdlock_main_loop();
goto out;
}
extent->flat_start_offset = flat_offset << 9;
}
g_free(buf);
if (ret) {
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_graph_rdlock_main_loop();
goto out;
}
extent = &s->extents[s->num_extents - 1];
} else if (!strcmp(type, "SESPARSE")) {
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
if (ret) {
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_graph_rdlock_main_loop();
goto out;
}
extent = &s->extents[s->num_extents - 1];
} else {
error_setg(errp, "Unsupported extent type '%s'", type);
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_graph_rdlock_main_loop();
ret = -ENOTSUP;
goto out;
}
return ret;
}
-static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
- QDict *options, Error **errp)
+static int GRAPH_RDLOCK
+vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf, QDict *options,
+ Error **errp)
{
int ret;
char ct[128];
error_setg(&s->migration_blocker, "The vmdk format used by node '%s' "
"does not support live migration",
bdrv_get_device_or_node_name(bs));
- ret = migrate_add_blocker(s->migration_blocker, errp);
+ ret = migrate_add_blocker_normal(&s->migration_blocker, errp);
if (ret < 0) {
- error_free(s->migration_blocker);
goto fail;
}
ret = -EINVAL;
goto exit;
}
+
+ bdrv_graph_co_rdlock();
ret = vmdk_read_cid(blk_bs(backing), 0, &parent_cid);
+ bdrv_graph_co_rdunlock();
blk_co_unref(backing);
if (ret) {
error_setg(errp, "Failed to read parent CID");
vmdk_free_extents(bs);
g_free(s->create_type);
- migrate_del_blocker(s->migration_blocker);
- error_free(s->migration_blocker);
+ migrate_del_blocker(&s->migration_blocker);
}
static int64_t coroutine_fn GRAPH_RDLOCK
return ret;
}
-static int vmdk_has_zero_init(BlockDriverState *bs)
+static int GRAPH_RDLOCK vmdk_has_zero_init(BlockDriverState *bs)
{
int i;
BDRVVmdkState *s = bs->opaque;
return 1;
}
-static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
+static VmdkExtentInfo * GRAPH_RDLOCK vmdk_get_extent_info(VmdkExtent *extent)
{
VmdkExtentInfo *info = g_new0(VmdkExtentInfo, 1);
return ret;
}
-static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs,
- Error **errp)
+static ImageInfoSpecific * GRAPH_RDLOCK
+vmdk_get_specific_info(BlockDriverState *bs, Error **errp)
{
int i;
BDRVVmdkState *s = bs->opaque;
return 0;
}
-static void vmdk_gather_child_options(BlockDriverState *bs, QDict *target,
- bool backing_overridden)
+static void GRAPH_RDLOCK
+vmdk_gather_child_options(BlockDriverState *bs, QDict *target,
+ bool backing_overridden)
{
/* No children but file and backing can be explicitly specified (TODO) */
qdict_put(target, "file",