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 |