Commit 095a9c58ce12afeeb90c225ed087017c307bc0fd

Authored by aliguori
1 parent 52d893ec

qcow2: Aggregate same type clusters (Laurent Vivier)

Modify get_cluster_offset(), alloc_cluster_offset() to specify how many clusters
we want.

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5006 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 181 additions and 53 deletions
block-qcow2.c
@@ -52,6 +52,8 @@ @@ -52,6 +52,8 @@
52 #define QCOW_CRYPT_NONE 0 52 #define QCOW_CRYPT_NONE 0
53 #define QCOW_CRYPT_AES 1 53 #define QCOW_CRYPT_AES 1
54 54
  55 +#define QCOW_MAX_CRYPT_CLUSTERS 32
  56 +
55 /* indicate that the refcount of the referenced cluster is exactly one. */ 57 /* indicate that the refcount of the referenced cluster is exactly one. */
56 #define QCOW_OFLAG_COPIED (1LL << 63) 58 #define QCOW_OFLAG_COPIED (1LL << 63)
57 /* indicate that the cluster is compressed (they never have the copied flag) */ 59 /* indicate that the cluster is compressed (they never have the copied flag) */
@@ -263,7 +265,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags) @@ -263,7 +265,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
263 if (!s->cluster_cache) 265 if (!s->cluster_cache)
264 goto fail; 266 goto fail;
265 /* one more sector for decompressed data alignment */ 267 /* one more sector for decompressed data alignment */
266 - s->cluster_data = qemu_malloc(s->cluster_size + 512); 268 + s->cluster_data = qemu_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size
  269 + + 512);
267 if (!s->cluster_data) 270 if (!s->cluster_data)
268 goto fail; 271 goto fail;
269 s->cluster_cache_offset = -1; 272 s->cluster_cache_offset = -1;
@@ -612,43 +615,98 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index) @@ -612,43 +615,98 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)
612 * For a given offset of the disk image, return cluster offset in 615 * For a given offset of the disk image, return cluster offset in
613 * qcow2 file. 616 * qcow2 file.
614 * 617 *
  618 + * on entry, *num is the number of contiguous clusters we'd like to
  619 + * access following offset.
  620 + *
  621 + * on exit, *num is the number of contiguous clusters we can read.
  622 + *
615 * Return 1, if the offset is found 623 * Return 1, if the offset is found
616 * Return 0, otherwise. 624 * Return 0, otherwise.
617 * 625 *
618 */ 626 */
619 627
620 -static uint64_t get_cluster_offset(BlockDriverState *bs, uint64_t offset) 628 +static uint64_t get_cluster_offset(BlockDriverState *bs,
  629 + uint64_t offset, int *num)
