Commit 6db6c63826a4a2c06cb02bec2bfce3f506eacda8

Authored by aliguori
1 parent 643e5399

Cleanup {alloc|get}_cluster_offset() (Gleb Natapov)

Move duplicated code into helper functions.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5860 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 73 additions and 89 deletions
block-qcow2.c
@@ -601,6 +601,34 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index) @@ -601,6 +601,34 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)
601 return l2_table; 601 return l2_table;
602 } 602 }
603 603
  604 +static int size_to_clusters(BDRVQcowState *s, int64_t size)
  605 +{
  606 + return (size + (s->cluster_size - 1)) >> s->cluster_bits;
  607 +}
  608 +
  609 +static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
  610 + uint64_t *l2_table, uint64_t mask)
  611 +{
  612 + int i;
  613 + uint64_t offset = be64_to_cpu(l2_table[0]) & ~mask;
  614 +
  615 + for (i = 0; i < nb_clusters; i++)
  616 + if (offset + i * cluster_size != (be64_to_cpu(l2_table[i]) & ~mask))
  617 + break;
  618 +
  619 + return i;
  620 +}
  621 +
  622 +static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table)
  623 +{
  624 + int i = 0;
  625 +
  626 + while(nb_clusters-- && l2_table[i] == 0)
  627 + i++;
  628 +
  629 + return i;
  630 +}
  631 +
604 /* 632 /*
605 * get_cluster_offset 633 * get_cluster_offset
606 * 634 *
@@ -622,9 +650,9 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, @@ -622,9 +650,9 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
622 { 650 {
623 BDRVQcowState *s = bs->opaque; 651 BDRVQcowState *s = bs->opaque;
624 int l1_index, l2_index; 652 int l1_index, l2_index;
625 - uint64_t l2_offset, *l2_table, cluster_offset, next;  
626 - int l1_bits;  
627 - int index_in_cluster, nb_available, nb_needed; 653 + uint64_t l2_offset, *l2_table, cluster_offset;
  654 + int l1_bits, c;
  655 + int index_in_cluster, nb_available, nb_needed, nb_clusters;
628 656
629 index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1); 657 index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
630 nb_needed = *num + index_in_cluster; 658 nb_needed = *num + index_in_cluster;
@@ -632,7 +660,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, @@ -632,7 +660,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
632 l1_bits = s->l2_bits + s->cluster_bits; 660 l1_bits = s->l2_bits + s->cluster_bits;
633 661
634 /* compute how many bytes there are between the offset and 662 /* compute how many bytes there are between the offset and
635 - * and the end of the l1 entry 663 + * the end of the l1 entry
636 */ 664 */
637 665
638 nb_available = (1 << l1_bits) - (offset & ((1 << l1_bits) - 1)); 666 nb_available = (1 << l1_bits) - (offset & ((1 << l1_bits) - 1));
@@ -667,38 +695,25 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, @@ -667,38 +695,25 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
667 695
668 l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); 696 l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
669 cluster_offset = be64_to_cpu(l2_table[l2_index]); 697 cluster_offset = be64_to_cpu(l2_table[l2_index]);
670 - nb_available = s->cluster_sectors;  
671 - l2_index++; 698 + nb_clusters = size_to_clusters(s, nb_needed << 9);
672 699
673 if (!cluster_offset) { 700 if (!cluster_offset) {
674 -  
675 - /* how many empty clusters ? */  
676 -  
677 - while (nb_available < nb_needed && !l2_table[l2_index]) {  
678 - l2_index++;  
679 - nb_available += s->cluster_sectors;  
680 - } 701 + /* how many empty clusters ? */
  702 + c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);
681 } else { 703 } else {
  704 + /* how many allocated clusters ? */
  705 + c = count_contiguous_clusters(nb_clusters, s->cluster_size,
  706 + &l2_table[l2_index], QCOW_OFLAG_COPIED);
  707 + }
