qcow2-cluster.c (c46e116723803012853690f7938d7f66b92489db) qcow2-cluster.c (66f82ceed6781261c09e65fb440ca76842fd0500)
1/*
2 * Block driver for the QCOW version 2 format
3 *
4 * Copyright (c) 2004-2006 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 40 unchanged lines hidden (view full) ---

49 printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
50#endif
51
52 new_l1_size2 = sizeof(uint64_t) * new_l1_size;
53 new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
54 memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
55
56 /* write new table (align to cluster) */
1/*
2 * Block driver for the QCOW version 2 format
3 *
4 * Copyright (c) 2004-2006 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 40 unchanged lines hidden (view full) ---

49 printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
50#endif
51
52 new_l1_size2 = sizeof(uint64_t) * new_l1_size;
53 new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
54 memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
55
56 /* write new table (align to cluster) */
57 BLKDBG_EVENT(s->hd, BLKDBG_L1_GROW_ALLOC_TABLE);
57 BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE);
58 new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
59 if (new_l1_table_offset < 0) {
60 qemu_free(new_l1_table);
61 return new_l1_table_offset;
62 }
63
58 new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
59 if (new_l1_table_offset < 0) {
60 qemu_free(new_l1_table);
61 return new_l1_table_offset;
62 }
63
64 BLKDBG_EVENT(s->hd, BLKDBG_L1_GROW_WRITE_TABLE);
64 BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
65 for(i = 0; i < s->l1_size; i++)
66 new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
65 for(i = 0; i < s->l1_size; i++)
66 new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
67 ret = bdrv_pwrite(s->hd, new_l1_table_offset, new_l1_table, new_l1_size2);
67 ret = bdrv_pwrite(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
68 if (ret != new_l1_size2)
69 goto fail;
70 for(i = 0; i < s->l1_size; i++)
71 new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
72
73 /* set new table */
68 if (ret != new_l1_size2)
69 goto fail;
70 for(i = 0; i < s->l1_size; i++)
71 new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
72
73 /* set new table */
74 BLKDBG_EVENT(s->hd, BLKDBG_L1_GROW_ACTIVATE_TABLE);
74 BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
75 cpu_to_be32w((uint32_t*)data, new_l1_size);
76 cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
75 cpu_to_be32w((uint32_t*)data, new_l1_size);
76 cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
77 ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,sizeof(data));
77 ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
78 if (ret != sizeof(data)) {
79 goto fail;
80 }
81 qemu_free(s->l1_table);
82 qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
83 s->l1_table_offset = new_l1_table_offset;
84 s->l1_table = new_l1_table;
85 s->l1_size = new_l1_size;

--- 83 unchanged lines hidden (view full) ---

169 if (l2_table != NULL)
170 return l2_table;
171
172 /* not found: load a new entry in the least used one */
173
174 min_index = l2_cache_new_entry(bs);
175 l2_table = s->l2_cache + (min_index << s->l2_bits);
176
78 if (ret != sizeof(data)) {
79 goto fail;
80 }
81 qemu_free(s->l1_table);
82 qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
83 s->l1_table_offset = new_l1_table_offset;
84 s->l1_table = new_l1_table;
85 s->l1_size = new_l1_size;

--- 83 unchanged lines hidden (view full) ---

169 if (l2_table != NULL)
170 return l2_table;
171
172 /* not found: load a new entry in the least used one */
173
174 min_index = l2_cache_new_entry(bs);
175 l2_table = s->l2_cache + (min_index << s->l2_bits);
176
177 BLKDBG_EVENT(s->hd, BLKDBG_L2_LOAD);
178 if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
177 BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
178 if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
179 s->l2_size * sizeof(uint64_t))
180 return NULL;
181 s->l2_cache_offsets[min_index] = l2_offset;
182 s->l2_cache_counts[min_index] = 1;
183
184 return l2_table;
185}
186
187/*
188 * Writes one sector of the L1 table to the disk (can't update single entries
189 * and we really don't want bdrv_pread to perform a read-modify-write)
190 */
191#define L1_ENTRIES_PER_SECTOR (512 / 8)
179 s->l2_size * sizeof(uint64_t))
180 return NULL;
181 s->l2_cache_offsets[min_index] = l2_offset;
182 s->l2_cache_counts[min_index] = 1;
183
184 return l2_table;
185}
186
187/*
188 * Writes one sector of the L1 table to the disk (can't update single entries
189 * and we really don't want bdrv_pread to perform a read-modify-write)
190 */
191#define L1_ENTRIES_PER_SECTOR (512 / 8)
192static int write_l1_entry(BDRVQcowState *s, int l1_index)
192static int write_l1_entry(BlockDriverState *bs, int l1_index)
193{
193{
194 BDRVQcowState *s = bs->opaque;
194 uint64_t buf[L1_ENTRIES_PER_SECTOR];
195 int l1_start_index;
196 int i, ret;
197
198 l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
199 for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) {
200 buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
201 }
202
195 uint64_t buf[L1_ENTRIES_PER_SECTOR];
196 int l1_start_index;
197 int i, ret;
198
199 l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
200 for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) {
201 buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
202 }
203
203 BLKDBG_EVENT(s->hd, BLKDBG_L1_UPDATE);
204 ret = bdrv_pwrite(s->hd, s->l1_table_offset + 8 * l1_start_index,
204 BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
205 ret = bdrv_pwrite(bs->file, s->l1_table_offset + 8 * l1_start_index,
205 buf, sizeof(buf));
206 if (ret < 0) {
207 return ret;
208 }
209
210 return 0;
211}
212

