root / block / qcow2-cluster.c @ 6cfcb9b8
History | View | Annotate | Download (43.8 kB)
1 | 45aba42f | Kevin Wolf | /*
|
---|---|---|---|
2 | 45aba42f | Kevin Wolf | * Block driver for the QCOW version 2 format
|
3 | 45aba42f | Kevin Wolf | *
|
4 | 45aba42f | Kevin Wolf | * Copyright (c) 2004-2006 Fabrice Bellard
|
5 | 45aba42f | Kevin Wolf | *
|
6 | 45aba42f | Kevin Wolf | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | 45aba42f | Kevin Wolf | * of this software and associated documentation files (the "Software"), to deal
|
8 | 45aba42f | Kevin Wolf | * in the Software without restriction, including without limitation the rights
|
9 | 45aba42f | Kevin Wolf | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | 45aba42f | Kevin Wolf | * copies of the Software, and to permit persons to whom the Software is
|
11 | 45aba42f | Kevin Wolf | * furnished to do so, subject to the following conditions:
|
12 | 45aba42f | Kevin Wolf | *
|
13 | 45aba42f | Kevin Wolf | * The above copyright notice and this permission notice shall be included in
|
14 | 45aba42f | Kevin Wolf | * all copies or substantial portions of the Software.
|
15 | 45aba42f | Kevin Wolf | *
|
16 | 45aba42f | Kevin Wolf | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | 45aba42f | Kevin Wolf | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | 45aba42f | Kevin Wolf | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | 45aba42f | Kevin Wolf | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | 45aba42f | Kevin Wolf | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | 45aba42f | Kevin Wolf | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | 45aba42f | Kevin Wolf | * THE SOFTWARE.
|
23 | 45aba42f | Kevin Wolf | */
|
24 | 45aba42f | Kevin Wolf | |
25 | 45aba42f | Kevin Wolf | #include <zlib.h> |
26 | 45aba42f | Kevin Wolf | |
27 | 45aba42f | Kevin Wolf | #include "qemu-common.h" |
28 | 737e150e | Paolo Bonzini | #include "block/block_int.h" |
29 | 45aba42f | Kevin Wolf | #include "block/qcow2.h" |
30 | 3cce16f4 | Kevin Wolf | #include "trace.h" |
31 | 45aba42f | Kevin Wolf | |
32 | 2cf7cfa1 | Kevin Wolf | int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
|
33 | 2cf7cfa1 | Kevin Wolf | bool exact_size)
|
34 | 45aba42f | Kevin Wolf | { |
35 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
36 | 2cf7cfa1 | Kevin Wolf | int new_l1_size2, ret, i;
|
37 | 45aba42f | Kevin Wolf | uint64_t *new_l1_table; |
38 | 2cf7cfa1 | Kevin Wolf | int64_t new_l1_table_offset, new_l1_size; |
39 | 45aba42f | Kevin Wolf | uint8_t data[12];
|
40 | 45aba42f | Kevin Wolf | |
41 | 72893756 | Stefan Hajnoczi | if (min_size <= s->l1_size)
|
42 | 45aba42f | Kevin Wolf | return 0; |
43 | 72893756 | Stefan Hajnoczi | |
44 | 72893756 | Stefan Hajnoczi | if (exact_size) {
|
45 | 72893756 | Stefan Hajnoczi | new_l1_size = min_size; |
46 | 72893756 | Stefan Hajnoczi | } else {
|
47 | 72893756 | Stefan Hajnoczi | /* Bump size up to reduce the number of times we have to grow */
|
48 | 72893756 | Stefan Hajnoczi | new_l1_size = s->l1_size; |
49 | 72893756 | Stefan Hajnoczi | if (new_l1_size == 0) { |
50 | 72893756 | Stefan Hajnoczi | new_l1_size = 1;
|
51 | 72893756 | Stefan Hajnoczi | } |
52 | 72893756 | Stefan Hajnoczi | while (min_size > new_l1_size) {
|
53 | 72893756 | Stefan Hajnoczi | new_l1_size = (new_l1_size * 3 + 1) / 2; |
54 | 72893756 | Stefan Hajnoczi | } |
55 | 45aba42f | Kevin Wolf | } |
56 | 72893756 | Stefan Hajnoczi | |
57 | 2cf7cfa1 | Kevin Wolf | if (new_l1_size > INT_MAX) {
|
58 | 2cf7cfa1 | Kevin Wolf | return -EFBIG;
|
59 | 2cf7cfa1 | Kevin Wolf | } |
60 | 2cf7cfa1 | Kevin Wolf | |
61 | 45aba42f | Kevin Wolf | #ifdef DEBUG_ALLOC2
|
62 | 2cf7cfa1 | Kevin Wolf | fprintf(stderr, "grow l1_table from %d to %" PRId64 "\n", |
63 | 2cf7cfa1 | Kevin Wolf | s->l1_size, new_l1_size); |
64 | 45aba42f | Kevin Wolf | #endif
|
65 | 45aba42f | Kevin Wolf | |
66 | 45aba42f | Kevin Wolf | new_l1_size2 = sizeof(uint64_t) * new_l1_size;
|
67 | 7267c094 | Anthony Liguori | new_l1_table = g_malloc0(align_offset(new_l1_size2, 512));
|
68 | 45aba42f | Kevin Wolf | memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
|
69 | 45aba42f | Kevin Wolf | |
70 | 45aba42f | Kevin Wolf | /* write new table (align to cluster) */
|
71 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE); |
72 | ed6ccf0f | Kevin Wolf | new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2); |
73 | 5d757b56 | Kevin Wolf | if (new_l1_table_offset < 0) { |
74 | 7267c094 | Anthony Liguori | g_free(new_l1_table); |
75 | 5d757b56 | Kevin Wolf | return new_l1_table_offset;
|
76 | 5d757b56 | Kevin Wolf | } |
77 | 29c1a730 | Kevin Wolf | |
78 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_flush(bs, s->refcount_block_cache); |
79 | 29c1a730 | Kevin Wolf | if (ret < 0) { |
80 | 80fa3341 | Kevin Wolf | goto fail;
|
81 | 29c1a730 | Kevin Wolf | } |
82 | 45aba42f | Kevin Wolf | |
83 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); |
84 | 45aba42f | Kevin Wolf | for(i = 0; i < s->l1_size; i++) |
85 | 45aba42f | Kevin Wolf | new_l1_table[i] = cpu_to_be64(new_l1_table[i]); |
86 | 8b3b7206 | Kevin Wolf | ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2); |
87 | 8b3b7206 | Kevin Wolf | if (ret < 0) |
88 | 45aba42f | Kevin Wolf | goto fail;
|
89 | 45aba42f | Kevin Wolf | for(i = 0; i < s->l1_size; i++) |
90 | 45aba42f | Kevin Wolf | new_l1_table[i] = be64_to_cpu(new_l1_table[i]); |
91 | 45aba42f | Kevin Wolf | |
92 | 45aba42f | Kevin Wolf | /* set new table */
|
93 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE); |
94 | 45aba42f | Kevin Wolf | cpu_to_be32w((uint32_t*)data, new_l1_size); |
95 | 653df36b | Aurelien Jarno | cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset);
|
96 | 8b3b7206 | Kevin Wolf | ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
|
97 | 8b3b7206 | Kevin Wolf | if (ret < 0) { |
98 | 45aba42f | Kevin Wolf | goto fail;
|
99 | fb8fa77c | Kevin Wolf | } |
100 | 7267c094 | Anthony Liguori | g_free(s->l1_table); |
101 | 6cfcb9b8 | Kevin Wolf | qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t),
|
102 | 6cfcb9b8 | Kevin Wolf | QCOW2_DISCARD_OTHER); |
103 | 45aba42f | Kevin Wolf | s->l1_table_offset = new_l1_table_offset; |
104 | 45aba42f | Kevin Wolf | s->l1_table = new_l1_table; |
105 | 45aba42f | Kevin Wolf | s->l1_size = new_l1_size; |
106 | 45aba42f | Kevin Wolf | return 0; |
107 | 45aba42f | Kevin Wolf | fail:
|
108 | 7267c094 | Anthony Liguori | g_free(new_l1_table); |
109 | 6cfcb9b8 | Kevin Wolf | qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2, |
110 | 6cfcb9b8 | Kevin Wolf | QCOW2_DISCARD_OTHER); |
111 | 8b3b7206 | Kevin Wolf | return ret;
|
112 | 45aba42f | Kevin Wolf | } |
113 | 45aba42f | Kevin Wolf | |
114 | 45aba42f | Kevin Wolf | /*
|
115 | 45aba42f | Kevin Wolf | * l2_load
|
116 | 45aba42f | Kevin Wolf | *
|
117 | 45aba42f | Kevin Wolf | * Loads a L2 table into memory. If the table is in the cache, the cache
|
118 | 45aba42f | Kevin Wolf | * is used; otherwise the L2 table is loaded from the image file.
|
119 | 45aba42f | Kevin Wolf | *
|
120 | 45aba42f | Kevin Wolf | * Returns a pointer to the L2 table on success, or NULL if the read from
|
121 | 45aba42f | Kevin Wolf | * the image file failed.
|
122 | 45aba42f | Kevin Wolf | */
|
123 | 45aba42f | Kevin Wolf | |
124 | 55c17e98 | Kevin Wolf | static int l2_load(BlockDriverState *bs, uint64_t l2_offset, |
125 | 55c17e98 | Kevin Wolf | uint64_t **l2_table) |
126 | 45aba42f | Kevin Wolf | { |
127 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
128 | 55c17e98 | Kevin Wolf | int ret;
|
129 | 45aba42f | Kevin Wolf | |
130 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, (void**) l2_table);
|
131 | 45aba42f | Kevin Wolf | |
132 | 29c1a730 | Kevin Wolf | return ret;
|
133 | 45aba42f | Kevin Wolf | } |
134 | 45aba42f | Kevin Wolf | |
135 | 45aba42f | Kevin Wolf | /*
|
136 | 6583e3c7 | Kevin Wolf | * Writes one sector of the L1 table to the disk (can't update single entries
|
137 | 6583e3c7 | Kevin Wolf | * and we really don't want bdrv_pread to perform a read-modify-write)
|
138 | 6583e3c7 | Kevin Wolf | */
|
139 | 6583e3c7 | Kevin Wolf | #define L1_ENTRIES_PER_SECTOR (512 / 8) |
140 | 66f82cee | Kevin Wolf | static int write_l1_entry(BlockDriverState *bs, int l1_index) |
141 | 6583e3c7 | Kevin Wolf | { |
142 | 66f82cee | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
143 | 6583e3c7 | Kevin Wolf | uint64_t buf[L1_ENTRIES_PER_SECTOR]; |
144 | 6583e3c7 | Kevin Wolf | int l1_start_index;
|
145 | f7defcb6 | Kevin Wolf | int i, ret;
|
146 | 6583e3c7 | Kevin Wolf | |
147 | 6583e3c7 | Kevin Wolf | l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
|
148 | 6583e3c7 | Kevin Wolf | for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) { |
149 | 6583e3c7 | Kevin Wolf | buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]); |
150 | 6583e3c7 | Kevin Wolf | } |
151 | 6583e3c7 | Kevin Wolf | |
152 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); |
153 | 8b3b7206 | Kevin Wolf | ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
|
154 | f7defcb6 | Kevin Wolf | buf, sizeof(buf));
|
155 | f7defcb6 | Kevin Wolf | if (ret < 0) { |
156 | f7defcb6 | Kevin Wolf | return ret;
|
157 | 6583e3c7 | Kevin Wolf | } |
158 | 6583e3c7 | Kevin Wolf | |
159 | 6583e3c7 | Kevin Wolf | return 0; |
160 | 6583e3c7 | Kevin Wolf | } |
161 | 6583e3c7 | Kevin Wolf | |
162 | 6583e3c7 | Kevin Wolf | /*
|
163 | 45aba42f | Kevin Wolf | * l2_allocate
|
164 | 45aba42f | Kevin Wolf | *
|
165 | 45aba42f | Kevin Wolf | * Allocate a new l2 entry in the file. If l1_index points to an already
|
166 | 45aba42f | Kevin Wolf | * used entry in the L2 table (i.e. we are doing a copy on write for the L2
|
167 | 45aba42f | Kevin Wolf | * table) copy the contents of the old L2 table into the newly allocated one.
|
168 | 45aba42f | Kevin Wolf | * Otherwise the new table is initialized with zeros.
|
169 | 45aba42f | Kevin Wolf | *
|
170 | 45aba42f | Kevin Wolf | */
|
171 | 45aba42f | Kevin Wolf | |
172 | c46e1167 | Kevin Wolf | static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table) |
173 | 45aba42f | Kevin Wolf | { |
174 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
175 | 6583e3c7 | Kevin Wolf | uint64_t old_l2_offset; |
176 | f4f0d391 | Kevin Wolf | uint64_t *l2_table; |
177 | f4f0d391 | Kevin Wolf | int64_t l2_offset; |
178 | c46e1167 | Kevin Wolf | int ret;
|
179 | 45aba42f | Kevin Wolf | |
180 | 45aba42f | Kevin Wolf | old_l2_offset = s->l1_table[l1_index]; |
181 | 45aba42f | Kevin Wolf | |
182 | 3cce16f4 | Kevin Wolf | trace_qcow2_l2_allocate(bs, l1_index); |
183 | 3cce16f4 | Kevin Wolf | |
184 | 45aba42f | Kevin Wolf | /* allocate a new l2 entry */
|
185 | 45aba42f | Kevin Wolf | |
186 | ed6ccf0f | Kevin Wolf | l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
|
187 | 5d757b56 | Kevin Wolf | if (l2_offset < 0) { |
188 | c46e1167 | Kevin Wolf | return l2_offset;
|
189 | 5d757b56 | Kevin Wolf | } |
190 | 29c1a730 | Kevin Wolf | |
191 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_flush(bs, s->refcount_block_cache); |
192 | 29c1a730 | Kevin Wolf | if (ret < 0) { |
193 | 29c1a730 | Kevin Wolf | goto fail;
|
194 | 29c1a730 | Kevin Wolf | } |
195 | 45aba42f | Kevin Wolf | |
196 | 45aba42f | Kevin Wolf | /* allocate a new entry in the l2 cache */
|
197 | 45aba42f | Kevin Wolf | |
198 | 3cce16f4 | Kevin Wolf | trace_qcow2_l2_allocate_get_empty(bs, l1_index); |
199 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
|
200 | 29c1a730 | Kevin Wolf | if (ret < 0) { |
201 | 29c1a730 | Kevin Wolf | return ret;
|
202 | 29c1a730 | Kevin Wolf | } |
203 | 29c1a730 | Kevin Wolf | |
204 | 29c1a730 | Kevin Wolf | l2_table = *table; |
205 | 45aba42f | Kevin Wolf | |
206 | 8e37f681 | Kevin Wolf | if ((old_l2_offset & L1E_OFFSET_MASK) == 0) { |
207 | 45aba42f | Kevin Wolf | /* if there was no old l2 table, clear the new table */
|
208 | 45aba42f | Kevin Wolf | memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); |
209 | 45aba42f | Kevin Wolf | } else {
|
210 | 29c1a730 | Kevin Wolf | uint64_t* old_table; |
211 | 29c1a730 | Kevin Wolf | |
212 | 45aba42f | Kevin Wolf | /* if there was an old l2 table, read it from the disk */
|
213 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ); |
214 | 8e37f681 | Kevin Wolf | ret = qcow2_cache_get(bs, s->l2_table_cache, |
215 | 8e37f681 | Kevin Wolf | old_l2_offset & L1E_OFFSET_MASK, |
216 | 29c1a730 | Kevin Wolf | (void**) &old_table);
|
217 | 29c1a730 | Kevin Wolf | if (ret < 0) { |
218 | 29c1a730 | Kevin Wolf | goto fail;
|
219 | 29c1a730 | Kevin Wolf | } |
220 | 29c1a730 | Kevin Wolf | |
221 | 29c1a730 | Kevin Wolf | memcpy(l2_table, old_table, s->cluster_size); |
222 | 29c1a730 | Kevin Wolf | |
223 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &old_table);
|
224 | c46e1167 | Kevin Wolf | if (ret < 0) { |
225 | 175e1152 | Kevin Wolf | goto fail;
|
226 | c46e1167 | Kevin Wolf | } |
227 | 45aba42f | Kevin Wolf | } |
228 | 29c1a730 | Kevin Wolf | |
229 | 45aba42f | Kevin Wolf | /* write the l2 table to the file */
|
230 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE); |
231 | 29c1a730 | Kevin Wolf | |
232 | 3cce16f4 | Kevin Wolf | trace_qcow2_l2_allocate_write_l2(bs, l1_index); |
233 | 29c1a730 | Kevin Wolf | qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); |
234 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_flush(bs, s->l2_table_cache); |
235 | c46e1167 | Kevin Wolf | if (ret < 0) { |
236 | 175e1152 | Kevin Wolf | goto fail;
|
237 | 175e1152 | Kevin Wolf | } |
238 | 175e1152 | Kevin Wolf | |
239 | 175e1152 | Kevin Wolf | /* update the L1 entry */
|
240 | 3cce16f4 | Kevin Wolf | trace_qcow2_l2_allocate_write_l1(bs, l1_index); |
241 | 175e1152 | Kevin Wolf | s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED; |
242 | 175e1152 | Kevin Wolf | ret = write_l1_entry(bs, l1_index); |
243 | 175e1152 | Kevin Wolf | if (ret < 0) { |
244 | 175e1152 | Kevin Wolf | goto fail;
|
245 | c46e1167 | Kevin Wolf | } |
246 | 45aba42f | Kevin Wolf | |
247 | c46e1167 | Kevin Wolf | *table = l2_table; |
248 | 3cce16f4 | Kevin Wolf | trace_qcow2_l2_allocate_done(bs, l1_index, 0);
|
249 | c46e1167 | Kevin Wolf | return 0; |
250 | 175e1152 | Kevin Wolf | |
251 | 175e1152 | Kevin Wolf | fail:
|
252 | 3cce16f4 | Kevin Wolf | trace_qcow2_l2_allocate_done(bs, l1_index, ret); |
253 | 29c1a730 | Kevin Wolf | qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
|
254 | 68dba0bf | Kevin Wolf | s->l1_table[l1_index] = old_l2_offset; |
255 | 175e1152 | Kevin Wolf | return ret;
|
256 | 45aba42f | Kevin Wolf | } |
257 | 45aba42f | Kevin Wolf | |
258 | 2bfcc4a0 | Kevin Wolf | /*
|
259 | 2bfcc4a0 | Kevin Wolf | * Checks how many clusters in a given L2 table are contiguous in the image
|
260 | 2bfcc4a0 | Kevin Wolf | * file. As soon as one of the flags in the bitmask stop_flags changes compared
|
261 | 2bfcc4a0 | Kevin Wolf | * to the first cluster, the search is stopped and the cluster is not counted
|
262 | 2bfcc4a0 | Kevin Wolf | * as contiguous. (This allows it, for example, to stop at the first compressed
|
263 | 2bfcc4a0 | Kevin Wolf | * cluster which may require a different handling)
|
264 | 2bfcc4a0 | Kevin Wolf | */
|
265 | 45aba42f | Kevin Wolf | static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size, |
266 | 2bfcc4a0 | Kevin Wolf | uint64_t *l2_table, uint64_t start, uint64_t stop_flags) |
267 | 45aba42f | Kevin Wolf | { |
268 | 45aba42f | Kevin Wolf | int i;
|
269 | 2bfcc4a0 | Kevin Wolf | uint64_t mask = stop_flags | L2E_OFFSET_MASK; |
270 | 2bfcc4a0 | Kevin Wolf | uint64_t offset = be64_to_cpu(l2_table[0]) & mask;
|
271 | 45aba42f | Kevin Wolf | |
272 | 45aba42f | Kevin Wolf | if (!offset)
|
273 | 45aba42f | Kevin Wolf | return 0; |
274 | 45aba42f | Kevin Wolf | |
275 | 2bfcc4a0 | Kevin Wolf | for (i = start; i < start + nb_clusters; i++) {
|
276 | 2bfcc4a0 | Kevin Wolf | uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask; |
277 | 2bfcc4a0 | Kevin Wolf | if (offset + (uint64_t) i * cluster_size != l2_entry) {
|
278 | 45aba42f | Kevin Wolf | break;
|
279 | 2bfcc4a0 | Kevin Wolf | } |
280 | 2bfcc4a0 | Kevin Wolf | } |
281 | 45aba42f | Kevin Wolf | |
282 | 45aba42f | Kevin Wolf | return (i - start);
|
283 | 45aba42f | Kevin Wolf | } |
284 | 45aba42f | Kevin Wolf | |
285 | 45aba42f | Kevin Wolf | static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table) |
286 | 45aba42f | Kevin Wolf | { |
287 | 2bfcc4a0 | Kevin Wolf | int i;
|
288 | 2bfcc4a0 | Kevin Wolf | |
289 | 2bfcc4a0 | Kevin Wolf | for (i = 0; i < nb_clusters; i++) { |
290 | 2bfcc4a0 | Kevin Wolf | int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i]));
|
291 | 45aba42f | Kevin Wolf | |
292 | 2bfcc4a0 | Kevin Wolf | if (type != QCOW2_CLUSTER_UNALLOCATED) {
|
293 | 2bfcc4a0 | Kevin Wolf | break;
|
294 | 2bfcc4a0 | Kevin Wolf | } |
295 | 2bfcc4a0 | Kevin Wolf | } |
296 | 45aba42f | Kevin Wolf | |
297 | 45aba42f | Kevin Wolf | return i;
|
298 | 45aba42f | Kevin Wolf | } |
299 | 45aba42f | Kevin Wolf | |
300 | 45aba42f | Kevin Wolf | /* The crypt function is compatible with the linux cryptoloop
|
301 | 45aba42f | Kevin Wolf | algorithm for < 4 GB images. NOTE: out_buf == in_buf is
|
302 | 45aba42f | Kevin Wolf | supported */
|
303 | ed6ccf0f | Kevin Wolf | void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
|
304 | ed6ccf0f | Kevin Wolf | uint8_t *out_buf, const uint8_t *in_buf,
|
305 | ed6ccf0f | Kevin Wolf | int nb_sectors, int enc, |
306 | ed6ccf0f | Kevin Wolf | const AES_KEY *key)
|
307 | 45aba42f | Kevin Wolf | { |
308 | 45aba42f | Kevin Wolf | union {
|
309 | 45aba42f | Kevin Wolf | uint64_t ll[2];
|
310 | 45aba42f | Kevin Wolf | uint8_t b[16];
|
311 | 45aba42f | Kevin Wolf | } ivec; |
312 | 45aba42f | Kevin Wolf | int i;
|
313 | 45aba42f | Kevin Wolf | |
314 | 45aba42f | Kevin Wolf | for(i = 0; i < nb_sectors; i++) { |
315 | 45aba42f | Kevin Wolf | ivec.ll[0] = cpu_to_le64(sector_num);
|
316 | 45aba42f | Kevin Wolf | ivec.ll[1] = 0; |
317 | 45aba42f | Kevin Wolf | AES_cbc_encrypt(in_buf, out_buf, 512, key,
|
318 | 45aba42f | Kevin Wolf | ivec.b, enc); |
319 | 45aba42f | Kevin Wolf | sector_num++; |
320 | 45aba42f | Kevin Wolf | in_buf += 512;
|
321 | 45aba42f | Kevin Wolf | out_buf += 512;
|
322 | 45aba42f | Kevin Wolf | } |
323 | 45aba42f | Kevin Wolf | } |
324 | 45aba42f | Kevin Wolf | |
325 | aef4acb6 | Stefan Hajnoczi | static int coroutine_fn copy_sectors(BlockDriverState *bs, |
326 | aef4acb6 | Stefan Hajnoczi | uint64_t start_sect, |
327 | aef4acb6 | Stefan Hajnoczi | uint64_t cluster_offset, |
328 | aef4acb6 | Stefan Hajnoczi | int n_start, int n_end) |
329 | 45aba42f | Kevin Wolf | { |
330 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
331 | aef4acb6 | Stefan Hajnoczi | QEMUIOVector qiov; |
332 | aef4acb6 | Stefan Hajnoczi | struct iovec iov;
|
333 | 45aba42f | Kevin Wolf | int n, ret;
|
334 | 1b9f1491 | Kevin Wolf | |
335 | 1b9f1491 | Kevin Wolf | /*
|
336 | 1b9f1491 | Kevin Wolf | * If this is the last cluster and it is only partially used, we must only
|
337 | 1b9f1491 | Kevin Wolf | * copy until the end of the image, or bdrv_check_request will fail for the
|
338 | 1b9f1491 | Kevin Wolf | * bdrv_read/write calls below.
|
339 | 1b9f1491 | Kevin Wolf | */
|
340 | 1b9f1491 | Kevin Wolf | if (start_sect + n_end > bs->total_sectors) {
|
341 | 1b9f1491 | Kevin Wolf | n_end = bs->total_sectors - start_sect; |
342 | 1b9f1491 | Kevin Wolf | } |
343 | 45aba42f | Kevin Wolf | |
344 | 45aba42f | Kevin Wolf | n = n_end - n_start; |
345 | 1b9f1491 | Kevin Wolf | if (n <= 0) { |
346 | 45aba42f | Kevin Wolf | return 0; |
347 | 1b9f1491 | Kevin Wolf | } |
348 | 1b9f1491 | Kevin Wolf | |
349 | aef4acb6 | Stefan Hajnoczi | iov.iov_len = n * BDRV_SECTOR_SIZE; |
350 | aef4acb6 | Stefan Hajnoczi | iov.iov_base = qemu_blockalign(bs, iov.iov_len); |
351 | aef4acb6 | Stefan Hajnoczi | |
352 | aef4acb6 | Stefan Hajnoczi | qemu_iovec_init_external(&qiov, &iov, 1);
|
353 | 1b9f1491 | Kevin Wolf | |
354 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_COW_READ); |
355 | aef4acb6 | Stefan Hajnoczi | |
356 | aef4acb6 | Stefan Hajnoczi | /* Call .bdrv_co_readv() directly instead of using the public block-layer
|
357 | aef4acb6 | Stefan Hajnoczi | * interface. This avoids double I/O throttling and request tracking,
|
358 | aef4acb6 | Stefan Hajnoczi | * which can lead to deadlock when block layer copy-on-read is enabled.
|
359 | aef4acb6 | Stefan Hajnoczi | */
|
360 | aef4acb6 | Stefan Hajnoczi | ret = bs->drv->bdrv_co_readv(bs, start_sect + n_start, n, &qiov); |
361 | 1b9f1491 | Kevin Wolf | if (ret < 0) { |
362 | 1b9f1491 | Kevin Wolf | goto out;
|
363 | 1b9f1491 | Kevin Wolf | } |
364 | 1b9f1491 | Kevin Wolf | |
365 | 45aba42f | Kevin Wolf | if (s->crypt_method) {
|
366 | ed6ccf0f | Kevin Wolf | qcow2_encrypt_sectors(s, start_sect + n_start, |
367 | aef4acb6 | Stefan Hajnoczi | iov.iov_base, iov.iov_base, n, 1,
|
368 | 45aba42f | Kevin Wolf | &s->aes_encrypt_key); |
369 | 45aba42f | Kevin Wolf | } |
370 | 1b9f1491 | Kevin Wolf | |
371 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE); |
372 | aef4acb6 | Stefan Hajnoczi | ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);
|
373 | 1b9f1491 | Kevin Wolf | if (ret < 0) { |
374 | 1b9f1491 | Kevin Wolf | goto out;
|
375 | 1b9f1491 | Kevin Wolf | } |
376 | 1b9f1491 | Kevin Wolf | |
377 | 1b9f1491 | Kevin Wolf | ret = 0;
|
378 | 1b9f1491 | Kevin Wolf | out:
|
379 | aef4acb6 | Stefan Hajnoczi | qemu_vfree(iov.iov_base); |
380 | 1b9f1491 | Kevin Wolf | return ret;
|
381 | 45aba42f | Kevin Wolf | } |
382 | 45aba42f | Kevin Wolf | |
383 | 45aba42f | Kevin Wolf | |
384 | 45aba42f | Kevin Wolf | /*
|
385 | 45aba42f | Kevin Wolf | * get_cluster_offset
|
386 | 45aba42f | Kevin Wolf | *
|
387 | 1c46efaa | Kevin Wolf | * For a given offset of the disk image, find the cluster offset in
|
388 | 1c46efaa | Kevin Wolf | * qcow2 file. The offset is stored in *cluster_offset.
|
389 | 45aba42f | Kevin Wolf | *
|
390 | d57237f2 | Devin Nakamura | * on entry, *num is the number of contiguous sectors we'd like to
|
391 | 45aba42f | Kevin Wolf | * access following offset.
|
392 | 45aba42f | Kevin Wolf | *
|
393 | d57237f2 | Devin Nakamura | * on exit, *num is the number of contiguous sectors we can read.
|
394 | 45aba42f | Kevin Wolf | *
|
395 | 68d000a3 | Kevin Wolf | * Returns the cluster type (QCOW2_CLUSTER_*) on success, -errno in error
|
396 | 68d000a3 | Kevin Wolf | * cases.
|
397 | 45aba42f | Kevin Wolf | */
|
398 | 1c46efaa | Kevin Wolf | int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
399 | 1c46efaa | Kevin Wolf | int *num, uint64_t *cluster_offset)
|
400 | 45aba42f | Kevin Wolf | { |
401 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
402 | 2cf7cfa1 | Kevin Wolf | unsigned int l2_index; |
403 | 2cf7cfa1 | Kevin Wolf | uint64_t l1_index, l2_offset, *l2_table; |
404 | 45aba42f | Kevin Wolf | int l1_bits, c;
|
405 | 80ee15a6 | Kevin Wolf | unsigned int index_in_cluster, nb_clusters; |
406 | 80ee15a6 | Kevin Wolf | uint64_t nb_available, nb_needed; |
407 | 55c17e98 | Kevin Wolf | int ret;
|
408 | 45aba42f | Kevin Wolf | |
409 | 45aba42f | Kevin Wolf | index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1); |
410 | 45aba42f | Kevin Wolf | nb_needed = *num + index_in_cluster; |
411 | 45aba42f | Kevin Wolf | |
412 | 45aba42f | Kevin Wolf | l1_bits = s->l2_bits + s->cluster_bits; |
413 | 45aba42f | Kevin Wolf | |
414 | 45aba42f | Kevin Wolf | /* compute how many bytes there are between the offset and
|
415 | 45aba42f | Kevin Wolf | * the end of the l1 entry
|
416 | 45aba42f | Kevin Wolf | */
|
417 | 45aba42f | Kevin Wolf | |
418 | 80ee15a6 | Kevin Wolf | nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1)); |
419 | 45aba42f | Kevin Wolf | |
420 | 45aba42f | Kevin Wolf | /* compute the number of available sectors */
|
421 | 45aba42f | Kevin Wolf | |
422 | 45aba42f | Kevin Wolf | nb_available = (nb_available >> 9) + index_in_cluster;
|
423 | 45aba42f | Kevin Wolf | |
424 | 45aba42f | Kevin Wolf | if (nb_needed > nb_available) {
|
425 | 45aba42f | Kevin Wolf | nb_needed = nb_available; |
426 | 45aba42f | Kevin Wolf | } |
427 | 45aba42f | Kevin Wolf | |
428 | 1c46efaa | Kevin Wolf | *cluster_offset = 0;
|
429 | 45aba42f | Kevin Wolf | |
430 | 45aba42f | Kevin Wolf | /* seek the the l2 offset in the l1 table */
|
431 | 45aba42f | Kevin Wolf | |
432 | 45aba42f | Kevin Wolf | l1_index = offset >> l1_bits; |
433 | 68d000a3 | Kevin Wolf | if (l1_index >= s->l1_size) {
|
434 | 68d000a3 | Kevin Wolf | ret = QCOW2_CLUSTER_UNALLOCATED; |
435 | 45aba42f | Kevin Wolf | goto out;
|
436 | 68d000a3 | Kevin Wolf | } |
437 | 45aba42f | Kevin Wolf | |
438 | 68d000a3 | Kevin Wolf | l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK; |
439 | 68d000a3 | Kevin Wolf | if (!l2_offset) {
|
440 | 68d000a3 | Kevin Wolf | ret = QCOW2_CLUSTER_UNALLOCATED; |
441 | 45aba42f | Kevin Wolf | goto out;
|
442 | 68d000a3 | Kevin Wolf | } |
443 | 45aba42f | Kevin Wolf | |
444 | 45aba42f | Kevin Wolf | /* load the l2 table in memory */
|
445 | 45aba42f | Kevin Wolf | |
446 | 55c17e98 | Kevin Wolf | ret = l2_load(bs, l2_offset, &l2_table); |
447 | 55c17e98 | Kevin Wolf | if (ret < 0) { |
448 | 55c17e98 | Kevin Wolf | return ret;
|
449 | 1c46efaa | Kevin Wolf | } |
450 | 45aba42f | Kevin Wolf | |
451 | 45aba42f | Kevin Wolf | /* find the cluster offset for the given disk offset */
|
452 | 45aba42f | Kevin Wolf | |
453 | 45aba42f | Kevin Wolf | l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
|
454 | 1c46efaa | Kevin Wolf | *cluster_offset = be64_to_cpu(l2_table[l2_index]); |
455 | 45aba42f | Kevin Wolf | nb_clusters = size_to_clusters(s, nb_needed << 9);
|
456 | 45aba42f | Kevin Wolf | |
457 | 68d000a3 | Kevin Wolf | ret = qcow2_get_cluster_type(*cluster_offset); |
458 | 68d000a3 | Kevin Wolf | switch (ret) {
|
459 | 68d000a3 | Kevin Wolf | case QCOW2_CLUSTER_COMPRESSED:
|
460 | 68d000a3 | Kevin Wolf | /* Compressed clusters can only be processed one by one */
|
461 | 68d000a3 | Kevin Wolf | c = 1;
|
462 | 68d000a3 | Kevin Wolf | *cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK; |
463 | 68d000a3 | Kevin Wolf | break;
|
464 | 6377af48 | Kevin Wolf | case QCOW2_CLUSTER_ZERO:
|
465 | 381b487d | Paolo Bonzini | if (s->qcow_version < 3) { |
466 | 381b487d | Paolo Bonzini | return -EIO;
|
467 | 381b487d | Paolo Bonzini | } |
468 | 6377af48 | Kevin Wolf | c = count_contiguous_clusters(nb_clusters, s->cluster_size, |
469 | 6377af48 | Kevin Wolf | &l2_table[l2_index], 0,
|
470 | 6377af48 | Kevin Wolf | QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO); |
471 | 6377af48 | Kevin Wolf | *cluster_offset = 0;
|
472 | 6377af48 | Kevin Wolf | break;
|
473 | 68d000a3 | Kevin Wolf | case QCOW2_CLUSTER_UNALLOCATED:
|
474 | 45aba42f | Kevin Wolf | /* how many empty clusters ? */
|
475 | 45aba42f | Kevin Wolf | c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]); |
476 | 68d000a3 | Kevin Wolf | *cluster_offset = 0;
|
477 | 68d000a3 | Kevin Wolf | break;
|
478 | 68d000a3 | Kevin Wolf | case QCOW2_CLUSTER_NORMAL:
|
479 | 45aba42f | Kevin Wolf | /* how many allocated clusters ? */
|
480 | 45aba42f | Kevin Wolf | c = count_contiguous_clusters(nb_clusters, s->cluster_size, |
481 | 6377af48 | Kevin Wolf | &l2_table[l2_index], 0,
|
482 | 6377af48 | Kevin Wolf | QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO); |
483 | 68d000a3 | Kevin Wolf | *cluster_offset &= L2E_OFFSET_MASK; |
484 | 68d000a3 | Kevin Wolf | break;
|
485 | 1417d7e4 | Kevin Wolf | default:
|
486 | 1417d7e4 | Kevin Wolf | abort(); |
487 | 45aba42f | Kevin Wolf | } |
488 | 45aba42f | Kevin Wolf | |
489 | 29c1a730 | Kevin Wolf | qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
490 | 29c1a730 | Kevin Wolf | |
491 | 68d000a3 | Kevin Wolf | nb_available = (c * s->cluster_sectors); |
492 | 68d000a3 | Kevin Wolf | |
493 | 45aba42f | Kevin Wolf | out:
|
494 | 45aba42f | Kevin Wolf | if (nb_available > nb_needed)
|
495 | 45aba42f | Kevin Wolf | nb_available = nb_needed; |
496 | 45aba42f | Kevin Wolf | |
497 | 45aba42f | Kevin Wolf | *num = nb_available - index_in_cluster; |
498 | 45aba42f | Kevin Wolf | |
499 | 68d000a3 | Kevin Wolf | return ret;
|
500 | 45aba42f | Kevin Wolf | } |
501 | 45aba42f | Kevin Wolf | |
502 | 45aba42f | Kevin Wolf | /*
|
503 | 45aba42f | Kevin Wolf | * get_cluster_table
|
504 | 45aba42f | Kevin Wolf | *
|
505 | 45aba42f | Kevin Wolf | * for a given disk offset, load (and allocate if needed)
|
506 | 45aba42f | Kevin Wolf | * the l2 table.
|
507 | 45aba42f | Kevin Wolf | *
|
508 | 45aba42f | Kevin Wolf | * the l2 table offset in the qcow2 file and the cluster index
|
509 | 45aba42f | Kevin Wolf | * in the l2 table are given to the caller.
|
510 | 45aba42f | Kevin Wolf | *
|
511 | 1e3e8f1a | Kevin Wolf | * Returns 0 on success, -errno in failure case
|
512 | 45aba42f | Kevin Wolf | */
|
513 | 45aba42f | Kevin Wolf | static int get_cluster_table(BlockDriverState *bs, uint64_t offset, |
514 | 45aba42f | Kevin Wolf | uint64_t **new_l2_table, |
515 | 45aba42f | Kevin Wolf | int *new_l2_index)
|
516 | 45aba42f | Kevin Wolf | { |
517 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
518 | 2cf7cfa1 | Kevin Wolf | unsigned int l2_index; |
519 | 2cf7cfa1 | Kevin Wolf | uint64_t l1_index, l2_offset; |
520 | c46e1167 | Kevin Wolf | uint64_t *l2_table = NULL;
|
521 | 80ee15a6 | Kevin Wolf | int ret;
|
522 | 45aba42f | Kevin Wolf | |
523 | 45aba42f | Kevin Wolf | /* seek the the l2 offset in the l1 table */
|
524 | 45aba42f | Kevin Wolf | |
525 | 45aba42f | Kevin Wolf | l1_index = offset >> (s->l2_bits + s->cluster_bits); |
526 | 45aba42f | Kevin Wolf | if (l1_index >= s->l1_size) {
|
527 | 72893756 | Stefan Hajnoczi | ret = qcow2_grow_l1_table(bs, l1_index + 1, false); |
528 | 1e3e8f1a | Kevin Wolf | if (ret < 0) { |
529 | 1e3e8f1a | Kevin Wolf | return ret;
|
530 | 1e3e8f1a | Kevin Wolf | } |
531 | 45aba42f | Kevin Wolf | } |
532 | 8e37f681 | Kevin Wolf | |
533 | 2cf7cfa1 | Kevin Wolf | assert(l1_index < s->l1_size); |
534 | 8e37f681 | Kevin Wolf | l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK; |
535 | 45aba42f | Kevin Wolf | |
536 | 45aba42f | Kevin Wolf | /* seek the l2 table of the given l2 offset */
|
537 | 45aba42f | Kevin Wolf | |
538 | 8e37f681 | Kevin Wolf | if (s->l1_table[l1_index] & QCOW_OFLAG_COPIED) {
|
539 | 45aba42f | Kevin Wolf | /* load the l2 table in memory */
|
540 | 55c17e98 | Kevin Wolf | ret = l2_load(bs, l2_offset, &l2_table); |
541 | 55c17e98 | Kevin Wolf | if (ret < 0) { |
542 | 55c17e98 | Kevin Wolf | return ret;
|
543 | 1e3e8f1a | Kevin Wolf | } |
544 | 45aba42f | Kevin Wolf | } else {
|
545 | 16fde5f2 | Kevin Wolf | /* First allocate a new L2 table (and do COW if needed) */
|
546 | c46e1167 | Kevin Wolf | ret = l2_allocate(bs, l1_index, &l2_table); |
547 | c46e1167 | Kevin Wolf | if (ret < 0) { |
548 | c46e1167 | Kevin Wolf | return ret;
|
549 | 1e3e8f1a | Kevin Wolf | } |
550 | 16fde5f2 | Kevin Wolf | |
551 | 16fde5f2 | Kevin Wolf | /* Then decrease the refcount of the old table */
|
552 | 16fde5f2 | Kevin Wolf | if (l2_offset) {
|
553 | 6cfcb9b8 | Kevin Wolf | qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),
|
554 | 6cfcb9b8 | Kevin Wolf | QCOW2_DISCARD_OTHER); |
555 | 16fde5f2 | Kevin Wolf | } |
556 | 45aba42f | Kevin Wolf | } |
557 | 45aba42f | Kevin Wolf | |
558 | 45aba42f | Kevin Wolf | /* find the cluster offset for the given disk offset */
|
559 | 45aba42f | Kevin Wolf | |
560 | 45aba42f | Kevin Wolf | l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
|
561 | 45aba42f | Kevin Wolf | |
562 | 45aba42f | Kevin Wolf | *new_l2_table = l2_table; |
563 | 45aba42f | Kevin Wolf | *new_l2_index = l2_index; |
564 | 45aba42f | Kevin Wolf | |
565 | 1e3e8f1a | Kevin Wolf | return 0; |
566 | 45aba42f | Kevin Wolf | } |
567 | 45aba42f | Kevin Wolf | |
568 | 45aba42f | Kevin Wolf | /*
|
569 | 45aba42f | Kevin Wolf | * alloc_compressed_cluster_offset
|
570 | 45aba42f | Kevin Wolf | *
|
571 | 45aba42f | Kevin Wolf | * For a given offset of the disk image, return cluster offset in
|
572 | 45aba42f | Kevin Wolf | * qcow2 file.
|
573 | 45aba42f | Kevin Wolf | *
|
574 | 45aba42f | Kevin Wolf | * If the offset is not found, allocate a new compressed cluster.
|
575 | 45aba42f | Kevin Wolf | *
|
576 | 45aba42f | Kevin Wolf | * Return the cluster offset if successful,
|
577 | 45aba42f | Kevin Wolf | * Return 0, otherwise.
|
578 | 45aba42f | Kevin Wolf | *
|
579 | 45aba42f | Kevin Wolf | */
|
580 | 45aba42f | Kevin Wolf | |
581 | ed6ccf0f | Kevin Wolf | uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, |
582 | ed6ccf0f | Kevin Wolf | uint64_t offset, |
583 | ed6ccf0f | Kevin Wolf | int compressed_size)
|
584 | 45aba42f | Kevin Wolf | { |
585 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
586 | 45aba42f | Kevin Wolf | int l2_index, ret;
|
587 | 3948d1d4 | Kevin Wolf | uint64_t *l2_table; |
588 | f4f0d391 | Kevin Wolf | int64_t cluster_offset; |
589 | 45aba42f | Kevin Wolf | int nb_csectors;
|
590 | 45aba42f | Kevin Wolf | |
591 | 3948d1d4 | Kevin Wolf | ret = get_cluster_table(bs, offset, &l2_table, &l2_index); |
592 | 1e3e8f1a | Kevin Wolf | if (ret < 0) { |
593 | 45aba42f | Kevin Wolf | return 0; |
594 | 1e3e8f1a | Kevin Wolf | } |
595 | 45aba42f | Kevin Wolf | |
596 | b0b6862e | Kevin Wolf | /* Compression can't overwrite anything. Fail if the cluster was already
|
597 | b0b6862e | Kevin Wolf | * allocated. */
|
598 | 45aba42f | Kevin Wolf | cluster_offset = be64_to_cpu(l2_table[l2_index]); |
599 | b0b6862e | Kevin Wolf | if (cluster_offset & L2E_OFFSET_MASK) {
|
600 | 8f1efd00 | Kevin Wolf | qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
601 | 8f1efd00 | Kevin Wolf | return 0; |
602 | 8f1efd00 | Kevin Wolf | } |
603 | 45aba42f | Kevin Wolf | |
604 | ed6ccf0f | Kevin Wolf | cluster_offset = qcow2_alloc_bytes(bs, compressed_size); |
605 | 5d757b56 | Kevin Wolf | if (cluster_offset < 0) { |
606 | 29c1a730 | Kevin Wolf | qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
607 | 5d757b56 | Kevin Wolf | return 0; |
608 | 5d757b56 | Kevin Wolf | } |
609 | 5d757b56 | Kevin Wolf | |
610 | 45aba42f | Kevin Wolf | nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) - |
611 | 45aba42f | Kevin Wolf | (cluster_offset >> 9);
|
612 | 45aba42f | Kevin Wolf | |
613 | 45aba42f | Kevin Wolf | cluster_offset |= QCOW_OFLAG_COMPRESSED | |
614 | 45aba42f | Kevin Wolf | ((uint64_t)nb_csectors << s->csize_shift); |
615 | 45aba42f | Kevin Wolf | |
616 | 45aba42f | Kevin Wolf | /* update L2 table */
|
617 | 45aba42f | Kevin Wolf | |
618 | 45aba42f | Kevin Wolf | /* compressed clusters never have the copied flag */
|
619 | 45aba42f | Kevin Wolf | |
620 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED); |
621 | 29c1a730 | Kevin Wolf | qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); |
622 | 45aba42f | Kevin Wolf | l2_table[l2_index] = cpu_to_be64(cluster_offset); |
623 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
624 | 79a31189 | Kevin Wolf | if (ret < 0) { |
625 | 29c1a730 | Kevin Wolf | return 0; |
626 | 4c1612d9 | Kevin Wolf | } |
627 | 4c1612d9 | Kevin Wolf | |
628 | 29c1a730 | Kevin Wolf | return cluster_offset;
|
629 | 4c1612d9 | Kevin Wolf | } |
630 | 4c1612d9 | Kevin Wolf | |
631 | 593fb83c | Kevin Wolf | static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r) |
632 | 593fb83c | Kevin Wolf | { |
633 | 593fb83c | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
634 | 593fb83c | Kevin Wolf | int ret;
|
635 | 593fb83c | Kevin Wolf | |
636 | 593fb83c | Kevin Wolf | if (r->nb_sectors == 0) { |
637 | 593fb83c | Kevin Wolf | return 0; |
638 | 593fb83c | Kevin Wolf | } |
639 | 593fb83c | Kevin Wolf | |
640 | 593fb83c | Kevin Wolf | qemu_co_mutex_unlock(&s->lock); |
641 | 593fb83c | Kevin Wolf | ret = copy_sectors(bs, m->offset / BDRV_SECTOR_SIZE, m->alloc_offset, |
642 | 593fb83c | Kevin Wolf | r->offset / BDRV_SECTOR_SIZE, |
643 | 593fb83c | Kevin Wolf | r->offset / BDRV_SECTOR_SIZE + r->nb_sectors); |
644 | 593fb83c | Kevin Wolf | qemu_co_mutex_lock(&s->lock); |
645 | 593fb83c | Kevin Wolf | |
646 | 593fb83c | Kevin Wolf | if (ret < 0) { |
647 | 593fb83c | Kevin Wolf | return ret;
|
648 | 593fb83c | Kevin Wolf | } |
649 | 593fb83c | Kevin Wolf | |
650 | 593fb83c | Kevin Wolf | /*
|
651 | 593fb83c | Kevin Wolf | * Before we update the L2 table to actually point to the new cluster, we
|
652 | 593fb83c | Kevin Wolf | * need to be sure that the refcounts have been increased and COW was
|
653 | 593fb83c | Kevin Wolf | * handled.
|
654 | 593fb83c | Kevin Wolf | */
|
655 | 593fb83c | Kevin Wolf | qcow2_cache_depends_on_flush(s->l2_table_cache); |
656 | 593fb83c | Kevin Wolf | |
657 | 593fb83c | Kevin Wolf | return 0; |
658 | 593fb83c | Kevin Wolf | } |
659 | 593fb83c | Kevin Wolf | |
660 | 148da7ea | Kevin Wolf | int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
|
661 | 45aba42f | Kevin Wolf | { |
662 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
663 | 45aba42f | Kevin Wolf | int i, j = 0, l2_index, ret; |
664 | 593fb83c | Kevin Wolf | uint64_t *old_cluster, *l2_table; |
665 | 250196f1 | Kevin Wolf | uint64_t cluster_offset = m->alloc_offset; |
666 | 45aba42f | Kevin Wolf | |
667 | 3cce16f4 | Kevin Wolf | trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters); |
668 | f50f88b9 | Kevin Wolf | assert(m->nb_clusters > 0);
|
669 | 45aba42f | Kevin Wolf | |
670 | 7267c094 | Anthony Liguori | old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
|
671 | 45aba42f | Kevin Wolf | |
672 | 45aba42f | Kevin Wolf | /* copy content of unmodified sectors */
|
673 | 593fb83c | Kevin Wolf | ret = perform_cow(bs, m, &m->cow_start); |
674 | 593fb83c | Kevin Wolf | if (ret < 0) { |
675 | 593fb83c | Kevin Wolf | goto err;
|
676 | 45aba42f | Kevin Wolf | } |
677 | 45aba42f | Kevin Wolf | |
678 | 593fb83c | Kevin Wolf | ret = perform_cow(bs, m, &m->cow_end); |
679 | 593fb83c | Kevin Wolf | if (ret < 0) { |
680 | 593fb83c | Kevin Wolf | goto err;
|
681 | 29c1a730 | Kevin Wolf | } |
682 | 29c1a730 | Kevin Wolf | |
683 | 593fb83c | Kevin Wolf | /* Update L2 table. */
|
684 | 74c4510a | Kevin Wolf | if (s->use_lazy_refcounts) {
|
685 | 280d3735 | Kevin Wolf | qcow2_mark_dirty(bs); |
686 | 280d3735 | Kevin Wolf | } |
687 | bfe8043e | Stefan Hajnoczi | if (qcow2_need_accurate_refcounts(s)) {
|
688 | bfe8043e | Stefan Hajnoczi | qcow2_cache_set_dependency(bs, s->l2_table_cache, |
689 | bfe8043e | Stefan Hajnoczi | s->refcount_block_cache); |
690 | bfe8043e | Stefan Hajnoczi | } |
691 | 280d3735 | Kevin Wolf | |
692 | 3948d1d4 | Kevin Wolf | ret = get_cluster_table(bs, m->offset, &l2_table, &l2_index); |
693 | 1e3e8f1a | Kevin Wolf | if (ret < 0) { |
694 | 45aba42f | Kevin Wolf | goto err;
|
695 | 1e3e8f1a | Kevin Wolf | } |
696 | 29c1a730 | Kevin Wolf | qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); |
697 | 45aba42f | Kevin Wolf | |
698 | 45aba42f | Kevin Wolf | for (i = 0; i < m->nb_clusters; i++) { |
699 | 45aba42f | Kevin Wolf | /* if two concurrent writes happen to the same unallocated cluster
|
700 | 45aba42f | Kevin Wolf | * each write allocates separate cluster and writes data concurrently.
|
701 | 45aba42f | Kevin Wolf | * The first one to complete updates l2 table with pointer to its
|
702 | 45aba42f | Kevin Wolf | * cluster the second one has to do RMW (which is done above by
|
703 | 45aba42f | Kevin Wolf | * copy_sectors()), update l2 table with its cluster pointer and free
|
704 | 45aba42f | Kevin Wolf | * old cluster. This is what this loop does */
|
705 | 45aba42f | Kevin Wolf | if(l2_table[l2_index + i] != 0) |
706 | 45aba42f | Kevin Wolf | old_cluster[j++] = l2_table[l2_index + i]; |
707 | 45aba42f | Kevin Wolf | |
708 | 45aba42f | Kevin Wolf | l2_table[l2_index + i] = cpu_to_be64((cluster_offset + |
709 | 45aba42f | Kevin Wolf | (i << s->cluster_bits)) | QCOW_OFLAG_COPIED); |
710 | 45aba42f | Kevin Wolf | } |
711 | 45aba42f | Kevin Wolf | |
712 | 9f8e668e | Kevin Wolf | |
713 | 29c1a730 | Kevin Wolf | ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
714 | c835d00f | Kevin Wolf | if (ret < 0) { |
715 | 45aba42f | Kevin Wolf | goto err;
|
716 | 4c1612d9 | Kevin Wolf | } |
717 | 45aba42f | Kevin Wolf | |
718 | 7ec5e6a4 | Kevin Wolf | /*
|
719 | 7ec5e6a4 | Kevin Wolf | * If this was a COW, we need to decrease the refcount of the old cluster.
|
720 | 7ec5e6a4 | Kevin Wolf | * Also flush bs->file to get the right order for L2 and refcount update.
|
721 | 6cfcb9b8 | Kevin Wolf | *
|
722 | 6cfcb9b8 | Kevin Wolf | * Don't discard clusters that reach a refcount of 0 (e.g. compressed
|
723 | 6cfcb9b8 | Kevin Wolf | * clusters), the next write will reuse them anyway.
|
724 | 7ec5e6a4 | Kevin Wolf | */
|
725 | 7ec5e6a4 | Kevin Wolf | if (j != 0) { |
726 | 7ec5e6a4 | Kevin Wolf | for (i = 0; i < j; i++) { |
727 | 6cfcb9b8 | Kevin Wolf | qcow2_free_any_clusters(bs, be64_to_cpu(old_cluster[i]), 1,
|
728 | 6cfcb9b8 | Kevin Wolf | QCOW2_DISCARD_NEVER); |
729 | 7ec5e6a4 | Kevin Wolf | } |
730 | 7ec5e6a4 | Kevin Wolf | } |
731 | 45aba42f | Kevin Wolf | |
732 | 45aba42f | Kevin Wolf | ret = 0;
|
733 | 45aba42f | Kevin Wolf | err:
|
734 | 7267c094 | Anthony Liguori | g_free(old_cluster); |
735 | 45aba42f | Kevin Wolf | return ret;
|
736 | 45aba42f | Kevin Wolf | } |
737 | 45aba42f | Kevin Wolf | |
738 | 45aba42f | Kevin Wolf | /*
|
739 | bf319ece | Kevin Wolf | * Returns the number of contiguous clusters that can be used for an allocating
|
740 | bf319ece | Kevin Wolf | * write, but require COW to be performed (this includes yet unallocated space,
|
741 | bf319ece | Kevin Wolf | * which must copy from the backing file)
|
742 | bf319ece | Kevin Wolf | */
|
743 | bf319ece | Kevin Wolf | static int count_cow_clusters(BDRVQcowState *s, int nb_clusters, |
744 | bf319ece | Kevin Wolf | uint64_t *l2_table, int l2_index)
|
745 | bf319ece | Kevin Wolf | { |
746 | 143550a8 | Kevin Wolf | int i;
|
747 | bf319ece | Kevin Wolf | |
748 | 143550a8 | Kevin Wolf | for (i = 0; i < nb_clusters; i++) { |
749 | 143550a8 | Kevin Wolf | uint64_t l2_entry = be64_to_cpu(l2_table[l2_index + i]); |
750 | 143550a8 | Kevin Wolf | int cluster_type = qcow2_get_cluster_type(l2_entry);
|
751 | 143550a8 | Kevin Wolf | |
752 | 143550a8 | Kevin Wolf | switch(cluster_type) {
|
753 | 143550a8 | Kevin Wolf | case QCOW2_CLUSTER_NORMAL:
|
754 | 143550a8 | Kevin Wolf | if (l2_entry & QCOW_OFLAG_COPIED) {
|
755 | 143550a8 | Kevin Wolf | goto out;
|
756 | 143550a8 | Kevin Wolf | } |
757 | bf319ece | Kevin Wolf | break;
|
758 | 143550a8 | Kevin Wolf | case QCOW2_CLUSTER_UNALLOCATED:
|
759 | 143550a8 | Kevin Wolf | case QCOW2_CLUSTER_COMPRESSED:
|
760 | 6377af48 | Kevin Wolf | case QCOW2_CLUSTER_ZERO:
|
761 | bf319ece | Kevin Wolf | break;
|
762 | 143550a8 | Kevin Wolf | default:
|
763 | 143550a8 | Kevin Wolf | abort(); |
764 | 143550a8 | Kevin Wolf | } |
765 | bf319ece | Kevin Wolf | } |
766 | bf319ece | Kevin Wolf | |
767 | 143550a8 | Kevin Wolf | out:
|
768 | bf319ece | Kevin Wolf | assert(i <= nb_clusters); |
769 | bf319ece | Kevin Wolf | return i;
|
770 | bf319ece | Kevin Wolf | } |
771 | bf319ece | Kevin Wolf | |
772 | bf319ece | Kevin Wolf | /*
|
773 | 226c3c26 | Kevin Wolf | * Check if there already is an AIO write request in flight which allocates
|
774 | 226c3c26 | Kevin Wolf | * the same cluster. In this case we need to wait until the previous
|
775 | 226c3c26 | Kevin Wolf | * request has completed and updated the L2 table accordingly.
|
776 | 65eb2e35 | Kevin Wolf | *
|
777 | 65eb2e35 | Kevin Wolf | * Returns:
|
778 | 65eb2e35 | Kevin Wolf | * 0 if there was no dependency. *cur_bytes indicates the number of
|
779 | 65eb2e35 | Kevin Wolf | * bytes from guest_offset that can be read before the next
|
780 | 65eb2e35 | Kevin Wolf | * dependency must be processed (or the request is complete)
|
781 | 65eb2e35 | Kevin Wolf | *
|
782 | 65eb2e35 | Kevin Wolf | * -EAGAIN if we had to wait for another request, previously gathered
|
783 | 65eb2e35 | Kevin Wolf | * information on cluster allocation may be invalid now. The caller
|
784 | 65eb2e35 | Kevin Wolf | * must start over anyway, so consider *cur_bytes undefined.
|
785 | 250196f1 | Kevin Wolf | */
|
786 | 226c3c26 | Kevin Wolf | static int handle_dependencies(BlockDriverState *bs, uint64_t guest_offset, |
787 | ecdd5333 | Kevin Wolf | uint64_t *cur_bytes, QCowL2Meta **m) |
788 | 250196f1 | Kevin Wolf | { |
789 | 250196f1 | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
790 | 250196f1 | Kevin Wolf | QCowL2Meta *old_alloc; |
791 | 65eb2e35 | Kevin Wolf | uint64_t bytes = *cur_bytes; |
792 | 250196f1 | Kevin Wolf | |
793 | 250196f1 | Kevin Wolf | QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) { |
794 | 250196f1 | Kevin Wolf | |
795 | 65eb2e35 | Kevin Wolf | uint64_t start = guest_offset; |
796 | 65eb2e35 | Kevin Wolf | uint64_t end = start + bytes; |
797 | 65eb2e35 | Kevin Wolf | uint64_t old_start = l2meta_cow_start(old_alloc); |
798 | 65eb2e35 | Kevin Wolf | uint64_t old_end = l2meta_cow_end(old_alloc); |
799 | 250196f1 | Kevin Wolf | |
800 | d9d74f41 | Kevin Wolf | if (end <= old_start || start >= old_end) {
|
801 | 250196f1 | Kevin Wolf | /* No intersection */
|
802 | 250196f1 | Kevin Wolf | } else {
|
803 | 250196f1 | Kevin Wolf | if (start < old_start) {
|
804 | 250196f1 | Kevin Wolf | /* Stop at the start of a running allocation */
|
805 | 65eb2e35 | Kevin Wolf | bytes = old_start - start; |
806 | 250196f1 | Kevin Wolf | } else {
|
807 | 65eb2e35 | Kevin Wolf | bytes = 0;
|
808 | 250196f1 | Kevin Wolf | } |
809 | 250196f1 | Kevin Wolf | |
810 | ecdd5333 | Kevin Wolf | /* Stop if already an l2meta exists. After yielding, it wouldn't
|
811 | ecdd5333 | Kevin Wolf | * be valid any more, so we'd have to clean up the old L2Metas
|
812 | ecdd5333 | Kevin Wolf | * and deal with requests depending on them before starting to
|
813 | ecdd5333 | Kevin Wolf | * gather new ones. Not worth the trouble. */
|
814 | ecdd5333 | Kevin Wolf | if (bytes == 0 && *m) { |
815 | ecdd5333 | Kevin Wolf | *cur_bytes = 0;
|
816 | ecdd5333 | Kevin Wolf | return 0; |
817 | ecdd5333 | Kevin Wolf | } |
818 | ecdd5333 | Kevin Wolf | |
819 | 65eb2e35 | Kevin Wolf | if (bytes == 0) { |
820 | 250196f1 | Kevin Wolf | /* Wait for the dependency to complete. We need to recheck
|
821 | 250196f1 | Kevin Wolf | * the free/allocated clusters when we continue. */
|
822 | 250196f1 | Kevin Wolf | qemu_co_mutex_unlock(&s->lock); |
823 | 250196f1 | Kevin Wolf | qemu_co_queue_wait(&old_alloc->dependent_requests); |
824 | 250196f1 | Kevin Wolf | qemu_co_mutex_lock(&s->lock); |
825 | 250196f1 | Kevin Wolf | return -EAGAIN;
|
826 | 250196f1 | Kevin Wolf | } |
827 | 250196f1 | Kevin Wolf | } |
828 | 250196f1 | Kevin Wolf | } |
829 | 250196f1 | Kevin Wolf | |
830 | 65eb2e35 | Kevin Wolf | /* Make sure that existing clusters and new allocations are only used up to
|
831 | 65eb2e35 | Kevin Wolf | * the next dependency if we shortened the request above */
|
832 | 65eb2e35 | Kevin Wolf | *cur_bytes = bytes; |
833 | 250196f1 | Kevin Wolf | |
834 | 226c3c26 | Kevin Wolf | return 0; |
835 | 226c3c26 | Kevin Wolf | } |
836 | 226c3c26 | Kevin Wolf | |
837 | 226c3c26 | Kevin Wolf | /*
|
838 | 0af729ec | Kevin Wolf | * Checks how many already allocated clusters that don't require a copy on
|
839 | 0af729ec | Kevin Wolf | * write there are at the given guest_offset (up to *bytes). If
|
840 | 0af729ec | Kevin Wolf | * *host_offset is not zero, only physically contiguous clusters beginning at
|
841 | 0af729ec | Kevin Wolf | * this host offset are counted.
|
842 | 0af729ec | Kevin Wolf | *
|
843 | 411d62b0 | Kevin Wolf | * Note that guest_offset may not be cluster aligned. In this case, the
|
844 | 411d62b0 | Kevin Wolf | * returned *host_offset points to exact byte referenced by guest_offset and
|
845 | 411d62b0 | Kevin Wolf | * therefore isn't cluster aligned as well.
|
846 | 0af729ec | Kevin Wolf | *
|
847 | 0af729ec | Kevin Wolf | * Returns:
|
848 | 0af729ec | Kevin Wolf | * 0: if no allocated clusters are available at the given offset.
|
849 | 0af729ec | Kevin Wolf | * *bytes is normally unchanged. It is set to 0 if the cluster
|
850 | 0af729ec | Kevin Wolf | * is allocated and doesn't need COW, but doesn't have the right
|
851 | 0af729ec | Kevin Wolf | * physical offset.
|
852 | 0af729ec | Kevin Wolf | *
|
853 | 0af729ec | Kevin Wolf | * 1: if allocated clusters that don't require a COW are available at
|
854 | 0af729ec | Kevin Wolf | * the requested offset. *bytes may have decreased and describes
|
855 | 0af729ec | Kevin Wolf | * the length of the area that can be written to.
|
856 | 0af729ec | Kevin Wolf | *
|
857 | 0af729ec | Kevin Wolf | * -errno: in error cases
|
858 | 0af729ec | Kevin Wolf | */
|
859 | 0af729ec | Kevin Wolf | static int handle_copied(BlockDriverState *bs, uint64_t guest_offset, |
860 | c53ede9f | Kevin Wolf | uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) |
861 | 0af729ec | Kevin Wolf | { |
862 | 0af729ec | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
863 | 0af729ec | Kevin Wolf | int l2_index;
|
864 | 0af729ec | Kevin Wolf | uint64_t cluster_offset; |
865 | 0af729ec | Kevin Wolf | uint64_t *l2_table; |
866 | acb0467f | Kevin Wolf | unsigned int nb_clusters; |
867 | c53ede9f | Kevin Wolf | unsigned int keep_clusters; |
868 | 0af729ec | Kevin Wolf | int ret, pret;
|
869 | 0af729ec | Kevin Wolf | |
870 | 0af729ec | Kevin Wolf | trace_qcow2_handle_copied(qemu_coroutine_self(), guest_offset, *host_offset, |
871 | 0af729ec | Kevin Wolf | *bytes); |
872 | 0af729ec | Kevin Wolf | |
873 | 411d62b0 | Kevin Wolf | assert(*host_offset == 0 || offset_into_cluster(s, guest_offset)
|
874 | 411d62b0 | Kevin Wolf | == offset_into_cluster(s, *host_offset)); |
875 | 411d62b0 | Kevin Wolf | |
876 | acb0467f | Kevin Wolf | /*
|
877 | acb0467f | Kevin Wolf | * Calculate the number of clusters to look for. We stop at L2 table
|
878 | acb0467f | Kevin Wolf | * boundaries to keep things simple.
|
879 | acb0467f | Kevin Wolf | */
|
880 | acb0467f | Kevin Wolf | nb_clusters = |
881 | acb0467f | Kevin Wolf | size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes); |
882 | acb0467f | Kevin Wolf | |
883 | acb0467f | Kevin Wolf | l2_index = offset_to_l2_index(s, guest_offset); |
884 | acb0467f | Kevin Wolf | nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); |
885 | acb0467f | Kevin Wolf | |
886 | 0af729ec | Kevin Wolf | /* Find L2 entry for the first involved cluster */
|
887 | 0af729ec | Kevin Wolf | ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index); |
888 | 0af729ec | Kevin Wolf | if (ret < 0) { |
889 | 0af729ec | Kevin Wolf | return ret;
|
890 | 0af729ec | Kevin Wolf | } |
891 | 0af729ec | Kevin Wolf | |
892 | 0af729ec | Kevin Wolf | cluster_offset = be64_to_cpu(l2_table[l2_index]); |
893 | 0af729ec | Kevin Wolf | |
894 | 0af729ec | Kevin Wolf | /* Check how many clusters are already allocated and don't need COW */
|
895 | 0af729ec | Kevin Wolf | if (qcow2_get_cluster_type(cluster_offset) == QCOW2_CLUSTER_NORMAL
|
896 | 0af729ec | Kevin Wolf | && (cluster_offset & QCOW_OFLAG_COPIED)) |
897 | 0af729ec | Kevin Wolf | { |
898 | e62daaf6 | Kevin Wolf | /* If a specific host_offset is required, check it */
|
899 | e62daaf6 | Kevin Wolf | bool offset_matches =
|
900 | e62daaf6 | Kevin Wolf | (cluster_offset & L2E_OFFSET_MASK) == *host_offset; |
901 | e62daaf6 | Kevin Wolf | |
902 | e62daaf6 | Kevin Wolf | if (*host_offset != 0 && !offset_matches) { |
903 | e62daaf6 | Kevin Wolf | *bytes = 0;
|
904 | e62daaf6 | Kevin Wolf | ret = 0;
|
905 | e62daaf6 | Kevin Wolf | goto out;
|
906 | e62daaf6 | Kevin Wolf | } |
907 | e62daaf6 | Kevin Wolf | |
908 | 0af729ec | Kevin Wolf | /* We keep all QCOW_OFLAG_COPIED clusters */
|
909 | c53ede9f | Kevin Wolf | keep_clusters = |
910 | acb0467f | Kevin Wolf | count_contiguous_clusters(nb_clusters, s->cluster_size, |
911 | 0af729ec | Kevin Wolf | &l2_table[l2_index], 0,
|
912 | 0af729ec | Kevin Wolf | QCOW_OFLAG_COPIED | QCOW_OFLAG_ZERO); |
913 | c53ede9f | Kevin Wolf | assert(keep_clusters <= nb_clusters); |
914 | c53ede9f | Kevin Wolf | |
915 | c53ede9f | Kevin Wolf | *bytes = MIN(*bytes, |
916 | c53ede9f | Kevin Wolf | keep_clusters * s->cluster_size |
917 | c53ede9f | Kevin Wolf | - offset_into_cluster(s, guest_offset)); |
918 | 0af729ec | Kevin Wolf | |
919 | 0af729ec | Kevin Wolf | ret = 1;
|
920 | 0af729ec | Kevin Wolf | } else {
|
921 | 0af729ec | Kevin Wolf | ret = 0;
|
922 | 0af729ec | Kevin Wolf | } |
923 | 0af729ec | Kevin Wolf | |
924 | 0af729ec | Kevin Wolf | /* Cleanup */
|
925 | e62daaf6 | Kevin Wolf | out:
|
926 | 0af729ec | Kevin Wolf | pret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
927 | 0af729ec | Kevin Wolf | if (pret < 0) { |
928 | 0af729ec | Kevin Wolf | return pret;
|
929 | 0af729ec | Kevin Wolf | } |
930 | 0af729ec | Kevin Wolf | |
931 | e62daaf6 | Kevin Wolf | /* Only return a host offset if we actually made progress. Otherwise we
|
932 | e62daaf6 | Kevin Wolf | * would make requirements for handle_alloc() that it can't fulfill */
|
933 | e62daaf6 | Kevin Wolf | if (ret) {
|
934 | 411d62b0 | Kevin Wolf | *host_offset = (cluster_offset & L2E_OFFSET_MASK) |
935 | 411d62b0 | Kevin Wolf | + offset_into_cluster(s, guest_offset); |
936 | e62daaf6 | Kevin Wolf | } |
937 | e62daaf6 | Kevin Wolf | |
938 | 0af729ec | Kevin Wolf | return ret;
|
939 | 0af729ec | Kevin Wolf | } |
940 | 0af729ec | Kevin Wolf | |
941 | 0af729ec | Kevin Wolf | /*
|
942 | 226c3c26 | Kevin Wolf | * Allocates new clusters for the given guest_offset.
|
943 | 226c3c26 | Kevin Wolf | *
|
944 | 226c3c26 | Kevin Wolf | * At most *nb_clusters are allocated, and on return *nb_clusters is updated to
|
945 | 226c3c26 | Kevin Wolf | * contain the number of clusters that have been allocated and are contiguous
|
946 | 226c3c26 | Kevin Wolf | * in the image file.
|
947 | 226c3c26 | Kevin Wolf | *
|
948 | 226c3c26 | Kevin Wolf | * If *host_offset is non-zero, it specifies the offset in the image file at
|
949 | 226c3c26 | Kevin Wolf | * which the new clusters must start. *nb_clusters can be 0 on return in this
|
950 | 226c3c26 | Kevin Wolf | * case if the cluster at host_offset is already in use. If *host_offset is
|
951 | 226c3c26 | Kevin Wolf | * zero, the clusters can be allocated anywhere in the image file.
|
952 | 226c3c26 | Kevin Wolf | *
|
953 | 226c3c26 | Kevin Wolf | * *host_offset is updated to contain the offset into the image file at which
|
954 | 226c3c26 | Kevin Wolf | * the first allocated cluster starts.
|
955 | 226c3c26 | Kevin Wolf | *
|
956 | 226c3c26 | Kevin Wolf | * Return 0 on success and -errno in error cases. -EAGAIN means that the
|
957 | 226c3c26 | Kevin Wolf | * function has been waiting for another request and the allocation must be
|
958 | 226c3c26 | Kevin Wolf | * restarted, but the whole request should not be failed.
|
959 | 226c3c26 | Kevin Wolf | */
|
960 | 226c3c26 | Kevin Wolf | static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset, |
961 | 226c3c26 | Kevin Wolf | uint64_t *host_offset, unsigned int *nb_clusters) |
962 | 226c3c26 | Kevin Wolf | { |
963 | 226c3c26 | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
964 | 226c3c26 | Kevin Wolf | |
965 | 226c3c26 | Kevin Wolf | trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset, |
966 | 226c3c26 | Kevin Wolf | *host_offset, *nb_clusters); |
967 | 226c3c26 | Kevin Wolf | |
968 | 250196f1 | Kevin Wolf | /* Allocate new clusters */
|
969 | 250196f1 | Kevin Wolf | trace_qcow2_cluster_alloc_phys(qemu_coroutine_self()); |
970 | 250196f1 | Kevin Wolf | if (*host_offset == 0) { |
971 | df021791 | Kevin Wolf | int64_t cluster_offset = |
972 | df021791 | Kevin Wolf | qcow2_alloc_clusters(bs, *nb_clusters * s->cluster_size); |
973 | df021791 | Kevin Wolf | if (cluster_offset < 0) { |
974 | df021791 | Kevin Wolf | return cluster_offset;
|
975 | df021791 | Kevin Wolf | } |
976 | df021791 | Kevin Wolf | *host_offset = cluster_offset; |
977 | df021791 | Kevin Wolf | return 0; |
978 | 250196f1 | Kevin Wolf | } else {
|
979 | 17a71e58 | Kevin Wolf | int ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters);
|
980 | df021791 | Kevin Wolf | if (ret < 0) { |
981 | df021791 | Kevin Wolf | return ret;
|
982 | df021791 | Kevin Wolf | } |
983 | df021791 | Kevin Wolf | *nb_clusters = ret; |
984 | df021791 | Kevin Wolf | return 0; |
985 | 250196f1 | Kevin Wolf | } |
986 | 250196f1 | Kevin Wolf | } |
987 | 250196f1 | Kevin Wolf | |
988 | 250196f1 | Kevin Wolf | /*
|
989 | 10f0ed8b | Kevin Wolf | * Allocates new clusters for an area that either is yet unallocated or needs a
|
990 | 10f0ed8b | Kevin Wolf | * copy on write. If *host_offset is non-zero, clusters are only allocated if
|
991 | 10f0ed8b | Kevin Wolf | * the new allocation can match the specified host offset.
|
992 | 10f0ed8b | Kevin Wolf | *
|
993 | 411d62b0 | Kevin Wolf | * Note that guest_offset may not be cluster aligned. In this case, the
|
994 | 411d62b0 | Kevin Wolf | * returned *host_offset points to exact byte referenced by guest_offset and
|
995 | 411d62b0 | Kevin Wolf | * therefore isn't cluster aligned as well.
|
996 | 10f0ed8b | Kevin Wolf | *
|
997 | 10f0ed8b | Kevin Wolf | * Returns:
|
998 | 10f0ed8b | Kevin Wolf | * 0: if no clusters could be allocated. *bytes is set to 0,
|
999 | 10f0ed8b | Kevin Wolf | * *host_offset is left unchanged.
|
1000 | 10f0ed8b | Kevin Wolf | *
|
1001 | 10f0ed8b | Kevin Wolf | * 1: if new clusters were allocated. *bytes may be decreased if the
|
1002 | 10f0ed8b | Kevin Wolf | * new allocation doesn't cover all of the requested area.
|
1003 | 10f0ed8b | Kevin Wolf | * *host_offset is updated to contain the host offset of the first
|
1004 | 10f0ed8b | Kevin Wolf | * newly allocated cluster.
|
1005 | 10f0ed8b | Kevin Wolf | *
|
1006 | 10f0ed8b | Kevin Wolf | * -errno: in error cases
|
1007 | 10f0ed8b | Kevin Wolf | */
|
1008 | 10f0ed8b | Kevin Wolf | static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, |
1009 | c37f4cd7 | Kevin Wolf | uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) |
1010 | 10f0ed8b | Kevin Wolf | { |
1011 | 10f0ed8b | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1012 | 10f0ed8b | Kevin Wolf | int l2_index;
|
1013 | 10f0ed8b | Kevin Wolf | uint64_t *l2_table; |
1014 | 10f0ed8b | Kevin Wolf | uint64_t entry; |
1015 | f5bc6350 | Kevin Wolf | unsigned int nb_clusters; |
1016 | 10f0ed8b | Kevin Wolf | int ret;
|
1017 | 10f0ed8b | Kevin Wolf | |
1018 | 10f0ed8b | Kevin Wolf | uint64_t alloc_cluster_offset; |
1019 | 10f0ed8b | Kevin Wolf | |
1020 | 10f0ed8b | Kevin Wolf | trace_qcow2_handle_alloc(qemu_coroutine_self(), guest_offset, *host_offset, |
1021 | 10f0ed8b | Kevin Wolf | *bytes); |
1022 | 10f0ed8b | Kevin Wolf | assert(*bytes > 0);
|
1023 | 10f0ed8b | Kevin Wolf | |
1024 | f5bc6350 | Kevin Wolf | /*
|
1025 | f5bc6350 | Kevin Wolf | * Calculate the number of clusters to look for. We stop at L2 table
|
1026 | f5bc6350 | Kevin Wolf | * boundaries to keep things simple.
|
1027 | f5bc6350 | Kevin Wolf | */
|
1028 | c37f4cd7 | Kevin Wolf | nb_clusters = |
1029 | c37f4cd7 | Kevin Wolf | size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes); |
1030 | c37f4cd7 | Kevin Wolf | |
1031 | f5bc6350 | Kevin Wolf | l2_index = offset_to_l2_index(s, guest_offset); |
1032 | c37f4cd7 | Kevin Wolf | nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); |
1033 | f5bc6350 | Kevin Wolf | |
1034 | 10f0ed8b | Kevin Wolf | /* Find L2 entry for the first involved cluster */
|
1035 | 10f0ed8b | Kevin Wolf | ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index); |
1036 | 10f0ed8b | Kevin Wolf | if (ret < 0) { |
1037 | 10f0ed8b | Kevin Wolf | return ret;
|
1038 | 10f0ed8b | Kevin Wolf | } |
1039 | 10f0ed8b | Kevin Wolf | |
1040 | 3b8e2e26 | Kevin Wolf | entry = be64_to_cpu(l2_table[l2_index]); |
1041 | 10f0ed8b | Kevin Wolf | |
1042 | 10f0ed8b | Kevin Wolf | /* For the moment, overwrite compressed clusters one by one */
|
1043 | 10f0ed8b | Kevin Wolf | if (entry & QCOW_OFLAG_COMPRESSED) {
|
1044 | 10f0ed8b | Kevin Wolf | nb_clusters = 1;
|
1045 | 10f0ed8b | Kevin Wolf | } else {
|
1046 | 3b8e2e26 | Kevin Wolf | nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index); |
1047 | 10f0ed8b | Kevin Wolf | } |
1048 | 10f0ed8b | Kevin Wolf | |
1049 | ecdd5333 | Kevin Wolf | /* This function is only called when there were no non-COW clusters, so if
|
1050 | ecdd5333 | Kevin Wolf | * we can't find any unallocated or COW clusters either, something is
|
1051 | ecdd5333 | Kevin Wolf | * wrong with our code. */
|
1052 | ecdd5333 | Kevin Wolf | assert(nb_clusters > 0);
|
1053 | ecdd5333 | Kevin Wolf | |
1054 | 10f0ed8b | Kevin Wolf | ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
1055 | 10f0ed8b | Kevin Wolf | if (ret < 0) { |
1056 | 10f0ed8b | Kevin Wolf | return ret;
|
1057 | 10f0ed8b | Kevin Wolf | } |
1058 | 10f0ed8b | Kevin Wolf | |
1059 | 10f0ed8b | Kevin Wolf | /* Allocate, if necessary at a given offset in the image file */
|
1060 | 411d62b0 | Kevin Wolf | alloc_cluster_offset = start_of_cluster(s, *host_offset); |
1061 | 83baa9a4 | Kevin Wolf | ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset, |
1062 | 10f0ed8b | Kevin Wolf | &nb_clusters); |
1063 | 10f0ed8b | Kevin Wolf | if (ret < 0) { |
1064 | 10f0ed8b | Kevin Wolf | goto fail;
|
1065 | 10f0ed8b | Kevin Wolf | } |
1066 | 10f0ed8b | Kevin Wolf | |
1067 | 83baa9a4 | Kevin Wolf | /* Can't extend contiguous allocation */
|
1068 | 83baa9a4 | Kevin Wolf | if (nb_clusters == 0) { |
1069 | 10f0ed8b | Kevin Wolf | *bytes = 0;
|
1070 | 10f0ed8b | Kevin Wolf | return 0; |
1071 | 10f0ed8b | Kevin Wolf | } |
1072 | 10f0ed8b | Kevin Wolf | |
1073 | 83baa9a4 | Kevin Wolf | /*
|
1074 | 83baa9a4 | Kevin Wolf | * Save info needed for meta data update.
|
1075 | 83baa9a4 | Kevin Wolf | *
|
1076 | 83baa9a4 | Kevin Wolf | * requested_sectors: Number of sectors from the start of the first
|
1077 | 83baa9a4 | Kevin Wolf | * newly allocated cluster to the end of the (possibly shortened
|
1078 | 83baa9a4 | Kevin Wolf | * before) write request.
|
1079 | 83baa9a4 | Kevin Wolf | *
|
1080 | 83baa9a4 | Kevin Wolf | * avail_sectors: Number of sectors from the start of the first
|
1081 | 83baa9a4 | Kevin Wolf | * newly allocated to the end of the last newly allocated cluster.
|
1082 | 83baa9a4 | Kevin Wolf | *
|
1083 | 83baa9a4 | Kevin Wolf | * nb_sectors: The number of sectors from the start of the first
|
1084 | 83baa9a4 | Kevin Wolf | * newly allocated cluster to the end of the area that the write
|
1085 | 83baa9a4 | Kevin Wolf | * request actually writes to (excluding COW at the end)
|
1086 | 83baa9a4 | Kevin Wolf | */
|
1087 | 83baa9a4 | Kevin Wolf | int requested_sectors =
|
1088 | 83baa9a4 | Kevin Wolf | (*bytes + offset_into_cluster(s, guest_offset)) |
1089 | 83baa9a4 | Kevin Wolf | >> BDRV_SECTOR_BITS; |
1090 | 83baa9a4 | Kevin Wolf | int avail_sectors = nb_clusters
|
1091 | 83baa9a4 | Kevin Wolf | << (s->cluster_bits - BDRV_SECTOR_BITS); |
1092 | 83baa9a4 | Kevin Wolf | int alloc_n_start = offset_into_cluster(s, guest_offset)
|
1093 | 83baa9a4 | Kevin Wolf | >> BDRV_SECTOR_BITS; |
1094 | 83baa9a4 | Kevin Wolf | int nb_sectors = MIN(requested_sectors, avail_sectors);
|
1095 | 88c6588c | Kevin Wolf | QCowL2Meta *old_m = *m; |
1096 | 83baa9a4 | Kevin Wolf | |
1097 | 83baa9a4 | Kevin Wolf | *m = g_malloc0(sizeof(**m));
|
1098 | 83baa9a4 | Kevin Wolf | |
1099 | 83baa9a4 | Kevin Wolf | **m = (QCowL2Meta) { |
1100 | 88c6588c | Kevin Wolf | .next = old_m, |
1101 | 88c6588c | Kevin Wolf | |
1102 | 411d62b0 | Kevin Wolf | .alloc_offset = alloc_cluster_offset, |
1103 | 83baa9a4 | Kevin Wolf | .offset = start_of_cluster(s, guest_offset), |
1104 | 83baa9a4 | Kevin Wolf | .nb_clusters = nb_clusters, |
1105 | 83baa9a4 | Kevin Wolf | .nb_available = nb_sectors, |
1106 | 83baa9a4 | Kevin Wolf | |
1107 | 83baa9a4 | Kevin Wolf | .cow_start = { |
1108 | 83baa9a4 | Kevin Wolf | .offset = 0,
|
1109 | 83baa9a4 | Kevin Wolf | .nb_sectors = alloc_n_start, |
1110 | 83baa9a4 | Kevin Wolf | }, |
1111 | 83baa9a4 | Kevin Wolf | .cow_end = { |
1112 | 83baa9a4 | Kevin Wolf | .offset = nb_sectors * BDRV_SECTOR_SIZE, |
1113 | 83baa9a4 | Kevin Wolf | .nb_sectors = avail_sectors - nb_sectors, |
1114 | 83baa9a4 | Kevin Wolf | }, |
1115 | 83baa9a4 | Kevin Wolf | }; |
1116 | 83baa9a4 | Kevin Wolf | qemu_co_queue_init(&(*m)->dependent_requests); |
1117 | 83baa9a4 | Kevin Wolf | QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); |
1118 | 83baa9a4 | Kevin Wolf | |
1119 | 411d62b0 | Kevin Wolf | *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset); |
1120 | 83baa9a4 | Kevin Wolf | *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE) |
1121 | 83baa9a4 | Kevin Wolf | - offset_into_cluster(s, guest_offset)); |
1122 | 83baa9a4 | Kevin Wolf | assert(*bytes != 0);
|
1123 | 83baa9a4 | Kevin Wolf | |
1124 | 10f0ed8b | Kevin Wolf | return 1; |
1125 | 10f0ed8b | Kevin Wolf | |
1126 | 10f0ed8b | Kevin Wolf | fail:
|
1127 | 10f0ed8b | Kevin Wolf | if (*m && (*m)->nb_clusters > 0) { |
1128 | 10f0ed8b | Kevin Wolf | QLIST_REMOVE(*m, next_in_flight); |
1129 | 10f0ed8b | Kevin Wolf | } |
1130 | 10f0ed8b | Kevin Wolf | return ret;
|
1131 | 10f0ed8b | Kevin Wolf | } |
1132 | 10f0ed8b | Kevin Wolf | |
1133 | 10f0ed8b | Kevin Wolf | /*
|
1134 | 45aba42f | Kevin Wolf | * alloc_cluster_offset
|
1135 | 45aba42f | Kevin Wolf | *
|
1136 | 250196f1 | Kevin Wolf | * For a given offset on the virtual disk, find the cluster offset in qcow2
|
1137 | 250196f1 | Kevin Wolf | * file. If the offset is not found, allocate a new cluster.
|
1138 | 45aba42f | Kevin Wolf | *
|
1139 | 250196f1 | Kevin Wolf | * If the cluster was already allocated, m->nb_clusters is set to 0 and
|
1140 | a7912369 | Frediano Ziglio | * other fields in m are meaningless.
|
1141 | 148da7ea | Kevin Wolf | *
|
1142 | 148da7ea | Kevin Wolf | * If the cluster is newly allocated, m->nb_clusters is set to the number of
|
1143 | 68d100e9 | Kevin Wolf | * contiguous clusters that have been allocated. In this case, the other
|
1144 | 68d100e9 | Kevin Wolf | * fields of m are valid and contain information about the first allocated
|
1145 | 68d100e9 | Kevin Wolf | * cluster.
|
1146 | 45aba42f | Kevin Wolf | *
|
1147 | 68d100e9 | Kevin Wolf | * If the request conflicts with another write request in flight, the coroutine
|
1148 | 68d100e9 | Kevin Wolf | * is queued and will be reentered when the dependency has completed.
|
1149 | 148da7ea | Kevin Wolf | *
|
1150 | 148da7ea | Kevin Wolf | * Return 0 on success and -errno in error cases
|
1151 | 45aba42f | Kevin Wolf | */
|
1152 | f4f0d391 | Kevin Wolf | int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
1153 | f50f88b9 | Kevin Wolf | int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m) |
1154 | 45aba42f | Kevin Wolf | { |
1155 | 45aba42f | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1156 | 710c2496 | Kevin Wolf | uint64_t start, remaining; |
1157 | 250196f1 | Kevin Wolf | uint64_t cluster_offset; |
1158 | 65eb2e35 | Kevin Wolf | uint64_t cur_bytes; |
1159 | 710c2496 | Kevin Wolf | int ret;
|
1160 | 45aba42f | Kevin Wolf | |
1161 | 3cce16f4 | Kevin Wolf | trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, |
1162 | 3cce16f4 | Kevin Wolf | n_start, n_end); |
1163 | 3cce16f4 | Kevin Wolf | |
1164 | 710c2496 | Kevin Wolf | assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset)); |
1165 | 710c2496 | Kevin Wolf | offset = start_of_cluster(s, offset); |
1166 | 710c2496 | Kevin Wolf | |
1167 | 72424114 | Kevin Wolf | again:
|
1168 | 710c2496 | Kevin Wolf | start = offset + (n_start << BDRV_SECTOR_BITS); |
1169 | 710c2496 | Kevin Wolf | remaining = (n_end - n_start) << BDRV_SECTOR_BITS; |
1170 | 0af729ec | Kevin Wolf | cluster_offset = 0;
|
1171 | 0af729ec | Kevin Wolf | *host_offset = 0;
|
1172 | ecdd5333 | Kevin Wolf | cur_bytes = 0;
|
1173 | ecdd5333 | Kevin Wolf | *m = NULL;
|
1174 | 0af729ec | Kevin Wolf | |
1175 | 2c3b32d2 | Kevin Wolf | while (true) { |
1176 | ecdd5333 | Kevin Wolf | |
1177 | ecdd5333 | Kevin Wolf | if (!*host_offset) {
|
1178 | ecdd5333 | Kevin Wolf | *host_offset = start_of_cluster(s, cluster_offset); |
1179 | ecdd5333 | Kevin Wolf | } |
1180 | ecdd5333 | Kevin Wolf | |
1181 | ecdd5333 | Kevin Wolf | assert(remaining >= cur_bytes); |
1182 | ecdd5333 | Kevin Wolf | |
1183 | ecdd5333 | Kevin Wolf | start += cur_bytes; |
1184 | ecdd5333 | Kevin Wolf | remaining -= cur_bytes; |
1185 | ecdd5333 | Kevin Wolf | cluster_offset += cur_bytes; |
1186 | ecdd5333 | Kevin Wolf | |
1187 | ecdd5333 | Kevin Wolf | if (remaining == 0) { |
1188 | ecdd5333 | Kevin Wolf | break;
|
1189 | ecdd5333 | Kevin Wolf | } |
1190 | ecdd5333 | Kevin Wolf | |
1191 | ecdd5333 | Kevin Wolf | cur_bytes = remaining; |
1192 | ecdd5333 | Kevin Wolf | |
1193 | 2c3b32d2 | Kevin Wolf | /*
|
1194 | 2c3b32d2 | Kevin Wolf | * Now start gathering as many contiguous clusters as possible:
|
1195 | 2c3b32d2 | Kevin Wolf | *
|
1196 | 2c3b32d2 | Kevin Wolf | * 1. Check for overlaps with in-flight allocations
|
1197 | 2c3b32d2 | Kevin Wolf | *
|
1198 | 2c3b32d2 | Kevin Wolf | * a) Overlap not in the first cluster -> shorten this request and
|
1199 | 2c3b32d2 | Kevin Wolf | * let the caller handle the rest in its next loop iteration.
|
1200 | 2c3b32d2 | Kevin Wolf | *
|
1201 | 2c3b32d2 | Kevin Wolf | * b) Real overlaps of two requests. Yield and restart the search
|
1202 | 2c3b32d2 | Kevin Wolf | * for contiguous clusters (the situation could have changed
|
1203 | 2c3b32d2 | Kevin Wolf | * while we were sleeping)
|
1204 | 2c3b32d2 | Kevin Wolf | *
|
1205 | 2c3b32d2 | Kevin Wolf | * c) TODO: Request starts in the same cluster as the in-flight
|
1206 | 2c3b32d2 | Kevin Wolf | * allocation ends. Shorten the COW of the in-fight allocation,
|
1207 | 2c3b32d2 | Kevin Wolf | * set cluster_offset to write to the same cluster and set up
|
1208 | 2c3b32d2 | Kevin Wolf | * the right synchronisation between the in-flight request and
|
1209 | 2c3b32d2 | Kevin Wolf | * the new one.
|
1210 | 2c3b32d2 | Kevin Wolf | */
|
1211 | ecdd5333 | Kevin Wolf | ret = handle_dependencies(bs, start, &cur_bytes, m); |
1212 | 2c3b32d2 | Kevin Wolf | if (ret == -EAGAIN) {
|
1213 | ecdd5333 | Kevin Wolf | /* Currently handle_dependencies() doesn't yield if we already had
|
1214 | ecdd5333 | Kevin Wolf | * an allocation. If it did, we would have to clean up the L2Meta
|
1215 | ecdd5333 | Kevin Wolf | * structs before starting over. */
|
1216 | ecdd5333 | Kevin Wolf | assert(*m == NULL);
|
1217 | 2c3b32d2 | Kevin Wolf | goto again;
|
1218 | 2c3b32d2 | Kevin Wolf | } else if (ret < 0) { |
1219 | 2c3b32d2 | Kevin Wolf | return ret;
|
1220 | ecdd5333 | Kevin Wolf | } else if (cur_bytes == 0) { |
1221 | ecdd5333 | Kevin Wolf | break;
|
1222 | 2c3b32d2 | Kevin Wolf | } else {
|
1223 | 2c3b32d2 | Kevin Wolf | /* handle_dependencies() may have decreased cur_bytes (shortened
|
1224 | 2c3b32d2 | Kevin Wolf | * the allocations below) so that the next dependency is processed
|
1225 | 2c3b32d2 | Kevin Wolf | * correctly during the next loop iteration. */
|
1226 | 0af729ec | Kevin Wolf | } |
1227 | 710c2496 | Kevin Wolf | |
1228 | 2c3b32d2 | Kevin Wolf | /*
|
1229 | 2c3b32d2 | Kevin Wolf | * 2. Count contiguous COPIED clusters.
|
1230 | 2c3b32d2 | Kevin Wolf | */
|
1231 | 2c3b32d2 | Kevin Wolf | ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m); |
1232 | 2c3b32d2 | Kevin Wolf | if (ret < 0) { |
1233 | 2c3b32d2 | Kevin Wolf | return ret;
|
1234 | 2c3b32d2 | Kevin Wolf | } else if (ret) { |
1235 | ecdd5333 | Kevin Wolf | continue;
|
1236 | 2c3b32d2 | Kevin Wolf | } else if (cur_bytes == 0) { |
1237 | 2c3b32d2 | Kevin Wolf | break;
|
1238 | 2c3b32d2 | Kevin Wolf | } |
1239 | 060bee89 | Kevin Wolf | |
1240 | 2c3b32d2 | Kevin Wolf | /*
|
1241 | 2c3b32d2 | Kevin Wolf | * 3. If the request still hasn't completed, allocate new clusters,
|
1242 | 2c3b32d2 | Kevin Wolf | * considering any cluster_offset of steps 1c or 2.
|
1243 | 2c3b32d2 | Kevin Wolf | */
|
1244 | 2c3b32d2 | Kevin Wolf | ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m); |
1245 | 2c3b32d2 | Kevin Wolf | if (ret < 0) { |
1246 | 2c3b32d2 | Kevin Wolf | return ret;
|
1247 | 2c3b32d2 | Kevin Wolf | } else if (ret) { |
1248 | ecdd5333 | Kevin Wolf | continue;
|
1249 | 2c3b32d2 | Kevin Wolf | } else {
|
1250 | 2c3b32d2 | Kevin Wolf | assert(cur_bytes == 0);
|
1251 | 2c3b32d2 | Kevin Wolf | break;
|
1252 | 2c3b32d2 | Kevin Wolf | } |
1253 | f5bc6350 | Kevin Wolf | } |
1254 | 10f0ed8b | Kevin Wolf | |
1255 | 710c2496 | Kevin Wolf | *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS); |
1256 | 710c2496 | Kevin Wolf | assert(*num > 0);
|
1257 | 710c2496 | Kevin Wolf | assert(*host_offset != 0);
|
1258 | 45aba42f | Kevin Wolf | |
1259 | 148da7ea | Kevin Wolf | return 0; |
1260 | 45aba42f | Kevin Wolf | } |
1261 | 45aba42f | Kevin Wolf | |
1262 | 45aba42f | Kevin Wolf | static int decompress_buffer(uint8_t *out_buf, int out_buf_size, |
1263 | 45aba42f | Kevin Wolf | const uint8_t *buf, int buf_size) |
1264 | 45aba42f | Kevin Wolf | { |
1265 | 45aba42f | Kevin Wolf | z_stream strm1, *strm = &strm1; |
1266 | 45aba42f | Kevin Wolf | int ret, out_len;
|
1267 | 45aba42f | Kevin Wolf | |
1268 | 45aba42f | Kevin Wolf | memset(strm, 0, sizeof(*strm)); |
1269 | 45aba42f | Kevin Wolf | |
1270 | 45aba42f | Kevin Wolf | strm->next_in = (uint8_t *)buf; |
1271 | 45aba42f | Kevin Wolf | strm->avail_in = buf_size; |
1272 | 45aba42f | Kevin Wolf | strm->next_out = out_buf; |
1273 | 45aba42f | Kevin Wolf | strm->avail_out = out_buf_size; |
1274 | 45aba42f | Kevin Wolf | |
1275 | 45aba42f | Kevin Wolf | ret = inflateInit2(strm, -12);
|
1276 | 45aba42f | Kevin Wolf | if (ret != Z_OK)
|
1277 | 45aba42f | Kevin Wolf | return -1; |
1278 | 45aba42f | Kevin Wolf | ret = inflate(strm, Z_FINISH); |
1279 | 45aba42f | Kevin Wolf | out_len = strm->next_out - out_buf; |
1280 | 45aba42f | Kevin Wolf | if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
|
1281 | 45aba42f | Kevin Wolf | out_len != out_buf_size) { |
1282 | 45aba42f | Kevin Wolf | inflateEnd(strm); |
1283 | 45aba42f | Kevin Wolf | return -1; |
1284 | 45aba42f | Kevin Wolf | } |
1285 | 45aba42f | Kevin Wolf | inflateEnd(strm); |
1286 | 45aba42f | Kevin Wolf | return 0; |
1287 | 45aba42f | Kevin Wolf | } |
1288 | 45aba42f | Kevin Wolf | |
1289 | 66f82cee | Kevin Wolf | int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
|
1290 | 45aba42f | Kevin Wolf | { |
1291 | 66f82cee | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1292 | 45aba42f | Kevin Wolf | int ret, csize, nb_csectors, sector_offset;
|
1293 | 45aba42f | Kevin Wolf | uint64_t coffset; |
1294 | 45aba42f | Kevin Wolf | |
1295 | 45aba42f | Kevin Wolf | coffset = cluster_offset & s->cluster_offset_mask; |
1296 | 45aba42f | Kevin Wolf | if (s->cluster_cache_offset != coffset) {
|
1297 | 45aba42f | Kevin Wolf | nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
|
1298 | 45aba42f | Kevin Wolf | sector_offset = coffset & 511;
|
1299 | 45aba42f | Kevin Wolf | csize = nb_csectors * 512 - sector_offset;
|
1300 | 66f82cee | Kevin Wolf | BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED); |
1301 | 66f82cee | Kevin Wolf | ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors);
|
1302 | 45aba42f | Kevin Wolf | if (ret < 0) { |
1303 | 8af36488 | Kevin Wolf | return ret;
|
1304 | 45aba42f | Kevin Wolf | } |
1305 | 45aba42f | Kevin Wolf | if (decompress_buffer(s->cluster_cache, s->cluster_size,
|
1306 | 45aba42f | Kevin Wolf | s->cluster_data + sector_offset, csize) < 0) {
|
1307 | 8af36488 | Kevin Wolf | return -EIO;
|
1308 | 45aba42f | Kevin Wolf | } |
1309 | 45aba42f | Kevin Wolf | s->cluster_cache_offset = coffset; |
1310 | 45aba42f | Kevin Wolf | } |
1311 | 45aba42f | Kevin Wolf | return 0; |
1312 | 45aba42f | Kevin Wolf | } |
1313 | 5ea929e3 | Kevin Wolf | |
1314 | 5ea929e3 | Kevin Wolf | /*
|
1315 | 5ea929e3 | Kevin Wolf | * This discards as many clusters of nb_clusters as possible at once (i.e.
|
1316 | 5ea929e3 | Kevin Wolf | * all clusters in the same L2 table) and returns the number of discarded
|
1317 | 5ea929e3 | Kevin Wolf | * clusters.
|
1318 | 5ea929e3 | Kevin Wolf | */
|
1319 | 5ea929e3 | Kevin Wolf | static int discard_single_l2(BlockDriverState *bs, uint64_t offset, |
1320 | 5ea929e3 | Kevin Wolf | unsigned int nb_clusters) |
1321 | 5ea929e3 | Kevin Wolf | { |
1322 | 5ea929e3 | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1323 | 3948d1d4 | Kevin Wolf | uint64_t *l2_table; |
1324 | 5ea929e3 | Kevin Wolf | int l2_index;
|
1325 | 5ea929e3 | Kevin Wolf | int ret;
|
1326 | 5ea929e3 | Kevin Wolf | int i;
|
1327 | 5ea929e3 | Kevin Wolf | |
1328 | 3948d1d4 | Kevin Wolf | ret = get_cluster_table(bs, offset, &l2_table, &l2_index); |
1329 | 5ea929e3 | Kevin Wolf | if (ret < 0) { |
1330 | 5ea929e3 | Kevin Wolf | return ret;
|
1331 | 5ea929e3 | Kevin Wolf | } |
1332 | 5ea929e3 | Kevin Wolf | |
1333 | 5ea929e3 | Kevin Wolf | /* Limit nb_clusters to one L2 table */
|
1334 | 5ea929e3 | Kevin Wolf | nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); |
1335 | 5ea929e3 | Kevin Wolf | |
1336 | 5ea929e3 | Kevin Wolf | for (i = 0; i < nb_clusters; i++) { |
1337 | 5ea929e3 | Kevin Wolf | uint64_t old_offset; |
1338 | 5ea929e3 | Kevin Wolf | |
1339 | 5ea929e3 | Kevin Wolf | old_offset = be64_to_cpu(l2_table[l2_index + i]); |
1340 | 8e37f681 | Kevin Wolf | if ((old_offset & L2E_OFFSET_MASK) == 0) { |
1341 | 5ea929e3 | Kevin Wolf | continue;
|
1342 | 5ea929e3 | Kevin Wolf | } |
1343 | 5ea929e3 | Kevin Wolf | |
1344 | 5ea929e3 | Kevin Wolf | /* First remove L2 entries */
|
1345 | 5ea929e3 | Kevin Wolf | qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); |
1346 | 5ea929e3 | Kevin Wolf | l2_table[l2_index + i] = cpu_to_be64(0);
|
1347 | 5ea929e3 | Kevin Wolf | |
1348 | 5ea929e3 | Kevin Wolf | /* Then decrease the refcount */
|
1349 | 6cfcb9b8 | Kevin Wolf | qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);
|
1350 | 5ea929e3 | Kevin Wolf | } |
1351 | 5ea929e3 | Kevin Wolf | |
1352 | 5ea929e3 | Kevin Wolf | ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
1353 | 5ea929e3 | Kevin Wolf | if (ret < 0) { |
1354 | 5ea929e3 | Kevin Wolf | return ret;
|
1355 | 5ea929e3 | Kevin Wolf | } |
1356 | 5ea929e3 | Kevin Wolf | |
1357 | 5ea929e3 | Kevin Wolf | return nb_clusters;
|
1358 | 5ea929e3 | Kevin Wolf | } |
1359 | 5ea929e3 | Kevin Wolf | |
1360 | 5ea929e3 | Kevin Wolf | int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
|
1361 | 5ea929e3 | Kevin Wolf | int nb_sectors)
|
1362 | 5ea929e3 | Kevin Wolf | { |
1363 | 5ea929e3 | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1364 | 5ea929e3 | Kevin Wolf | uint64_t end_offset; |
1365 | 5ea929e3 | Kevin Wolf | unsigned int nb_clusters; |
1366 | 5ea929e3 | Kevin Wolf | int ret;
|
1367 | 5ea929e3 | Kevin Wolf | |
1368 | 5ea929e3 | Kevin Wolf | end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS); |
1369 | 5ea929e3 | Kevin Wolf | |
1370 | 5ea929e3 | Kevin Wolf | /* Round start up and end down */
|
1371 | 5ea929e3 | Kevin Wolf | offset = align_offset(offset, s->cluster_size); |
1372 | 5ea929e3 | Kevin Wolf | end_offset &= ~(s->cluster_size - 1);
|
1373 | 5ea929e3 | Kevin Wolf | |
1374 | 5ea929e3 | Kevin Wolf | if (offset > end_offset) {
|
1375 | 5ea929e3 | Kevin Wolf | return 0; |
1376 | 5ea929e3 | Kevin Wolf | } |
1377 | 5ea929e3 | Kevin Wolf | |
1378 | 5ea929e3 | Kevin Wolf | nb_clusters = size_to_clusters(s, end_offset - offset); |
1379 | 5ea929e3 | Kevin Wolf | |
1380 | 5ea929e3 | Kevin Wolf | /* Each L2 table is handled by its own loop iteration */
|
1381 | 5ea929e3 | Kevin Wolf | while (nb_clusters > 0) { |
1382 | 5ea929e3 | Kevin Wolf | ret = discard_single_l2(bs, offset, nb_clusters); |
1383 | 5ea929e3 | Kevin Wolf | if (ret < 0) { |
1384 | 5ea929e3 | Kevin Wolf | return ret;
|
1385 | 5ea929e3 | Kevin Wolf | } |
1386 | 5ea929e3 | Kevin Wolf | |
1387 | 5ea929e3 | Kevin Wolf | nb_clusters -= ret; |
1388 | 5ea929e3 | Kevin Wolf | offset += (ret * s->cluster_size); |
1389 | 5ea929e3 | Kevin Wolf | } |
1390 | 5ea929e3 | Kevin Wolf | |
1391 | 5ea929e3 | Kevin Wolf | return 0; |
1392 | 5ea929e3 | Kevin Wolf | } |
1393 | 621f0589 | Kevin Wolf | |
1394 | 621f0589 | Kevin Wolf | /*
|
1395 | 621f0589 | Kevin Wolf | * This zeroes as many clusters of nb_clusters as possible at once (i.e.
|
1396 | 621f0589 | Kevin Wolf | * all clusters in the same L2 table) and returns the number of zeroed
|
1397 | 621f0589 | Kevin Wolf | * clusters.
|
1398 | 621f0589 | Kevin Wolf | */
|
1399 | 621f0589 | Kevin Wolf | static int zero_single_l2(BlockDriverState *bs, uint64_t offset, |
1400 | 621f0589 | Kevin Wolf | unsigned int nb_clusters) |
1401 | 621f0589 | Kevin Wolf | { |
1402 | 621f0589 | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1403 | 621f0589 | Kevin Wolf | uint64_t *l2_table; |
1404 | 621f0589 | Kevin Wolf | int l2_index;
|
1405 | 621f0589 | Kevin Wolf | int ret;
|
1406 | 621f0589 | Kevin Wolf | int i;
|
1407 | 621f0589 | Kevin Wolf | |
1408 | 621f0589 | Kevin Wolf | ret = get_cluster_table(bs, offset, &l2_table, &l2_index); |
1409 | 621f0589 | Kevin Wolf | if (ret < 0) { |
1410 | 621f0589 | Kevin Wolf | return ret;
|
1411 | 621f0589 | Kevin Wolf | } |
1412 | 621f0589 | Kevin Wolf | |
1413 | 621f0589 | Kevin Wolf | /* Limit nb_clusters to one L2 table */
|
1414 | 621f0589 | Kevin Wolf | nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); |
1415 | 621f0589 | Kevin Wolf | |
1416 | 621f0589 | Kevin Wolf | for (i = 0; i < nb_clusters; i++) { |
1417 | 621f0589 | Kevin Wolf | uint64_t old_offset; |
1418 | 621f0589 | Kevin Wolf | |
1419 | 621f0589 | Kevin Wolf | old_offset = be64_to_cpu(l2_table[l2_index + i]); |
1420 | 621f0589 | Kevin Wolf | |
1421 | 621f0589 | Kevin Wolf | /* Update L2 entries */
|
1422 | 621f0589 | Kevin Wolf | qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); |
1423 | 621f0589 | Kevin Wolf | if (old_offset & QCOW_OFLAG_COMPRESSED) {
|
1424 | 621f0589 | Kevin Wolf | l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO); |
1425 | 6cfcb9b8 | Kevin Wolf | qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);
|
1426 | 621f0589 | Kevin Wolf | } else {
|
1427 | 621f0589 | Kevin Wolf | l2_table[l2_index + i] |= cpu_to_be64(QCOW_OFLAG_ZERO); |
1428 | 621f0589 | Kevin Wolf | } |
1429 | 621f0589 | Kevin Wolf | } |
1430 | 621f0589 | Kevin Wolf | |
1431 | 621f0589 | Kevin Wolf | ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
|
1432 | 621f0589 | Kevin Wolf | if (ret < 0) { |
1433 | 621f0589 | Kevin Wolf | return ret;
|
1434 | 621f0589 | Kevin Wolf | } |
1435 | 621f0589 | Kevin Wolf | |
1436 | 621f0589 | Kevin Wolf | return nb_clusters;
|
1437 | 621f0589 | Kevin Wolf | } |
1438 | 621f0589 | Kevin Wolf | |
1439 | 621f0589 | Kevin Wolf | int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors) |
1440 | 621f0589 | Kevin Wolf | { |
1441 | 621f0589 | Kevin Wolf | BDRVQcowState *s = bs->opaque; |
1442 | 621f0589 | Kevin Wolf | unsigned int nb_clusters; |
1443 | 621f0589 | Kevin Wolf | int ret;
|
1444 | 621f0589 | Kevin Wolf | |
1445 | 621f0589 | Kevin Wolf | /* The zero flag is only supported by version 3 and newer */
|
1446 | 621f0589 | Kevin Wolf | if (s->qcow_version < 3) { |
1447 | 621f0589 | Kevin Wolf | return -ENOTSUP;
|
1448 | 621f0589 | Kevin Wolf | } |
1449 | 621f0589 | Kevin Wolf | |
1450 | 621f0589 | Kevin Wolf | /* Each L2 table is handled by its own loop iteration */
|
1451 | 621f0589 | Kevin Wolf | nb_clusters = size_to_clusters(s, nb_sectors << BDRV_SECTOR_BITS); |
1452 | 621f0589 | Kevin Wolf | |
1453 | 621f0589 | Kevin Wolf | while (nb_clusters > 0) { |
1454 | 621f0589 | Kevin Wolf | ret = zero_single_l2(bs, offset, nb_clusters); |
1455 | 621f0589 | Kevin Wolf | if (ret < 0) { |
1456 | 621f0589 | Kevin Wolf | return ret;
|
1457 | 621f0589 | Kevin Wolf | } |
1458 | 621f0589 | Kevin Wolf | |
1459 | 621f0589 | Kevin Wolf | nb_clusters -= ret; |
1460 | 621f0589 | Kevin Wolf | offset += (ret * s->cluster_size); |
1461 | 621f0589 | Kevin Wolf | } |
1462 | 621f0589 | Kevin Wolf | |
1463 | 621f0589 | Kevin Wolf | return 0; |
1464 | 621f0589 | Kevin Wolf | } |