682 708
683 - /* how many allocated clusters ? */  
684 -  
685 - cluster_offset &= ~QCOW_OFLAG_COPIED;  
686 - while (nb_available < nb_needed) {  
687 - next = be64_to_cpu(l2_table[l2_index]) & ~QCOW_OFLAG_COPIED;  
688 - if (next != cluster_offset + (nb_available << 9))  
689 - break;  
690 - l2_index++;  
691 - nb_available += s->cluster_sectors;  
692 - }  
693 - }  
694 - 709 + nb_available = (c * s->cluster_sectors);
695 out: 710 out:
696 if (nb_available > nb_needed) 711 if (nb_available > nb_needed)
697 nb_available = nb_needed; 712 nb_available = nb_needed;
698 713
699 *num = nb_available - index_in_cluster; 714 *num = nb_available - index_in_cluster;
700 715
701 - return cluster_offset; 716 + return cluster_offset & ~QCOW_OFLAG_COPIED;
702 } 717 }
703 718
704 /* 719 /*
@@ -862,15 +877,15 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs, @@ -862,15 +877,15 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs,
862 BDRVQcowState *s = bs->opaque; 877 BDRVQcowState *s = bs->opaque;
863 int l2_index, ret; 878 int l2_index, ret;
864 uint64_t l2_offset, *l2_table, cluster_offset; 879 uint64_t l2_offset, *l2_table, cluster_offset;
865 - int nb_available, nb_clusters, i, j;  
866 - uint64_t start_sect, current; 880 + int nb_available, nb_clusters, i = 0;
  881 + uint64_t start_sect;
867 882
868 ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index); 883 ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
869 if (ret == 0) 884 if (ret == 0)
870 return 0; 885 return 0;
871 886
872 - nb_clusters = ((n_end << 9) + s->cluster_size - 1) >>  
873 - s->cluster_bits; 887 + nb_clusters = size_to_clusters(s, n_end << 9);
  888 +
874 if (nb_clusters > s->l2_size - l2_index) 889 if (nb_clusters > s->l2_size - l2_index)
875 nb_clusters = s->l2_size - l2_index; 890 nb_clusters = s->l2_size - l2_index;
876 891
@@ -879,13 +894,8 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs, @@ -879,13 +894,8 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs,
879 /* We keep all QCOW_OFLAG_COPIED clusters */ 894 /* We keep all QCOW_OFLAG_COPIED clusters */
880 895
881 if (cluster_offset & QCOW_OFLAG_COPIED) { 896 if (cluster_offset & QCOW_OFLAG_COPIED) {
882 -  
883 - for (i = 1; i < nb_clusters; i++) {  
884 - current = be64_to_cpu(l2_table[l2_index + i]);  
885 - if (cluster_offset + (i << s->cluster_bits) != current)  
886 - break;  
887 - }  
888 - nb_clusters = i; 897 + nb_clusters = count_contiguous_clusters(nb_clusters, s->cluster_size,
  898 + &l2_table[l2_index], 0);
889 899
890 nb_available = nb_clusters << (s->cluster_bits - 9); 900 nb_available = nb_clusters << (s->cluster_bits - 9);
891 if (nb_available > n_end) 901 if (nb_available > n_end)
@@ -903,46 +913,27 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs, @@ -903,46 +913,27 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs,
903 913
904 /* how many available clusters ? */ 914 /* how many available clusters ? */
905 915
906 - i = 0;  
907 while (i < nb_clusters) { 916 while (i < nb_clusters) {
  917 + int j;
  918 + i += count_contiguous_free_clusters(nb_clusters - i,
  919 + &l2_table[l2_index + i]);
908 920
909 - i++;  
910 -  
911 - if (!cluster_offset) {  
912 -  
913 - /* how many free clusters ? */  
914 -  
915 - while (i < nb_clusters) {  
916 - cluster_offset = be64_to_cpu(l2_table[l2_index + i]);  
917 - if (cluster_offset != 0)  
918 - break;  
919 - i++;  
920 - } 921 + cluster_offset = be64_to_cpu(l2_table[l2_index + i]);
921 922
922 - if ((cluster_offset & QCOW_OFLAG_COPIED) || 923 + if ((cluster_offset & QCOW_OFLAG_COPIED) ||
923 (cluster_offset & QCOW_OFLAG_COMPRESSED)) 924 (cluster_offset & QCOW_OFLAG_COMPRESSED))
924 - break;  
925 -  
926 - } else { 925 + break;
927 926
928 - /* how many contiguous clusters ? */ 927 + j = count_contiguous_clusters(nb_clusters - i, s->cluster_size,
  928 + &l2_table[l2_index + i], 0);
929 929
930 - j = 1;  
931 - current = 0;  
932 - while (i < nb_clusters) {  
933 - current = be64_to_cpu(l2_table[l2_index + i]);  
934 - if (cluster_offset + (j << s->cluster_bits) != current)  
935 - break; 930 + if (j)
  931 + free_any_clusters(bs, cluster_offset, j);
936 932
937 - i++;  
938 - j++;  
939 - } 933 + i += j;
940 934
941 - free_any_clusters(bs, cluster_offset, j);  
942 - if (current)  
943 - break;  
944 - cluster_offset = current;  
945 - } 935 + if(be64_to_cpu(l2_table[l2_index + i]))
  936 + break;
946 } 937 }
947 nb_clusters = i; 938 nb_clusters = i;
948 939
@@ -2194,26 +2185,19 @@ static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size) @@ -2194,26 +2185,19 @@ static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
2194 BDRVQcowState *s = bs->opaque; 2185 BDRVQcowState *s = bs->opaque;
2195 int i, nb_clusters; 2186 int i, nb_clusters;
2196 2187
2197 - nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;  
2198 - for(;;) {  
2199 - if (get_refcount(bs, s->free_cluster_index) == 0) {  
2200 - s->free_cluster_index++;  
2201 - for(i = 1; i < nb_clusters; i++) {  
2202 - if (get_refcount(bs, s->free_cluster_index) != 0)  
2203 - goto not_found;  
2204 - s->free_cluster_index++;  
2205 - } 2188 + nb_clusters = size_to_clusters(s, size);
  2189 +retry:
  2190 + for(i = 0; i < nb_clusters; i++) {
  2191 + int64_t i = s->free_cluster_index++;
  2192 + if (get_refcount(bs, i) != 0)
  2193 + goto retry;
  2194 + }
2206 #ifdef DEBUG_ALLOC2 2195 #ifdef DEBUG_ALLOC2
2207 - printf("alloc_clusters: size=%lld -> %lld\n",  
2208 - size,  
2209 - (s->free_cluster_index - nb_clusters) << s->cluster_bits); 2196 + printf("alloc_clusters: size=%lld -> %lld\n",
  2197 + size,
  2198 + (s->free_cluster_index - nb_clusters) << s->cluster_bits);
2210 #endif 2199 #endif
2211 - return (s->free_cluster_index - nb_clusters) << s->cluster_bits;  
2212 - } else {  
2213 - not_found:  
2214 - s->free_cluster_index++;  
2215 - }  
2216 - } 2200 + return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
2217 } 2201 }
2218 2202
2219 static int64_t alloc_clusters(BlockDriverState *bs, int64_t size) 2203 static int64_t alloc_clusters(BlockDriverState *bs, int64_t size)
@@ -2548,7 +2532,7 @@ static void check_refcounts(BlockDriverState *bs) @@ -2548,7 +2532,7 @@ static void check_refcounts(BlockDriverState *bs)
2548 uint16_t *refcount_table; 2532 uint16_t *refcount_table;
2549 2533
2550 size = bdrv_getlength(s->hd); 2534 size = bdrv_getlength(s->hd);
2551 - nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits; 2535 + nb_clusters = size_to_clusters(s, size);
2552 refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t)); 2536 refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t));
2553 2537
2554 /* header */ 2538 /* header */
@@ -2600,7 +2584,7 @@ static void dump_refcounts(BlockDriverState *bs) @@ -2600,7 +2584,7 @@ static void dump_refcounts(BlockDriverState *bs)
2600 int refcount; 2584 int refcount;
2601 2585
2602 size = bdrv_getlength(s->hd); 2586 size = bdrv_getlength(s->hd);
2603 - nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits; 2587 + nb_clusters = size_to_clusters(s, size);
2604 for(k = 0; k < nb_clusters;) { 2588 for(k = 0; k < nb_clusters;) {
2605 k1 = k; 2589 k1 = k;
2606 refcount = get_refcount(bs, k); 2590 refcount = get_refcount(bs, k);