--- 23 unchanged lines hidden (view full) ---

236 l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
237 if (l2_offset < 0) {
238 return l2_offset;
239 }
240
241 /* update the L1 entry */
242
243 s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
206 buf, sizeof(buf));
207 if (ret < 0) {
208 return ret;
209 }
210
211 return 0;
212}
213

--- 23 unchanged lines hidden (view full) ---

237 l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
238 if (l2_offset < 0) {
239 return l2_offset;
240 }
241
242 /* update the L1 entry */
243
244 s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
244 ret = write_l1_entry(s, l1_index);
245 ret = write_l1_entry(bs, l1_index);
245 if (ret < 0) {
246 return ret;
247 }
248
249 /* allocate a new entry in the l2 cache */
250
251 min_index = l2_cache_new_entry(bs);
252 l2_table = s->l2_cache + (min_index << s->l2_bits);
253
254 if (old_l2_offset == 0) {
255 /* if there was no old l2 table, clear the new table */
256 memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
257 } else {
258 /* if there was an old l2 table, read it from the disk */
246 if (ret < 0) {
247 return ret;
248 }
249
250 /* allocate a new entry in the l2 cache */
251
252 min_index = l2_cache_new_entry(bs);
253 l2_table = s->l2_cache + (min_index << s->l2_bits);
254
255 if (old_l2_offset == 0) {
256 /* if there was no old l2 table, clear the new table */
257 memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
258 } else {
259 /* if there was an old l2 table, read it from the disk */
259 BLKDBG_EVENT(s->hd, BLKDBG_L2_ALLOC_COW_READ);
260 ret = bdrv_pread(s->hd, old_l2_offset, l2_table,
260 BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ);
261 ret = bdrv_pread(bs->file, old_l2_offset, l2_table,
261 s->l2_size * sizeof(uint64_t));
262 if (ret < 0) {
263 return ret;
264 }
265 }
266 /* write the l2 table to the file */
262 s->l2_size * sizeof(uint64_t));
263 if (ret < 0) {
264 return ret;
265 }
266 }
267 /* write the l2 table to the file */
267 BLKDBG_EVENT(s->hd, BLKDBG_L2_ALLOC_WRITE);
268 ret = bdrv_pwrite(s->hd, l2_offset, l2_table,
268 BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
269 ret = bdrv_pwrite(bs->file, l2_offset, l2_table,
269 s->l2_size * sizeof(uint64_t));
270 if (ret < 0) {
271 return ret;
272 }
273
274 /* update the l2 cache entry */
275
276 s->l2_cache_offsets[min_index] = l2_offset;

--- 66 unchanged lines hidden (view full) ---

343 n = nb_sectors;
344 cluster_offset = qcow2_get_cluster_offset(bs, sector_num << 9, &n);
345 index_in_cluster = sector_num & (s->cluster_sectors - 1);
346 if (!cluster_offset) {
347 if (bs->backing_hd) {
348 /* read from the base image */
349 n1 = qcow2_backing_read1(bs->backing_hd, sector_num, buf, n);
350 if (n1 > 0) {
270 s->l2_size * sizeof(uint64_t));
271 if (ret < 0) {
272 return ret;
273 }
274
275 /* update the l2 cache entry */
276
277 s->l2_cache_offsets[min_index] = l2_offset;

--- 66 unchanged lines hidden (view full) ---

344 n = nb_sectors;
345 cluster_offset = qcow2_get_cluster_offset(bs, sector_num << 9, &n);
346 index_in_cluster = sector_num & (s->cluster_sectors - 1);
347 if (!cluster_offset) {
348 if (bs->backing_hd) {
349 /* read from the base image */
350 n1 = qcow2_backing_read1(bs->backing_hd, sector_num, buf, n);
351 if (n1 > 0) {
351 BLKDBG_EVENT(s->hd, BLKDBG_READ_BACKING);
352 BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING);
352 ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
353 if (ret < 0)
354 return -1;
355 }
356 } else {
357 memset(buf, 0, 512 * n);
358 }
359 } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
353 ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
354 if (ret < 0)
355 return -1;
356 }
357 } else {
358 memset(buf, 0, 512 * n);
359 }
360 } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
360 if (qcow2_decompress_cluster(s, cluster_offset) < 0)
361 if (qcow2_decompress_cluster(bs, cluster_offset) < 0)
361 return -1;
362 memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
363 } else {
362 return -1;
363 memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
364 } else {
364 BLKDBG_EVENT(s->hd, BLKDBG_READ);
365 ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
365 BLKDBG_EVENT(bs->file, BLKDBG_READ);
366 ret = bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512);
366 if (ret != n * 512)
367 return -1;
368 if (s->crypt_method) {
369 qcow2_encrypt_sectors(s, sector_num, buf, buf, n, 0,
370 &s->aes_decrypt_key);
371 }
372 }
373 nb_sectors -= n;