621 { 630 {
622 BDRVQcowState *s = bs->opaque; 631 BDRVQcowState *s = bs->opaque;
623 int l1_index, l2_index; 632 int l1_index, l2_index;
624 - uint64_t l2_offset, *l2_table, cluster_offset; 633 + uint64_t l2_offset, *l2_table, cluster_offset, next;
  634 + int l1_bits;
  635 + int index_in_cluster, nb_available, nb_needed;
  636 +
  637 + index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
  638 + nb_needed = *num + index_in_cluster;
  639 +
  640 + l1_bits = s->l2_bits + s->cluster_bits;
  641 +
  642 + /* compute how many bytes there are between the offset and
  643 + * and the end of the l1 entry
  644 + */
  645 +
  646 + nb_available = (1 << l1_bits) - (offset & ((1 << l1_bits) - 1));
  647 +
  648 + /* compute the number of available sectors */
  649 +
  650 + nb_available = (nb_available >> 9) + index_in_cluster;
  651 +
  652 + cluster_offset = 0;
625 653
626 /* seek the the l2 offset in the l1 table */ 654 /* seek the the l2 offset in the l1 table */
627 655
628 - l1_index = offset >> (s->l2_bits + s->cluster_bits); 656 + l1_index = offset >> l1_bits;
629 if (l1_index >= s->l1_size) 657 if (l1_index >= s->l1_size)
630 - return 0; 658 + goto out;
631 659
632 l2_offset = s->l1_table[l1_index]; 660 l2_offset = s->l1_table[l1_index];
633 661
634 /* seek the l2 table of the given l2 offset */ 662 /* seek the l2 table of the given l2 offset */
635 663
636 if (!l2_offset) 664 if (!l2_offset)
637 - return 0; 665 + goto out;
638 666
639 /* load the l2 table in memory */ 667 /* load the l2 table in memory */
640 668
641 l2_offset &= ~QCOW_OFLAG_COPIED; 669 l2_offset &= ~QCOW_OFLAG_COPIED;
642 l2_table = l2_load(bs, l2_offset); 670 l2_table = l2_load(bs, l2_offset);
643 if (l2_table == NULL) 671 if (l2_table == NULL)
644 - return 0; 672 + goto out;
645 673
646 /* find the cluster offset for the given disk offset */ 674 /* find the cluster offset for the given disk offset */
647 675
648 l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); 676 l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
649 cluster_offset = be64_to_cpu(l2_table[l2_index]); 677 cluster_offset = be64_to_cpu(l2_table[l2_index]);
  678 + nb_available = s->cluster_sectors;
  679 + l2_index++;
  680 +
  681 + if (!cluster_offset) {
650 682
651 - return cluster_offset & ~QCOW_OFLAG_COPIED; 683 + /* how many empty clusters ? */
  684 +
  685 + while (nb_available < nb_needed && !l2_table[l2_index]) {
  686 + l2_index++;
  687 + nb_available += s->cluster_sectors;
  688 + }
  689 + } else {
  690 +
  691 + /* how many allocated clusters ? */
  692 +
  693 + cluster_offset &= ~QCOW_OFLAG_COPIED;
  694 + while (nb_available < nb_needed) {
  695 + next = be64_to_cpu(l2_table[l2_index]) & ~QCOW_OFLAG_COPIED;
  696 + if (next != cluster_offset + (nb_available << 9))
  697 + break;
  698 + l2_index++;
  699 + nb_available += s->cluster_sectors;
  700 + }
  701 + }
  702 +
  703 +out:
  704 + if (nb_available > nb_needed)
  705 + nb_available = nb_needed;
  706 +
  707 + *num = nb_available - index_in_cluster;
  708 +
  709 + return cluster_offset;
652 } 710 }
653 711
654 /* 712 /*
@@ -659,13 +717,10 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, uint64_t offset) @@ -659,13 +717,10 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, uint64_t offset)
659 */ 717 */
660 718
661 static void free_any_clusters(BlockDriverState *bs, 719 static void free_any_clusters(BlockDriverState *bs,
662 - uint64_t cluster_offset) 720 + uint64_t cluster_offset, int nb_clusters)
663 { 721 {
664 BDRVQcowState *s = bs->opaque; 722 BDRVQcowState *s = bs->opaque;
665 723
666 - if (cluster_offset == 0)  
667 - return;  
668 -  
669 /* free the cluster */ 724 /* free the cluster */
670 725
671 if (cluster_offset & QCOW_OFLAG_COMPRESSED) { 726 if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
@@ -677,7 +732,9 @@ static void free_any_clusters(BlockDriverState *bs, @@ -677,7 +732,9 @@ static void free_any_clusters(BlockDriverState *bs,
677 return; 732 return;
678 } 733 }
679 734
680 - free_clusters(bs, cluster_offset, s->cluster_size); 735 + free_clusters(bs, cluster_offset, nb_clusters << s->cluster_bits);
  736 +
  737 + return;
681 } 738 }
682 739
683 /* 740 /*
@@ -768,7 +825,8 @@ static uint64_t alloc_compressed_cluster_offset(BlockDriverState *bs, @@ -768,7 +825,8 @@ static uint64_t alloc_compressed_cluster_offset(BlockDriverState *bs,
768 if (cluster_offset & QCOW_OFLAG_COPIED) 825 if (cluster_offset & QCOW_OFLAG_COPIED)
769 return cluster_offset & ~QCOW_OFLAG_COPIED; 826 return cluster_offset & ~QCOW_OFLAG_COPIED;
770 827
771 - free_any_clusters(bs, cluster_offset); 828 + if (cluster_offset)
  829 + free_any_clusters(bs, cluster_offset, 1);
772 830
773 cluster_offset = alloc_bytes(bs, compressed_size); 831 cluster_offset = alloc_bytes(bs, compressed_size);
774 nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) - 832 nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
@@ -806,68 +864,136 @@ static uint64_t alloc_compressed_cluster_offset(BlockDriverState *bs, @@ -806,68 +864,136 @@ static uint64_t alloc_compressed_cluster_offset(BlockDriverState *bs,
806 864
807 static uint64_t alloc_cluster_offset(BlockDriverState *bs, 865 static uint64_t alloc_cluster_offset(BlockDriverState *bs,
808 uint64_t offset, 866 uint64_t offset,
809 - int n_start, int n_end) 867 + int n_start, int n_end,
  868 + int *num)
810 { 869 {
811 BDRVQcowState *s = bs->opaque; 870 BDRVQcowState *s = bs->opaque;
812 int l2_index, ret; 871 int l2_index, ret;
813 uint64_t l2_offset, *l2_table, cluster_offset; 872 uint64_t l2_offset, *l2_table, cluster_offset;
  873 + int nb_available, nb_clusters, i;
  874 + uint64_t start_sect, current;
814 875
815 ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index); 876 ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
816 if (ret == 0) 877 if (ret == 0)
817 return 0; 878 return 0;
818 879
  880 + nb_clusters = ((n_end << 9) + s->cluster_size - 1) >>
  881 + s->cluster_bits;
  882 + if (nb_clusters > s->l2_size - l2_index)
  883 + nb_clusters = s->l2_size - l2_index;
  884 +
819 cluster_offset = be64_to_cpu(l2_table[l2_index]); 885 cluster_offset = be64_to_cpu(l2_table[l2_index]);
820 - if (cluster_offset & QCOW_OFLAG_COPIED)  
821 - return cluster_offset & ~QCOW_OFLAG_COPIED;  
822 886
823 - free_any_clusters(bs, cluster_offset); 887 + /* We keep all QCOW_OFLAG_COPIED clusters */
  888 +
  889 + if (cluster_offset & QCOW_OFLAG_COPIED) {
  890 +
  891 + for (i = 1; i < nb_clusters; i++) {
  892 + current = be64_to_cpu(l2_table[l2_index + i]);
  893 + if (cluster_offset + (i << s->cluster_bits) != current)
  894 + break;
  895 + }
  896 + nb_clusters = i;
  897 +
  898 + nb_available = nb_clusters << (s->cluster_bits - 9);
  899 + if (nb_available > n_end)
  900 + nb_available = n_end;
  901 +
  902 + cluster_offset &= ~QCOW_OFLAG_COPIED;
  903 +
  904 + goto out;
  905 + }
  906 +
  907 + /* for the moment, multiple compressed clusters are not managed */
  908 +
  909 + if (cluster_offset & QCOW_OFLAG_COMPRESSED)
  910 + nb_clusters = 1;
  911 +
  912 + /* how many empty or how many to free ? */
  913 +
  914 + if (!cluster_offset) {
  915 +
  916 + /* how many free clusters ? */
  917 +
  918 + i = 1;
  919 + while (i < nb_clusters &&
  920 + l2_table[l2_index + i] == 0) {
  921 + i++;
  922 + }
  923 + nb_clusters = i;
  924 +
  925 + } else {
  926 +
  927 + /* how many contiguous clusters ? */
  928 +
  929 + for (i = 1; i < nb_clusters; i++) {
  930 + current = be64_to_cpu(l2_table[l2_index + i]);
  931 + if (cluster_offset + (i << s->cluster_bits) != current)
  932 + break;
  933 + }
  934 + nb_clusters = i;
  935 +
  936 + free_any_clusters(bs, cluster_offset, i);
  937 + }
824 938
825 /* allocate a new cluster */ 939 /* allocate a new cluster */
826 940
827 - cluster_offset = alloc_clusters(bs, s->cluster_size); 941 + cluster_offset = alloc_clusters(bs, nb_clusters * s->cluster_size);
828 942
829 /* we must initialize the cluster content which won't be 943 /* we must initialize the cluster content which won't be
830 written */ 944 written */
831 945
832 - if ((n_end - n_start) < s->cluster_sectors) {  
833 - uint64_t start_sect; 946 + nb_available = nb_clusters << (s->cluster_bits - 9);
  947 + if (nb_available > n_end)
  948 + nb_available = n_end;
834 949
835 - start_sect = (offset & ~(s->cluster_size - 1)) >> 9;  
836 - ret = copy_sectors(bs, start_sect,  
837 - cluster_offset, 0, n_start); 950 + /* copy content of unmodified sectors */
  951 +
  952 + start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
  953 + if (n_start) {
  954 + ret = copy_sectors(bs, start_sect, cluster_offset, 0, n_start);
838 if (ret < 0) 955 if (ret < 0)
839 return 0; 956 return 0;
840 - ret = copy_sectors(bs, start_sect,  
841 - cluster_offset, n_end, s->cluster_sectors); 957 + }
  958 +
  959 + if (nb_available & (s->cluster_sectors - 1)) {
  960 + uint64_t end = nb_available & ~(uint64_t)(s->cluster_sectors - 1);
  961 + ret = copy_sectors(bs, start_sect + end,
  962 + cluster_offset + (end << 9),
  963 + nb_available - end,
  964 + s->cluster_sectors);
842 if (ret < 0) 965 if (ret < 0)
843 return 0; 966 return 0;
844 } 967 }
845 968
846 /* update L2 table */ 969 /* update L2 table */
847 970
848 - l2_table[l2_index] = cpu_to_be64(cluster_offset | QCOW_OFLAG_COPIED); 971 + for (i = 0; i < nb_clusters; i++)
  972 + l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
  973 + (i << s->cluster_bits)) |
  974 + QCOW_OFLAG_COPIED);
  975 +
