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} |