qcow2: Simplify count_cow_clusters

count_cow_clusters() tries to reuse existing functions, and all it
achieves is to make things much more complicated than they really are:
Everything needs COW, unless it's a normal cluster with refcount 1.

This patch implements the obvious way of doing this, and by using
qcow2_get_cluster_type() it gets rid of all flag magic.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Kevin Wolf 2012-03-27 13:17:22 +02:00
parent c7a4c37a0f
commit 143550a83e

View File

@ -706,30 +706,27 @@ err:
static int count_cow_clusters(BDRVQcowState *s, int nb_clusters, static int count_cow_clusters(BDRVQcowState *s, int nb_clusters,
uint64_t *l2_table, int l2_index) uint64_t *l2_table, int l2_index)
{ {
int i = 0; int i;
uint64_t cluster_offset;
while (i < nb_clusters) { for (i = 0; i < nb_clusters; i++) {
i += count_contiguous_clusters(nb_clusters - i, s->cluster_size, uint64_t l2_entry = be64_to_cpu(l2_table[l2_index + i]);
&l2_table[l2_index], i, int cluster_type = qcow2_get_cluster_type(l2_entry);
QCOW_OFLAG_COPIED | QCOW_OFLAG_COMPRESSED);
if ((i >= nb_clusters) || be64_to_cpu(l2_table[l2_index + i])) { switch(cluster_type) {
break; case QCOW2_CLUSTER_NORMAL:
} if (l2_entry & QCOW_OFLAG_COPIED) {
goto out;
i += count_contiguous_free_clusters(nb_clusters - i, }
&l2_table[l2_index + i]);
if (i >= nb_clusters) {
break;
}
cluster_offset = be64_to_cpu(l2_table[l2_index + i]);
if ((cluster_offset & QCOW_OFLAG_COPIED) ||
(cluster_offset & QCOW_OFLAG_COMPRESSED))
break; break;
case QCOW2_CLUSTER_UNALLOCATED:
case QCOW2_CLUSTER_COMPRESSED:
break;
default:
abort();
}
} }
out:
assert(i <= nb_clusters); assert(i <= nb_clusters);
return i; return i;
} }