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;
vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
Error **errp)
{
+ ERRP_GUARD();
int ret;
int matches;
char access[11];
0, 0, 0, 0, 0, &extent, errp);
if (ret < 0) {
bdrv_graph_rdunlock_main_loop();
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
g_free(buf);
if (ret) {
bdrv_graph_rdunlock_main_loop();
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
if (ret) {
bdrv_graph_rdunlock_main_loop();
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
} else {
error_setg(errp, "Unsupported extent type '%s'", type);
bdrv_graph_rdunlock_main_loop();
- bdrv_graph_wrlock(NULL);
+ bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
bdrv_graph_rdlock_main_loop();
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 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;
ImageInfoSpecific *spec_info = g_new0(ImageInfoSpecific, 1);
VmdkExtentInfoList **tail;
- assume_graph_lock(); /* FIXME */
-
*spec_info = (ImageInfoSpecific){
.type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
.u = {
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",