aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/vmdk.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/block/vmdk.c b/block/vmdk.c
index b80810802a..f34c16db7c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -526,8 +526,8 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
return ret;
}
-static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
- uint64_t desc_offset, Error **errp);
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
+ Error **errp);
static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
Error **errp)
@@ -576,7 +576,13 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
if (header.capacity == 0) {
uint64_t desc_offset = le64_to_cpu(header.desc_offset);
if (desc_offset) {
- return vmdk_open_desc_file(bs, flags, desc_offset << 9, errp);
+ char *buf = vmdk_read_desc(file, desc_offset << 9, errp);
+ if (!buf) {
+ return -EINVAL;
+ }
+ ret = vmdk_open_desc_file(bs, flags, buf, errp);
+ g_free(buf);
+ return ret;
}
}
@@ -727,16 +733,12 @@ static int vmdk_parse_description(const char *desc, const char *opt_name,
/* Open an extent file and append to bs array */
static int vmdk_open_sparse(BlockDriverState *bs,
- BlockDriverState *file,
- int flags, Error **errp)
+ BlockDriverState *file, int flags,
+ char *buf, Error **errp)
{
uint32_t magic;
- if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
- return -EIO;
- }
-
- magic = be32_to_cpu(magic);
+ magic = ldl_be_p(buf);
switch (magic) {
case VMDK3_MAGIC:
return vmdk_open_vmfs_sparse(bs, file, flags, errp);
@@ -821,8 +823,14 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
extent->flat_start_offset = flat_offset << 9;
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
/* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
- ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, errp);
+ char *buf = vmdk_read_desc(extent_file, 0, errp);
+ if (!buf) {
+ ret = -EINVAL;
+ } else {
+ ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf, errp);
+ }
if (ret) {
+ g_free(buf);
bdrv_unref(extent_file);
return ret;
}
@@ -845,20 +853,13 @@ next_line:
return 0;
}
-static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
- uint64_t desc_offset, Error **errp)
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
+ Error **errp)
{
int ret;
- char *buf;
char ct[128];
BDRVVmdkState *s = bs->opaque;
- buf = vmdk_read_desc(bs->file, desc_offset, errp);
- if (!buf) {
- return -EINVAL;
- goto exit;
- }
-
if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
ret = -EMEDIUMTYPE;
goto exit;
@@ -876,20 +877,25 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
s->desc_offset = 0;
ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
exit:
- g_free(buf);
return ret;
}
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
+ char *buf = NULL;
int ret;
BDRVVmdkState *s = bs->opaque;
- if (vmdk_open_sparse(bs, bs->file, flags, errp) == 0) {
+ buf = vmdk_read_desc(bs->file, 0, errp);
+ if (!buf) {
+ return -EINVAL;
+ }
+
+ if (vmdk_open_sparse(bs, bs->file, flags, buf, errp) == 0) {
s->desc_offset = 0x200;
} else {
- ret = vmdk_open_desc_file(bs, flags, 0, errp);
+ ret = vmdk_open_desc_file(bs, flags, buf, errp);
if (ret) {
goto fail;
}
@@ -908,10 +914,11 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
"vmdk", bs->device_name, "live migration");
migrate_add_blocker(s->migration_blocker);
-
+ g_free(buf);
return 0;
fail:
+ g_free(buf);
g_free(s->create_type);
s->create_type = NULL;
vmdk_free_extents(bs);