[Qemu-devel] [PATCH v3 04/12] VMDK: separate vmdk_open by format version

2011-06-26 Thread Fam Zheng
Separate vmdk_open by subformats to:
* vmdk_open_vmdk3
* vmdk_open_vmdk4

Signed-off-by: Fam Zheng famc...@gmail.com
---
 block/vmdk.c |  255 --
 1 files changed, 177 insertions(+), 78 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 0517fdf..55b1e2b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -401,84 +401,26 @@ static int vmdk_parent_open(BlockDriverState *bs)
 return 0;
 }
 
-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 ret;
 int l1_size, i;
-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;
-s-extents = qemu_mallocz(sizeof(VmdkExtent));
-s-num_extents = 1;
-if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header))
-!= sizeof(header)) {
-goto fail;
-}
-extent = s-extents;
-extent-flat = false;
-extent-file = bs-file;
-extent-cluster_sectors = le32_to_cpu(header.granularity);
-extent-l2_size = 1  9;
-extent-l1_size = 1  6;
-extent-sectors = le32_to_cpu(header.disk_sectors);
-extent-end_sector = le32_to_cpu(header.disk_sectors);
-extent-l1_table_offset = le32_to_cpu(header.l1dir_offset)  9;
-extent-l1_backup_table_offset = 0;
-extent-l1_entry_sectors = extent-l2_size * extent-cluster_sectors;
-} else if (magic == VMDK4_MAGIC) {
-VMDK4Header header;
-s-extents = qemu_mallocz(sizeof(VmdkExtent));
-s-num_extents = 1;
-if (bdrv_pread(bs-file, sizeof(magic), header, sizeof(header))
-!= sizeof(header)) {
-goto fail;
-}
-extent = s-extents;
-extent-file = bs-file;
-extent-sectors = le64_to_cpu(header.capacity);
-extent-end_sector = le64_to_cpu(header.capacity);
-extent-cluster_sectors = le64_to_cpu(header.granularity);
-extent-l2_size = le32_to_cpu(header.num_gtes_per_gte);
-extent-l1_entry_sectors = extent-l2_size * extent-cluster_sectors;
-if (extent-l1_entry_sectors = 0) {
-goto fail;
-}
-extent-l1_size = (extent-sectors + extent-l1_entry_sectors - 1)
-/ extent-l1_entry_sectors;
-extent-l1_table_offset = le64_to_cpu(header.rgd_offset)  9;
-extent-l1_backup_table_offset = le64_to_cpu(header.gd_offset)  9;
-
-// 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;
-}
-
-/* sum up the total sectors */
-bs-total_sectors = 0;
-for (i = 0; i  s-num_extents; i++) {
-bs-total_sectors += s-extents[i].sectors;
-}
 
 /* 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) {
+if (!extent-l1_table) {
+ret = -ENOMEM;
 goto fail;
 }
+ret = bdrv_pread(bs-file,
+extent-l1_table_offset,
+extent-l1_table,
+l1_size);
+if (ret != l1_size) {
+ret = ret  0 ? ret : -EIO;
+goto fail_l1;
+}
 for (i = 0; i  extent-l1_size; i++) {
 le32_to_cpus(extent-l1_table[i]);
 }
@@ -493,21 +435,178 @@ static int vmdk_open(BlockDriverState *bs, int flags)
 goto fail;
 }
 for (i = 0; i  extent-l1_size; i++) {
+if (!extent-l1_backup_table) {
+ret = -ENOMEM;
+goto fail_l1;
+}
+}
+ret = bdrv_pread(bs-file,
+extent-l1_backup_table_offset,
+extent-l1_backup_table,
+l1_size);
+if (ret != l1_size) {
+ret = ret  0 ? ret : -EIO;
+goto fail;
+}
+for (i = 0; i  extent-l1_size; i++) {
 le32_to_cpus(extent-l1_backup_table[i]);
 }
 }
 
 extent-l2_cache =
 qemu_malloc(extent-l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
+if (!extent-l2_cache) {
+ret = -ENOMEM;
+goto fail_l1b;
+}
 return 0;
+ fail_l1b:
+qemu_free(extent-l1_backup_table);
+ fail_l1:
+qemu_free(extent-l1_table);
  fail:
-for (i = 0; i  s-num_extents; i++) {
-qemu_free(s-extents[i].l1_backup_table);
-qemu_free(s-extents[i].l1_table);
-qemu_free(s-extents[i].l2_cache);
+return ret;
+}
+
+/* Create and append 

Re: [Qemu-devel] [PATCH v3 04/12] VMDK: separate vmdk_open by format version

2011-06-26 Thread Stefan Hajnoczi
On Mon, Jun 27, 2011 at 4:48 AM, Fam Zheng famc...@gmail.com wrote:
 -        extent = s-extents;
 -        extent-flat = false;
 -        extent-file = bs-file;
 -        extent-cluster_sectors = le32_to_cpu(header.granularity);
 -        extent-l2_size = 1  9;
 -        extent-l1_size = 1  6;
 -        extent-sectors = le32_to_cpu(header.disk_sectors);
 -        extent-end_sector = le32_to_cpu(header.disk_sectors);
 -        extent-l1_table_offset = le32_to_cpu(header.l1dir_offset)  9;
 -        extent-l1_backup_table_offset = 0;
 -        extent-l1_entry_sectors = extent-l2_size * extent-cluster_sectors;

Please move vmdk_add_extent() to the patch where you added this code.
A nice patch series minimizes the amount of code that gets added
temporarily and then removed again.

 +/* Create and append extent to the entext array. Return the added VmdkExtent

s/entext/extent/

 + * address. return NULL if allocation failed. */
 +static int vmdk_add_extent(BlockDriverState *bs,
 +                           BlockDriverState *file, bool flat, int64_t 
 sectors,
 +                           int64_t l1_offset, int64_t l1_backup_offset,
 +                           uint32_t l1_size,
 +                           int l2_size, unsigned int cluster_sectors,
 +                           VmdkExtent **new_extent)
 +{
 +    VmdkExtent *extent, *p;
 +    BDRVVmdkState *s = bs-opaque;
 +
 +    p = qemu_realloc(s-extents, (s-num_extents + 1) * sizeof(VmdkExtent));
 +    if (!p) {
 +        return -ENOMEM;
 +    }

qemu_realloc() never returns NULL.

 +    s-extents = p;
 +    extent = s-extents[s-num_extents];
 +    s-num_extents++;
 +
 +    memset(extent, 0, sizeof(VmdkExtent));
 +    extent-file = file;
 +    extent-flat = flat;
 +    extent-sectors = sectors;
 +    extent-l1_table_offset = l1_offset;
 +    extent-l1_backup_table_offset = l1_backup_offset;
 +    extent-l1_size = l1_size;
 +    extent-l1_entry_sectors = l2_size * cluster_sectors;
 +    extent-l2_size = l2_size;
 +    extent-cluster_sectors = cluster_sectors;
 +
 +    if (s-num_extents  1) {
 +        extent-end_sector = (*(extent - 1)).end_sector + extent-sectors;
 +    } else {
 +        extent-end_sector = extent-sectors;
 +    }
 +    bs-total_sectors = extent-end_sector;
 +    if (new_extent) {
 +        *new_extent = extent;
 +    }
 +    return 0;

Since this function cannot fail it would be simpler to make the return
value VmdkExtent *.

Stefan