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 | 870 | BDRVQcowState *s = bs->opaque; |
871 | 871 | int l2_index, ret; |
872 | 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 | 874 | uint64_t start_sect, current; |
875 | 875 | |
876 | 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 | 909 | if (cluster_offset & QCOW_OFLAG_COMPRESSED) |
910 | 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 | 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 | 957 | /* allocate a new cluster */ |
940 | 958 | ... | ... |