--- 7 unchanged lines hidden (view full) ---

381 uint64_t cluster_offset, int n_start, int n_end)
382{
383 BDRVQcowState *s = bs->opaque;
384 int n, ret;
385
386 n = n_end - n_start;
387 if (n <= 0)
388 return 0;
367 if (ret != n * 512)
368 return -1;
369 if (s->crypt_method) {
370 qcow2_encrypt_sectors(s, sector_num, buf, buf, n, 0,
371 &s->aes_decrypt_key);
372 }
373 }
374 nb_sectors -= n;

--- 7 unchanged lines hidden (view full) ---

382 uint64_t cluster_offset, int n_start, int n_end)
383{
384 BDRVQcowState *s = bs->opaque;
385 int n, ret;
386
387 n = n_end - n_start;
388 if (n <= 0)
389 return 0;
389 BLKDBG_EVENT(s->hd, BLKDBG_COW_READ);
390 BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
390 ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n);
391 if (ret < 0)
392 return ret;
393 if (s->crypt_method) {
394 qcow2_encrypt_sectors(s, start_sect + n_start,
395 s->cluster_data,
396 s->cluster_data, n, 1,
397 &s->aes_encrypt_key);
398 }
391 ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n);
392 if (ret < 0)
393 return ret;
394 if (s->crypt_method) {
395 qcow2_encrypt_sectors(s, start_sect + n_start,
396 s->cluster_data,
397 s->cluster_data, n, 1,
398 &s->aes_encrypt_key);
399 }
399 BLKDBG_EVENT(s->hd, BLKDBG_COW_WRITE);
400 ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start,
400 BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
401 ret = bdrv_write(bs->file, (cluster_offset >> 9) + n_start,
401 s->cluster_data, n);
402 if (ret < 0)
403 return ret;
404 return 0;
405}
406
407
408/*

--- 196 unchanged lines hidden (view full) ---

605
606 cluster_offset |= QCOW_OFLAG_COMPRESSED |
607 ((uint64_t)nb_csectors << s->csize_shift);
608
609 /* update L2 table */
610
611 /* compressed clusters never have the copied flag */
612
402 s->cluster_data, n);
403 if (ret < 0)
404 return ret;
405 return 0;
406}
407
408
409/*

--- 196 unchanged lines hidden (view full) ---

606
607 cluster_offset |= QCOW_OFLAG_COMPRESSED |
608 ((uint64_t)nb_csectors << s->csize_shift);
609
610 /* update L2 table */
611
612 /* compressed clusters never have the copied flag */
613
613 BLKDBG_EVENT(s->hd, BLKDBG_L2_UPDATE_COMPRESSED);
614 BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
614 l2_table[l2_index] = cpu_to_be64(cluster_offset);
615 l2_table[l2_index] = cpu_to_be64(cluster_offset);
615 if (bdrv_pwrite(s->hd,
616 if (bdrv_pwrite(bs->file,
616 l2_offset + l2_index * sizeof(uint64_t),
617 l2_table + l2_index,
618 sizeof(uint64_t)) != sizeof(uint64_t))
619 return 0;
620
621 return cluster_offset;
622}
623
624/*
625 * Write L2 table updates to disk, writing whole sectors to avoid a
626 * read-modify-write in bdrv_pwrite
627 */
628#define L2_ENTRIES_PER_SECTOR (512 / 8)
617 l2_offset + l2_index * sizeof(uint64_t),
618 l2_table + l2_index,
619 sizeof(uint64_t)) != sizeof(uint64_t))
620 return 0;
621
622 return cluster_offset;
623}
624
625/*
626 * Write L2 table updates to disk, writing whole sectors to avoid a
627 * read-modify-write in bdrv_pwrite
628 */
629#define L2_ENTRIES_PER_SECTOR (512 / 8)
629static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,
630static int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table,
630 uint64_t l2_offset, int l2_index, int num)
631{
632 int l2_start_index = l2_index & ~(L1_ENTRIES_PER_SECTOR - 1);
633 int start_offset = (8 * l2_index) & ~511;
634 int end_offset = (8 * (l2_index + num) + 511) & ~511;
635 size_t len = end_offset - start_offset;
636 int ret;
637
631 uint64_t l2_offset, int l2_index, int num)
632{
633 int l2_start_index = l2_index & ~(L1_ENTRIES_PER_SECTOR - 1);
634 int start_offset = (8 * l2_index) & ~511;
635 int end_offset = (8 * (l2_index + num) + 511) & ~511;
636 size_t len = end_offset - start_offset;
637 int ret;
638
638 BLKDBG_EVENT(s->hd, BLKDBG_L2_UPDATE);
639 ret = bdrv_pwrite(s->hd, l2_offset + start_offset,
639 BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
640 ret = bdrv_pwrite(bs->file, l2_offset + start_offset,
640 &l2_table[l2_start_index], len);
641 if (ret < 0) {
642 return ret;
643 }
644
645 return 0;
646}
647

--- 40 unchanged lines hidden (view full) ---

688 * old cluster. This is what this loop does */
689 if(l2_table[l2_index + i] != 0)
690 old_cluster[j++] = l2_table[l2_index + i];
691
692 l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
693 (i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
694 }
695
641 &l2_table[l2_start_index], len);
642 if (ret < 0) {
643 return ret;
644 }
645
646 return 0;
647}
648

