build/image: warn if missing qemu-img for VDI/VMDK
[openwrt/staging/mkresin.git] / tools / qemu / patches / 0005-VMDK-separate-vmdk_open-by-format-version.patch
1 From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001
2 From: Fam Zheng <famcool@gmail.com>
3 Date: Tue, 12 Jul 2011 19:56:31 +0800
4 Subject: [PATCH 05/12] VMDK: separate vmdk_open by format version
5
6 Separate vmdk_open by subformats to:
7 * vmdk_open_vmdk3
8 * vmdk_open_vmdk4
9
10 Signed-off-by: Fam Zheng <famcool@gmail.com>
11 Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
12 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13 ---
14 block/vmdk.c | 178 +++++++++++++++++++++++++++++++++++++----------------------
15 1 file changed, 112 insertions(+), 66 deletions(-)
16
17 --- a/block/vmdk.c
18 +++ b/block/vmdk.c
19 @@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(Block
20 return extent;
21 }
22
23 -
24 -static int vmdk_open(BlockDriverState *bs, int flags)
25 +static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
26 {
27 - BDRVVmdkState *s = bs->opaque;
28 - uint32_t magic;
29 - int i;
30 - uint32_t l1_size, l1_entry_sectors;
31 - VmdkExtent *extent = NULL;
32 -
33 - if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
34 - goto fail;
35 -
36 - magic = be32_to_cpu(magic);
37 - if (magic == VMDK3_MAGIC) {
38 - VMDK3Header header;
39 - if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
40 - != sizeof(header)) {
41 - goto fail;
42 - }
43 - extent = vmdk_add_extent(bs, bs->file, false,
44 - le32_to_cpu(header.disk_sectors),
45 - le32_to_cpu(header.l1dir_offset) << 9, 0,
46 - 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
47 - } else if (magic == VMDK4_MAGIC) {
48 - VMDK4Header header;
49 - if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
50 - != sizeof(header)) {
51 - goto fail;
52 - }
53 - l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
54 - * le64_to_cpu(header.granularity);
55 - l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
56 - / l1_entry_sectors;
57 - extent = vmdk_add_extent(bs, bs->file, false,
58 - le64_to_cpu(header.capacity),
59 - le64_to_cpu(header.gd_offset) << 9,
60 - le64_to_cpu(header.rgd_offset) << 9,
61 - l1_size,
62 - le32_to_cpu(header.num_gtes_per_gte),
63 - le64_to_cpu(header.granularity));
64 - if (extent->l1_entry_sectors <= 0) {
65 - goto fail;
66 - }
67 - // try to open parent images, if exist
68 - if (vmdk_parent_open(bs) != 0)
69 - goto fail;
70 - // write the CID once after the image creation
71 - s->parent_cid = vmdk_read_cid(bs,1);
72 - } else {
73 - goto fail;
74 - }
75 + int ret;
76 + int l1_size, i;
77
78 /* read the L1 table */
79 l1_size = extent->l1_size * sizeof(uint32_t);
80 extent->l1_table = qemu_malloc(l1_size);
81 - if (bdrv_pread(bs->file,
82 - extent->l1_table_offset,
83 - extent->l1_table,
84 - l1_size)
85 - != l1_size) {
86 - goto fail;
87 + ret = bdrv_pread(extent->file,
88 + extent->l1_table_offset,
89 + extent->l1_table,
90 + l1_size);
91 + if (ret < 0) {
92 + goto fail_l1;
93 }
94 for (i = 0; i < extent->l1_size; i++) {
95 le32_to_cpus(&extent->l1_table[i]);
96 @@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *b
97
98 if (extent->l1_backup_table_offset) {
99 extent->l1_backup_table = qemu_malloc(l1_size);
100 - if (bdrv_pread(bs->file,
101 - extent->l1_backup_table_offset,
102 - extent->l1_backup_table,
103 - l1_size)
104 - != l1_size) {
105 - goto fail;
106 + ret = bdrv_pread(extent->file,
107 + extent->l1_backup_table_offset,
108 + extent->l1_backup_table,
109 + l1_size);
110 + if (ret < 0) {
111 + goto fail_l1b;
112 }
113 for (i = 0; i < extent->l1_size; i++) {
114 le32_to_cpus(&extent->l1_backup_table[i]);
115 @@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *b
116 extent->l2_cache =
117 qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
118 return 0;
119 + fail_l1b:
120 + qemu_free(extent->l1_backup_table);
121 + fail_l1:
122 + qemu_free(extent->l1_table);
123 + return ret;
124 +}
125 +
126 +static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
127 +{
128 + int ret;
129 + uint32_t magic;
130 + VMDK3Header header;
131 + VmdkExtent *extent;
132 +
133 + ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
134 + if (ret < 0) {
135 + goto fail;
136 + }
137 + extent = vmdk_add_extent(bs,
138 + bs->file, false,
139 + le32_to_cpu(header.disk_sectors),
140 + le32_to_cpu(header.l1dir_offset) << 9,
141 + 0, 1 << 6, 1 << 9,
142 + le32_to_cpu(header.granularity));
143 + ret = vmdk_init_tables(bs, extent);
144 + if (ret) {
145 + /* vmdk_init_tables cleans up on fail, so only free allocation of
146 + * vmdk_add_extent here. */
147 + goto fail;
148 + }
149 + return 0;
150 fail:
151 vmdk_free_extents(bs);
152 - return -1;
153 + return ret;
154 +}
155 +
156 +static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
157 +{
158 + int ret;
159 + uint32_t magic;
160 + uint32_t l1_size, l1_entry_sectors;
161 + VMDK4Header header;
162 + BDRVVmdkState *s = bs->opaque;
163 + VmdkExtent *extent;
164 +
165 + ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
166 + if (ret < 0) {
167 + goto fail;
168 + }
169 + l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
170 + * le64_to_cpu(header.granularity);
171 + l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
172 + / l1_entry_sectors;
173 + extent = vmdk_add_extent(bs, bs->file, false,
174 + le64_to_cpu(header.capacity),
175 + le64_to_cpu(header.gd_offset) << 9,
176 + le64_to_cpu(header.rgd_offset) << 9,
177 + l1_size,
178 + le32_to_cpu(header.num_gtes_per_gte),
179 + le64_to_cpu(header.granularity));
180 + if (extent->l1_entry_sectors <= 0) {
181 + ret = -EINVAL;
182 + goto fail;
183 + }
184 + /* try to open parent images, if exist */
185 + ret = vmdk_parent_open(bs);
186 + if (ret) {
187 + goto fail;
188 + }
189 + s->parent_cid = vmdk_read_cid(bs, 1);
190 + ret = vmdk_init_tables(bs, extent);
191 + if (ret) {
192 + goto fail;
193 + }
194 + return 0;
195 + fail:
196 + vmdk_free_extents(bs);
197 + return ret;
198 +}
199 +
200 +static int vmdk_open(BlockDriverState *bs, int flags)
201 +{
202 + uint32_t magic;
203 +
204 + if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
205 + return -EIO;
206 + }
207 +
208 + magic = be32_to_cpu(magic);
209 + if (magic == VMDK3_MAGIC) {
210 + return vmdk_open_vmdk3(bs, flags);
211 + } else if (magic == VMDK4_MAGIC) {
212 + return vmdk_open_vmdk4(bs, flags);
213 + } else {
214 + return -EINVAL;
215 + }
216 }
217
218 static int get_whole_cluster(BlockDriverState *bs,
219 @@ -630,11 +676,11 @@ static uint64_t get_cluster_offset(Block
220 if (!l2_offset) {
221 return 0;
222 }
223 - for(i = 0; i < L2_CACHE_SIZE; i++) {
224 + for (i = 0; i < L2_CACHE_SIZE; i++) {
225 if (l2_offset == extent->l2_cache_offsets[i]) {
226 /* increment the hit count */
227 if (++extent->l2_cache_counts[i] == 0xffffffff) {
228 - for(j = 0; j < L2_CACHE_SIZE; j++) {
229 + for (j = 0; j < L2_CACHE_SIZE; j++) {
230 extent->l2_cache_counts[j] >>= 1;
231 }
232 }
233 @@ -645,7 +691,7 @@ static uint64_t get_cluster_offset(Block
234 /* not found: load a new entry in the least used one */
235 min_index = 0;
236 min_count = 0xffffffff;
237 - for(i = 0; i < L2_CACHE_SIZE; i++) {
238 + for (i = 0; i < L2_CACHE_SIZE; i++) {
239 if (extent->l2_cache_counts[i] < min_count) {
240 min_count = extent->l2_cache_counts[i];
241 min_index = i;