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 | ... | ... |