--- 40 unchanged lines hidden (view full) ---

689 * old cluster. This is what this loop does */
690 if(l2_table[l2_index + i] != 0)
691 old_cluster[j++] = l2_table[l2_index + i];
692
693 l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
694 (i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
695 }
696
696 ret = write_l2_entries(s, l2_table, l2_offset, l2_index, m->nb_clusters);
697 ret = write_l2_entries(bs, l2_table, l2_offset, l2_index, m->nb_clusters);
697 if (ret < 0) {
698 goto err;
699 }
700
701 for (i = 0; i < j; i++)
702 qcow2_free_any_clusters(bs,
703 be64_to_cpu(old_cluster[i]) & ~QCOW_OFLAG_COPIED, 1);
704

--- 167 unchanged lines hidden (view full) ---

872 out_len != out_buf_size) {
873 inflateEnd(strm);
874 return -1;
875 }
876 inflateEnd(strm);
877 return 0;
878}
879
698 if (ret < 0) {
699 goto err;
700 }
701
702 for (i = 0; i < j; i++)
703 qcow2_free_any_clusters(bs,
704 be64_to_cpu(old_cluster[i]) & ~QCOW_OFLAG_COPIED, 1);
705

--- 167 unchanged lines hidden (view full) ---

873 out_len != out_buf_size) {
874 inflateEnd(strm);
875 return -1;
876 }
877 inflateEnd(strm);
878 return 0;
879}
880
880int qcow2_decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
881int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
881{
882{
883 BDRVQcowState *s = bs->opaque;
882 int ret, csize, nb_csectors, sector_offset;
883 uint64_t coffset;
884
885 coffset = cluster_offset & s->cluster_offset_mask;
886 if (s->cluster_cache_offset != coffset) {
887 nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
888 sector_offset = coffset & 511;
889 csize = nb_csectors * 512 - sector_offset;
884 int ret, csize, nb_csectors, sector_offset;
885 uint64_t coffset;
886
887 coffset = cluster_offset & s->cluster_offset_mask;
888 if (s->cluster_cache_offset != coffset) {
889 nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
890 sector_offset = coffset & 511;
891 csize = nb_csectors * 512 - sector_offset;
890 BLKDBG_EVENT(s->hd, BLKDBG_READ_COMPRESSED);
891 ret = bdrv_read(s->hd, coffset >> 9, s->cluster_data, nb_csectors);
892 BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
893 ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors);
892 if (ret < 0) {
893 return -1;
894 }
895 if (decompress_buffer(s->cluster_cache, s->cluster_size,
896 s->cluster_data + sector_offset, csize) < 0) {
897 return -1;
898 }
899 s->cluster_cache_offset = coffset;
900 }
901 return 0;
902}
894 if (ret < 0) {
895 return -1;
896 }
897 if (decompress_buffer(s->cluster_cache, s->cluster_size,
898 s->cluster_data + sector_offset, csize) < 0) {
899 return -1;
900 }
901 s->cluster_cache_offset = coffset;
902 }
903 return 0;
904}