123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001
- From: Fam Zheng <[email protected]>
- 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 <[email protected]>
- Reviewed-by: Stefan Hajnoczi <[email protected]>
- Signed-off-by: Kevin Wolf <[email protected]>
- ---
- 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;
|