tools: qemu: Add patches to support adapter_type and monolithicFlat
[openwrt/openwrt.git] / tools / qemu / patches / 0009-VMDK-change-get_cluster_offset-return-type.patch
1 From 9e1ddc6967e8739f4fa47fa4f6a767ebe319f6ff Mon Sep 17 00:00:00 2001
2 From: Fam Zheng <famcool@gmail.com>
3 Date: Tue, 12 Jul 2011 19:56:35 +0800
4 Subject: [PATCH 09/12] VMDK: change get_cluster_offset return type
5
6 The return type of get_cluster_offset was an offset that use 0 to denote
7 'not allocated', this will be no longer true for flat extents, as we see
8 flat extent file as a single huge cluster whose offset is 0 and length
9 is the whole file length.
10 So now we use int return value, 0 means success and otherwise offset
11 invalid.
12
13 Signed-off-by: Fam Zheng <famcool@gmail.com>
14 Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
15 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16 ---
17 block/vmdk.c | 79 ++++++++++++++++++++++++++++++++----------------------------
18 1 file changed, 42 insertions(+), 37 deletions(-)
19
20 --- a/block/vmdk.c
21 +++ b/block/vmdk.c
22 @@ -665,26 +665,31 @@ static int vmdk_L2update(VmdkExtent *ext
23 return 0;
24 }
25
26 -static uint64_t get_cluster_offset(BlockDriverState *bs,
27 +static int get_cluster_offset(BlockDriverState *bs,
28 VmdkExtent *extent,
29 VmdkMetaData *m_data,
30 - uint64_t offset, int allocate)
31 + uint64_t offset,
32 + int allocate,
33 + uint64_t *cluster_offset)
34 {
35 unsigned int l1_index, l2_offset, l2_index;
36 int min_index, i, j;
37 uint32_t min_count, *l2_table, tmp = 0;
38 - uint64_t cluster_offset;
39
40 if (m_data)
41 m_data->valid = 0;
42 + if (extent->flat) {
43 + *cluster_offset = 0;
44 + return 0;
45 + }
46
47 l1_index = (offset >> 9) / extent->l1_entry_sectors;
48 if (l1_index >= extent->l1_size) {
49 - return 0;
50 + return -1;
51 }
52 l2_offset = extent->l1_table[l1_index];
53 if (!l2_offset) {
54 - return 0;
55 + return -1;
56 }
57 for (i = 0; i < L2_CACHE_SIZE; i++) {
58 if (l2_offset == extent->l2_cache_offsets[i]) {
59 @@ -714,28 +719,29 @@ static uint64_t get_cluster_offset(Block
60 l2_table,
61 extent->l2_size * sizeof(uint32_t)
62 ) != extent->l2_size * sizeof(uint32_t)) {
63 - return 0;
64 + return -1;
65 }
66
67 extent->l2_cache_offsets[min_index] = l2_offset;
68 extent->l2_cache_counts[min_index] = 1;
69 found:
70 l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
71 - cluster_offset = le32_to_cpu(l2_table[l2_index]);
72 + *cluster_offset = le32_to_cpu(l2_table[l2_index]);
73
74 - if (!cluster_offset) {
75 - if (!allocate)
76 - return 0;
77 + if (!*cluster_offset) {
78 + if (!allocate) {
79 + return -1;
80 + }
81
82 // Avoid the L2 tables update for the images that have snapshots.
83 - cluster_offset = bdrv_getlength(extent->file);
84 + *cluster_offset = bdrv_getlength(extent->file);
85 bdrv_truncate(
86 extent->file,
87 - cluster_offset + (extent->cluster_sectors << 9)
88 + *cluster_offset + (extent->cluster_sectors << 9)
89 );
90
91 - cluster_offset >>= 9;
92 - tmp = cpu_to_le32(cluster_offset);
93 + *cluster_offset >>= 9;
94 + tmp = cpu_to_le32(*cluster_offset);
95 l2_table[l2_index] = tmp;
96
97 /* First of all we write grain itself, to avoid race condition
98 @@ -744,8 +750,8 @@ static uint64_t get_cluster_offset(Block
99 * or inappropriate VM shutdown.
100 */
101 if (get_whole_cluster(
102 - bs, extent, cluster_offset, offset, allocate) == -1)
103 - return 0;
104 + bs, extent, *cluster_offset, offset, allocate) == -1)
105 + return -1;
106
107 if (m_data) {
108 m_data->offset = tmp;
109 @@ -755,8 +761,8 @@ static uint64_t get_cluster_offset(Block
110 m_data->valid = 1;
111 }
112 }
113 - cluster_offset <<= 9;
114 - return cluster_offset;
115 + *cluster_offset <<= 9;
116 + return 0;
117 }
118
119 static VmdkExtent *find_extent(BDRVVmdkState *s,
120 @@ -780,7 +786,6 @@ static int vmdk_is_allocated(BlockDriver
121 int nb_sectors, int *pnum)
122 {
123 BDRVVmdkState *s = bs->opaque;
124 -
125 int64_t index_in_cluster, n, ret;
126 uint64_t offset;
127 VmdkExtent *extent;
128 @@ -789,15 +794,13 @@ static int vmdk_is_allocated(BlockDriver
129 if (!extent) {
130 return 0;
131 }
132 - if (extent->flat) {
133 - n = extent->end_sector - sector_num;
134 - ret = 1;
135 - } else {
136 - offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
137 - index_in_cluster = sector_num % extent->cluster_sectors;
138 - n = extent->cluster_sectors - index_in_cluster;
139 - ret = offset ? 1 : 0;
140 - }
141 + ret = get_cluster_offset(bs, extent, NULL,
142 + sector_num * 512, 0, &offset);
143 + /* get_cluster_offset returning 0 means success */
144 + ret = !ret;
145 +
146 + index_in_cluster = sector_num % extent->cluster_sectors;
147 + n = extent->cluster_sectors - index_in_cluster;
148 if (n > nb_sectors)
149 n = nb_sectors;
150 *pnum = n;
151 @@ -818,14 +821,15 @@ static int vmdk_read(BlockDriverState *b
152 if (!extent) {
153 return -EIO;
154 }
155 - cluster_offset = get_cluster_offset(
156 - bs, extent, NULL, sector_num << 9, 0);
157 + ret = get_cluster_offset(
158 + bs, extent, NULL,
159 + sector_num << 9, 0, &cluster_offset);
160 index_in_cluster = sector_num % extent->cluster_sectors;
161 n = extent->cluster_sectors - index_in_cluster;
162 if (n > nb_sectors)
163 n = nb_sectors;
164 - if (!cluster_offset) {
165 - // try to read from parent image, if exist
166 + if (ret) {
167 + /* if not allocated, try to read from parent image, if exist */
168 if (bs->backing_hd) {
169 if (!vmdk_is_cid_valid(bs))
170 return -1;
171 @@ -851,7 +855,7 @@ static int vmdk_write(BlockDriverState *
172 {
173 BDRVVmdkState *s = bs->opaque;
174 VmdkExtent *extent = NULL;
175 - int n;
176 + int n, ret;
177 int64_t index_in_cluster;
178 uint64_t cluster_offset;
179 VmdkMetaData m_data;
180 @@ -869,13 +873,14 @@ static int vmdk_write(BlockDriverState *
181 if (!extent) {
182 return -EIO;
183 }
184 - cluster_offset = get_cluster_offset(
185 + ret = get_cluster_offset(
186 bs,
187 extent,
188 &m_data,
189 - sector_num << 9, 1);
190 - if (!cluster_offset) {
191 - return -1;
192 + sector_num << 9, 1,
193 + &cluster_offset);
194 + if (ret) {
195 + return -EINVAL;
196 }
197 index_in_cluster = sector_num % extent->cluster_sectors;
198 n = extent->cluster_sectors - index_in_cluster;