849 if (bdrv_pwrite(s->hd, 976 if (bdrv_pwrite(s->hd,
850 l2_offset + l2_index * sizeof(uint64_t), 977 l2_offset + l2_index * sizeof(uint64_t),
851 l2_table + l2_index, 978 l2_table + l2_index,
852 - sizeof(uint64_t)) != sizeof(uint64_t)) 979 + nb_clusters * sizeof(uint64_t)) !=
  980 + nb_clusters * sizeof(uint64_t))
853 return 0; 981 return 0;
854 982
  983 +out:
  984 + *num = nb_available - n_start;
  985 +
855 return cluster_offset; 986 return cluster_offset;
856 } 987 }
857 988
858 static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num, 989 static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
859 int nb_sectors, int *pnum) 990 int nb_sectors, int *pnum)
860 { 991 {
861 - BDRVQcowState *s = bs->opaque;  
862 - int index_in_cluster, n;  
863 uint64_t cluster_offset; 992 uint64_t cluster_offset;
864 993
865 - cluster_offset = get_cluster_offset(bs, sector_num << 9);  
866 - index_in_cluster = sector_num & (s->cluster_sectors - 1);  
867 - n = s->cluster_sectors - index_in_cluster;  
868 - if (n > nb_sectors)  
869 - n = nb_sectors;  
870 - *pnum = n; 994 + *pnum = nb_sectors;
  995 + cluster_offset = get_cluster_offset(bs, sector_num << 9, pnum);
  996 +
871 return (cluster_offset != 0); 997 return (cluster_offset != 0);
872 } 998 }
873 999
@@ -944,11 +1070,9 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num, @@ -944,11 +1070,9 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
944 uint64_t cluster_offset; 1070 uint64_t cluster_offset;
945 1071
946 while (nb_sectors > 0) { 1072 while (nb_sectors > 0) {
947 - cluster_offset = get_cluster_offset(bs, sector_num << 9); 1073 + n = nb_sectors;
  1074 + cluster_offset = get_cluster_offset(bs, sector_num << 9, &n);
948 index_in_cluster = sector_num & (s->cluster_sectors - 1); 1075 index_in_cluster = sector_num & (s->cluster_sectors - 1);
949 - n = s->cluster_sectors - index_in_cluster;  
950 - if (n > nb_sectors)  
951 - n = nb_sectors;  
952 if (!cluster_offset) { 1076 if (!cluster_offset) {
953 if (bs->backing_hd) { 1077 if (bs->backing_hd) {
954 /* read from the base image */ 1078 /* read from the base image */
@@ -987,15 +1111,17 @@ static int qcow_write(BlockDriverState *bs, int64_t sector_num, @@ -987,15 +1111,17 @@ static int qcow_write(BlockDriverState *bs, int64_t sector_num,
987 BDRVQcowState *s = bs->opaque; 1111 BDRVQcowState *s = bs->opaque;
988 int ret, index_in_cluster, n; 1112 int ret, index_in_cluster, n;
989 uint64_t cluster_offset; 1113 uint64_t cluster_offset;
  1114 + int n_end;
990 1115
991 while (nb_sectors > 0) { 1116 while (nb_sectors > 0) {
992 index_in_cluster = sector_num & (s->cluster_sectors - 1); 1117 index_in_cluster = sector_num & (s->cluster_sectors - 1);
993 - n = s->cluster_sectors - index_in_cluster;  
994 - if (n > nb_sectors)  
995 - n = nb_sectors; 1118 + n_end = index_in_cluster + nb_sectors;
  1119 + if (s->crypt_method &&
  1120 + n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
  1121 + n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
996 cluster_offset = alloc_cluster_offset(bs, sector_num << 9, 1122 cluster_offset = alloc_cluster_offset(bs, sector_num << 9,
997 index_in_cluster, 1123 index_in_cluster,
998 - index_in_cluster + n); 1124 + n_end, &n);
999 if (!cluster_offset) 1125 if (!cluster_offset)
1000 return -1; 1126 return -1;
1001 if (s->crypt_method) { 1127 if (s->crypt_method) {
@@ -1068,11 +1194,9 @@ static void qcow_aio_read_cb(void *opaque, int ret) @@ -1068,11 +1194,9 @@ static void qcow_aio_read_cb(void *opaque, int ret)
1068 } 1194 }
1069 1195
1070 /* prepare next AIO request */ 1196 /* prepare next AIO request */
1071 - acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9); 1197 + acb->n = acb->nb_sectors;
  1198 + acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, &acb->n);
1072 index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); 1199 index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
1073 - acb->n = s->cluster_sectors - index_in_cluster;  
1074 - if (acb->n > acb->nb_sectors)  
1075 - acb->n = acb->nb_sectors;  
1076 1200
1077 if (!acb->cluster_offset) { 1201 if (!acb->cluster_offset) {
1078 if (bs->backing_hd) { 1202 if (bs->backing_hd) {
@@ -1152,6 +1276,7 @@ static void qcow_aio_write_cb(void *opaque, int ret) @@ -1152,6 +1276,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
1152 int index_in_cluster; 1276 int index_in_cluster;
1153 uint64_t cluster_offset; 1277 uint64_t cluster_offset;
1154 const uint8_t *src_buf; 1278 const uint8_t *src_buf;
  1279 + int n_end;
1155 1280
1156 acb->hd_aiocb = NULL; 1281 acb->hd_aiocb = NULL;
1157 1282
@@ -1174,19 +1299,22 @@ static void qcow_aio_write_cb(void *opaque, int ret) @@ -1174,19 +1299,22 @@ static void qcow_aio_write_cb(void *opaque, int ret)
1174 } 1299 }
1175 1300
1176 index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); 1301 index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
1177 - acb->n = s->cluster_sectors - index_in_cluster;  
1178 - if (acb->n > acb->nb_sectors)  
1179 - acb->n = acb->nb_sectors; 1302 + n_end = index_in_cluster + acb->nb_sectors;
  1303 + if (s->crypt_method &&
  1304 + n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
  1305 + n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
  1306 +
1180 cluster_offset = alloc_cluster_offset(bs, acb->sector_num << 9, 1307 cluster_offset = alloc_cluster_offset(bs, acb->sector_num << 9,
1181 index_in_cluster, 1308 index_in_cluster,
1182 - index_in_cluster + acb->n); 1309 + n_end, &acb->n);
1183 if (!cluster_offset || (cluster_offset & 511) != 0) { 1310 if (!cluster_offset || (cluster_offset & 511) != 0) {
1184 ret = -EIO; 1311 ret = -EIO;
1185 goto fail; 1312 goto fail;
1186 } 1313 }
1187 if (s->crypt_method) { 1314 if (s->crypt_method) {
1188 if (!acb->cluster_data) { 1315 if (!acb->cluster_data) {
1189 - acb->cluster_data = qemu_mallocz(s->cluster_size); 1316 + acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
  1317 + s->cluster_size);
1190 if (!acb->cluster_data) { 1318 if (!acb->cluster_data) {
1191 ret = -ENOMEM; 1319 ret = -ENOMEM;
1192 goto fail; 1320 goto fail;