summaryrefslogtreecommitdiffstats
path: root/block/vmdk.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/vmdk.c')
-rw-r--r--block/vmdk.c82
1 files changed, 51 insertions, 31 deletions
diff --git a/block/vmdk.c b/block/vmdk.c
index 5d16ec4..6be592f 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -90,6 +90,7 @@ typedef struct VmdkExtent {
} VmdkExtent;
typedef struct BDRVVmdkState {
+ CoMutex lock;
int desc_offset;
bool cid_updated;
uint32_t parent_cid;
@@ -283,10 +284,12 @@ static int vmdk_parent_open(BlockDriverState *bs)
char *p_name;
char desc[DESC_SIZE + 1];
BDRVVmdkState *s = bs->opaque;
+ int ret;
desc[DESC_SIZE] = '\0';
- if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
- return -1;
+ ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
+ if (ret < 0) {
+ return ret;
}
p_name = strstr(desc, "parentFileNameHint");
@@ -296,10 +299,10 @@ static int vmdk_parent_open(BlockDriverState *bs)
p_name += sizeof("parentFileNameHint") + 1;
end_name = strchr(p_name, '\"');
if (end_name == NULL) {
- return -1;
+ return -EINVAL;
}
if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
- return -1;
+ return -EINVAL;
}
pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
@@ -622,19 +625,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
return -ENOTSUP;
}
s->desc_offset = 0;
- ret = vmdk_parse_extents(buf, bs, bs->file->filename);
- if (ret) {
- vmdk_free_extents(bs);
- return ret;
- }
-
- /* try to open parent images, if exist */
- if (vmdk_parent_open(bs)) {
- vmdk_free_extents(bs);
- return -EINVAL;
- }
- s->parent_cid = vmdk_read_cid(bs, 1);
- return 0;
+ return vmdk_parse_extents(buf, bs, bs->file->filename);
}
static int vmdk_open(BlockDriverState *bs, int flags)
@@ -644,17 +635,24 @@ static int vmdk_open(BlockDriverState *bs, int flags)
if (vmdk_open_sparse(bs, bs->file, flags) == 0) {
s->desc_offset = 0x200;
- /* try to open parent images, if exist */
- ret = vmdk_parent_open(bs);
+ } else {
+ ret = vmdk_open_desc_file(bs, flags, 0);
if (ret) {
- vmdk_free_extents(bs);
- return ret;
+ goto fail;
}
- s->parent_cid = vmdk_read_cid(bs, 1);
- return 0;
- } else {
- return vmdk_open_desc_file(bs, flags, 0);
}
+ /* try to open parent images, if exist */
+ ret = vmdk_parent_open(bs);
+ if (ret) {
+ goto fail;
+ }
+ s->parent_cid = vmdk_read_cid(bs, 1);
+ qemu_co_mutex_init(&s->lock);
+ return ret;
+
+fail:
+ vmdk_free_extents(bs);
+ return ret;
}
static int get_whole_cluster(BlockDriverState *bs,
@@ -1026,6 +1024,17 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
return 0;
}
+static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
+ uint8_t *buf, int nb_sectors)
+{
+ int ret;
+ BDRVVmdkState *s = bs->opaque;
+ qemu_co_mutex_lock(&s->lock);
+ ret = vmdk_read(bs, sector_num, buf, nb_sectors);
+ qemu_co_mutex_unlock(&s->lock);
+ return ret;
+}
+
static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
@@ -1107,6 +1116,17 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
return 0;
}
+static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+ int ret;
+ BDRVVmdkState *s = bs->opaque;
+ qemu_co_mutex_lock(&s->lock);
+ ret = vmdk_write(bs, sector_num, buf, nb_sectors);
+ qemu_co_mutex_unlock(&s->lock);
+ return ret;
+}
+
static int vmdk_create_extent(const char *filename, int64_t filesize,
bool flat, bool compress)
@@ -1474,14 +1494,14 @@ static void vmdk_close(BlockDriverState *bs)
vmdk_free_extents(bs);
}
-static int vmdk_flush(BlockDriverState *bs)
+static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)
{
int i, ret, err;
BDRVVmdkState *s = bs->opaque;
- ret = bdrv_flush(bs->file);
+ ret = bdrv_co_flush(bs->file);
for (i = 0; i < s->num_extents; i++) {
- err = bdrv_flush(s->extents[i].file);
+ err = bdrv_co_flush(s->extents[i].file);
if (err < 0) {
ret = err;
}
@@ -1544,11 +1564,11 @@ static BlockDriver bdrv_vmdk = {
.instance_size = sizeof(BDRVVmdkState),
.bdrv_probe = vmdk_probe,
.bdrv_open = vmdk_open,
- .bdrv_read = vmdk_read,
- .bdrv_write = vmdk_write,
+ .bdrv_read = vmdk_co_read,
+ .bdrv_write = vmdk_co_write,
.bdrv_close = vmdk_close,
.bdrv_create = vmdk_create,
- .bdrv_flush = vmdk_flush,
+ .bdrv_co_flush = vmdk_co_flush,
.bdrv_is_allocated = vmdk_is_allocated,
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
OpenPOWER on IntegriCloud