aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch')
-rw-r--r--tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch241
1 files changed, 241 insertions, 0 deletions
diff --git a/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch b/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch
new file mode 100644
index 0000000000..7323aa13be
--- /dev/null
+++ b/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch
@@ -0,0 +1,241 @@
+From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famcool@gmail.com>
+Date: Tue, 12 Jul 2011 19:56:31 +0800
+Subject: [PATCH 05/12] VMDK: separate vmdk_open by format version
+
+Separate vmdk_open by subformats to:
+* vmdk_open_vmdk3
+* vmdk_open_vmdk4
+
+Signed-off-by: Fam Zheng <famcool@gmail.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ block/vmdk.c | 178 +++++++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 112 insertions(+), 66 deletions(-)
+
+--- a/block/vmdk.c
++++ b/block/vmdk.c
+@@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(Block
+ return extent;
+ }
+
+-
+-static int vmdk_open(BlockDriverState *bs, int flags)
++static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
+ {
+- BDRVVmdkState *s = bs->opaque;
+- uint32_t magic;
+- int i;
+- uint32_t l1_size, l1_entry_sectors;
+- VmdkExtent *extent = NULL;
+-
+- if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
+- goto fail;
+-
+- magic = be32_to_cpu(magic);
+- if (magic == VMDK3_MAGIC) {
+- VMDK3Header header;
+- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
+- != sizeof(header)) {
+- goto fail;
+- }
+- extent = vmdk_add_extent(bs, bs->file, false,
+- le32_to_cpu(header.disk_sectors),
+- le32_to_cpu(header.l1dir_offset) << 9, 0,
+- 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
+- } else if (magic == VMDK4_MAGIC) {
+- VMDK4Header header;
+- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
+- != sizeof(header)) {
+- goto fail;
+- }
+- l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
+- * le64_to_cpu(header.granularity);
+- l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
+- / l1_entry_sectors;
+- extent = vmdk_add_extent(bs, bs->file, false,
+- le64_to_cpu(header.capacity),
+- le64_to_cpu(header.gd_offset) << 9,
+- le64_to_cpu(header.rgd_offset) << 9,
+- l1_size,
+- le32_to_cpu(header.num_gtes_per_gte),
+- le64_to_cpu(header.granularity));
+- if (extent->l1_entry_sectors <= 0) {
+- goto fail;
+- }
+- // try to open parent images, if exist
+- if (vmdk_parent_open(bs) != 0)
+- goto fail;
+- // write the CID once after the image creation
+- s->parent_cid = vmdk_read_cid(bs,1);
+- } else {
+- goto fail;
+- }
++ int ret;
++ int l1_size, i;
+
+ /* read the L1 table */
+ l1_size = extent->l1_size * sizeof(uint32_t);
+ extent->l1_table = qemu_malloc(l1_size);
+- if (bdrv_pread(bs->file,
+- extent->l1_table_offset,
+- extent->l1_table,
+- l1_size)
+- != l1_size) {
+- goto fail;
++ ret = bdrv_pread(extent->file,
++ extent->l1_table_offset,
++ extent->l1_table,
++ l1_size);
++ if (ret < 0) {
++ goto fail_l1;
+ }
+ for (i = 0; i < extent->l1_size; i++) {
+ le32_to_cpus(&extent->l1_table[i]);
+@@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *b
+
+ if (extent->l1_backup_table_offset) {
+ extent->l1_backup_table = qemu_malloc(l1_size);
+- if (bdrv_pread(bs->file,
+- extent->l1_backup_table_offset,
+- extent->l1_backup_table,
+- l1_size)
+- != l1_size) {
+- goto fail;
++ ret = bdrv_pread(extent->file,
++ extent->l1_backup_table_offset,
++ extent->l1_backup_table,
++ l1_size);
++ if (ret < 0) {
++ goto fail_l1b;
+ }
+ for (i = 0; i < extent->l1_size; i++) {
+ le32_to_cpus(&extent->l1_backup_table[i]);
+@@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *b
+ extent->l2_cache =
+ qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
+ return 0;
++ fail_l1b:
++ qemu_free(extent->l1_backup_table);
++ fail_l1:
++ qemu_free(extent->l1_table);
++ return ret;
++}
++
++static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
++{
++ int ret;
++ uint32_t magic;
++ VMDK3Header header;
++ VmdkExtent *extent;
++
++ ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
++ if (ret < 0) {
++ goto fail;
++ }
++ extent = vmdk_add_extent(bs,
++ bs->file, false,
++ le32_to_cpu(header.disk_sectors),
++ le32_to_cpu(header.l1dir_offset) << 9,
++ 0, 1 << 6, 1 << 9,
++ le32_to_cpu(header.granularity));
++ ret = vmdk_init_tables(bs, extent);
++ if (ret) {
++ /* vmdk_init_tables cleans up on fail, so only free allocation of
++ * vmdk_add_extent here. */
++ goto fail;
++ }
++ return 0;
+ fail:
+ vmdk_free_extents(bs);
+- return -1;
++ return ret;
++}
++
++static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
++{
++ int ret;
++ uint32_t magic;
++ uint32_t l1_size, l1_entry_sectors;
++ VMDK4Header header;
++ BDRVVmdkState *s = bs->opaque;
++ VmdkExtent *extent;
++
++ ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
++ if (ret < 0) {
++ goto fail;
++ }
++ l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
++ * le64_to_cpu(header.granularity);
++ l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
++ / l1_entry_sectors;
++ extent = vmdk_add_extent(bs, bs->file, false,
++ le64_to_cpu(header.capacity),
++ le64_to_cpu(header.gd_offset) << 9,
++ le64_to_cpu(header.rgd_offset) << 9,
++ l1_size,
++ le32_to_cpu(header.num_gtes_per_gte),
++ le64_to_cpu(header.granularity));
++ if (extent->l1_entry_sectors <= 0) {
++ ret = -EINVAL;
++ goto fail;
++ }
++ /* try to open parent images, if exist */
++ ret = vmdk_parent_open(bs);
++ if (ret) {
++ goto fail;
++ }
++ s->parent_cid = vmdk_read_cid(bs, 1);
++ ret = vmdk_init_tables(bs, extent);
++ if (ret) {
++ goto fail;
++ }
++ return 0;
++ fail:
++ vmdk_free_extents(bs);
++ return ret;
++}
++
++static int vmdk_open(BlockDriverState *bs, int flags)
++{
++ uint32_t magic;
++
++ if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
++ return -EIO;
++ }
++
++ magic = be32_to_cpu(magic);
++ if (magic == VMDK3_MAGIC) {
++ return vmdk_open_vmdk3(bs, flags);
++ } else if (magic == VMDK4_MAGIC) {
++ return vmdk_open_vmdk4(bs, flags);
++ } else {
++ return -EINVAL;
++ }
+ }
+
+ static int get_whole_cluster(BlockDriverState *bs,
+@@ -630,11 +676,11 @@ static uint64_t get_cluster_offset(Block
+ if (!l2_offset) {
+ return 0;
+ }
+- for(i = 0; i < L2_CACHE_SIZE; i++) {
++ for (i = 0; i < L2_CACHE_SIZE; i++) {
+ if (l2_offset == extent->l2_cache_offsets[i]) {
+ /* increment the hit count */
+ if (++extent->l2_cache_counts[i] == 0xffffffff) {
+- for(j = 0; j < L2_CACHE_SIZE; j++) {
++ for (j = 0; j < L2_CACHE_SIZE; j++) {
+ extent->l2_cache_counts[j] >>= 1;
+ }
+ }
+@@ -645,7 +691,7 @@ static uint64_t get_cluster_offset(Block
+ /* not found: load a new entry in the least used one */
+ min_index = 0;
+ min_count = 0xffffffff;
+- for(i = 0; i < L2_CACHE_SIZE; i++) {
++ for (i = 0; i < L2_CACHE_SIZE; i++) {
+ if (extent->l2_cache_counts[i] < min_count) {
+ min_count = extent->l2_cache_counts[i];
+ min_index = i;