Commit bc352085d2c82ef7bef37452b56fdafb148fe1f4
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 |