Commit b9fa33a6e4cb65c55798d8cef604f3b57383280e

Authored by aliguori
1 parent f55761a0

block-vpc: Split up struct vpc_subheader (Kevin Wolf)

struct vpc_subheader currently is a union of two completely different
data structures (the Hard Disk Footer and the Dynamic Disk Header).
That doesn't make too much sense, so split them up.

Signed-off-by: Kevin Wolf <kwolf@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6454 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 43 additions and 42 deletions
block-vpc.c
@@ -31,36 +31,31 @@ @@ -31,36 +31,31 @@
31 //#define CACHE 31 //#define CACHE
32 32
33 // always big-endian 33 // always big-endian
34 -struct vpc_subheader {  
35 - char magic[8]; // "conectix" / "cxsparse"  
36 - union {  
37 - struct {  
38 - uint32_t unk1[2];  
39 - uint32_t unk2; // always zero?  
40 - uint32_t subheader_offset;  
41 - uint32_t unk3; // some size?  
42 - char creator[4]; // "vpc "  
43 - uint16_t major;  
44 - uint16_t minor;  
45 - char guest[4]; // "Wi2k"  
46 - uint32_t unk4[7];  
47 - uint8_t vnet_id[16]; // virtual network id, purpose unknown  
48 - // next 16 longs are used, but dunno the purpose  
49 - // next 6 longs unknown, following 7 long maybe a serial  
50 - char padding[HEADER_SIZE - 84];  
51 - } main;  
52 - struct {  
53 - uint32_t unk1[2]; // all bits set  
54 - uint32_t unk2; // always zero?  
55 - uint32_t pagetable_offset;  
56 - uint32_t unk3;  
57 - uint32_t pagetable_entries; // 32bit/entry  
58 - uint32_t pageentry_size; // 512*8*512  
59 - uint32_t nb_sectors;  
60 - char padding[HEADER_SIZE - 40];  
61 - } sparse;  
62 - char padding[HEADER_SIZE - 8];  
63 - } type; 34 +struct vhd_footer {
  35 + char creator[8]; // "conectix
  36 + uint32_t unk1[2];
  37 + uint32_t unk2; // always zero?
  38 + uint32_t subheader_offset;
  39 + uint32_t unk3; // some size?
  40 + char creator_app[4]; // "vpc "
  41 + uint16_t major;
  42 + uint16_t minor;
  43 + char guest[4]; // "Wi2k"
  44 + uint32_t unk4[7];
  45 + uint8_t vnet_id[16]; // virtual network id, purpose unknown
  46 + // next 16 longs are used, but dunno the purpose
  47 + // next 6 longs unknown, following 7 long maybe a serial
  48 +};
  49 +
  50 +struct vhd_dyndisk_header {
  51 + char magic[8]; // "cxsparse"
  52 + uint32_t unk1[2]; // all bits set
  53 + uint32_t unk2; // always zero?
  54 + uint32_t pagetable_offset;
  55 + uint32_t unk3;
  56 + uint32_t pagetable_entries; // 32bit/entry
  57 + uint32_t pageentry_size; // 512*8*512
  58 + uint32_t nb_sectors;
64 }; 59 };
65 60
66 typedef struct BDRVVPCState { 61 typedef struct BDRVVPCState {
@@ -90,7 +85,9 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) @@ -90,7 +85,9 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
90 { 85 {
91 BDRVVPCState *s = bs->opaque; 86 BDRVVPCState *s = bs->opaque;
92 int fd, i; 87 int fd, i;
93 - struct vpc_subheader header; 88 + struct vhd_footer* footer;
  89 + struct vhd_dyndisk_header* dyndisk_header;
  90 + uint8_t buf[HEADER_SIZE];
94 91
95 fd = open(filename, O_RDONLY | O_BINARY); 92 fd = open(filename, O_RDONLY | O_BINARY);
96 if (fd < 0) 93 if (fd < 0)
@@ -100,25 +97,29 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) @@ -100,25 +97,29 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
100 97
101 s->fd = fd; 98 s->fd = fd;
102 99
103 - if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE) 100 + if (read(fd, buf, HEADER_SIZE) != HEADER_SIZE)
104 goto fail; 101 goto fail;
105 102
106 - if (strncmp(header.magic, "conectix", 8)) 103 + footer = (struct vhd_footer*) buf;
  104 + if (strncmp(footer->creator, "conectix", 8))
107 goto fail; 105 goto fail;
108 - lseek(s->fd, be32_to_cpu(header.type.main.subheader_offset), SEEK_SET);  
109 106
110 - if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE) 107 + lseek(s->fd, be32_to_cpu(footer->subheader_offset), SEEK_SET);
  108 + if (read(fd, buf, HEADER_SIZE) != HEADER_SIZE)
111 goto fail; 109 goto fail;
112 110
113 - if (strncmp(header.magic, "cxsparse", 8))  
114 - goto fail; 111 + footer = NULL;
  112 + dyndisk_header = (struct vhd_dyndisk_header*) buf;
  113 +
  114 + if (strncmp(dyndisk_header->magic, "cxsparse", 8))
  115 + goto fail;
115 116
116 - bs->total_sectors = ((uint64_t)be32_to_cpu(header.type.sparse.pagetable_entries) *  
117 - be32_to_cpu(header.type.sparse.pageentry_size)) / 512; 117 + bs->total_sectors = ((uint64_t)be32_to_cpu(dyndisk_header->pagetable_entries) *
  118 + be32_to_cpu(dyndisk_header->pageentry_size)) / 512;
118 119
119 - lseek(s->fd, be32_to_cpu(header.type.sparse.pagetable_offset), SEEK_SET); 120 + lseek(s->fd, be32_to_cpu(dyndisk_header->pagetable_offset), SEEK_SET);
120 121
121 - s->pagetable_entries = be32_to_cpu(header.type.sparse.pagetable_entries); 122 + s->pagetable_entries = be32_to_cpu(dyndisk_header->pagetable_entries);
122 s->pagetable = qemu_malloc(s->pagetable_entries * 4); 123 s->pagetable = qemu_malloc(s->pagetable_entries * 4);
123 if (!s->pagetable) 124 if (!s->pagetable)
124 goto fail; 125 goto fail;
@@ -128,7 +129,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags) @@ -128,7 +129,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
128 for (i = 0; i < s->pagetable_entries; i++) 129 for (i = 0; i < s->pagetable_entries; i++)
129 be32_to_cpus(&s->pagetable[i]); 130 be32_to_cpus(&s->pagetable[i]);
130 131
131 - s->pageentry_size = be32_to_cpu(header.type.sparse.pageentry_size); 132 + s->pageentry_size = be32_to_cpu(dyndisk_header->pageentry_size);
132 #ifdef CACHE 133 #ifdef CACHE
133 s->pageentry_u8 = qemu_malloc(512); 134 s->pageentry_u8 = qemu_malloc(512);
134 if (!s->pageentry_u8) 135 if (!s->pageentry_u8)