Commit bc352085d2c82ef7bef37452b56fdafb148fe1f4

Authored by aliguori
1 parent 768706a5

qcow2: Try to aggregate free clusters and freed clusters (Laurent Vivier)

In alloc_cluster_offset(), try to aggregate free clusters and freed clusters.

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@5008 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 36 additions and 18 deletions
block-qcow2.c
@@ -870,7 +870,7 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs, @@ -870,7 +870,7 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs,
870 BDRVQcowState *s = bs->opaque; 870 BDRVQcowState *s = bs->opaque;
871 int l2_index, ret; 871 int l2_index, ret;
872 uint64_t l2_offset, *l2_table, cluster_offset; 872 uint64_t l2_offset, *l2_table, cluster_offset;
873 - int nb_available, nb_clusters, i; 873 + int nb_available, nb_clusters, i, j;
874 uint64_t start_sect, current; 874 uint64_t start_sect, current;
875 875
876 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);
@@ -909,32 +909,50 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs, @@ -909,32 +909,50 @@ static uint64_t alloc_cluster_offset(BlockDriverState *bs,
909 if (cluster_offset & QCOW_OFLAG_COMPRESSED) 909 if (cluster_offset & QCOW_OFLAG_COMPRESSED)
910 nb_clusters = 1; 910 nb_clusters = 1;
911 911
912 - /* how many empty or how many to free ? */ 912 + /* how many available clusters ? */
913 913
914 - if (!cluster_offset) { 914 + i = 0;
  915 + while (i < nb_clusters) {
915 916
916 - /* how many free clusters ? */ 917 + i++;
917 918
918 - i = 1;  
919 - while (i < nb_clusters &&  
920 - l2_table[l2_index + i] == 0) {  
921 - i++;  
922 - }  
923 - nb_clusters = i; 919 + if (!cluster_offset) {
924 920
925 - } else { 921 + /* how many free clusters ? */
926 922
927 - /* how many contiguous clusters ? */ 923 + while (i < nb_clusters) {
  924 + cluster_offset = l2_table[l2_index + i];
  925 + if (cluster_offset != 0)
  926 + break;
  927 + i++;
  928 + }
928 929
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) 930 + if ((cluster_offset & QCOW_OFLAG_COPIED) ||
  931 + (cluster_offset & QCOW_OFLAG_COMPRESSED))
932 break; 932 break;
933 - }  
934 - nb_clusters = i;  
935 933
936 - free_any_clusters(bs, cluster_offset, i); 934 + } else {
  935 +
  936 + /* how many contiguous clusters ? */
  937 +
  938 + j = 1;
  939 + current = 0;
  940 + while (i < nb_clusters) {
  941 + current = be64_to_cpu(l2_table[l2_index + i]);
  942 + if (cluster_offset + (j << s->cluster_bits) != current)
  943 + break;
  944 +
  945 + i++;
  946 + j++;
  947 + }
  948 +
  949 + free_any_clusters(bs, cluster_offset, j);
  950 + if (current)
  951 + break;
  952 + cluster_offset = current;
  953 + }
937 } 954 }
  955 + nb_clusters = i;
938 956
939 /* allocate a new cluster */ 957 /* allocate a new cluster */
940 958