aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2-cluster.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2012-03-27 13:17:22 +0200
committerKevin Wolf <kwolf@redhat.com>2012-04-20 15:57:28 +0200
commit143550a83ef4eef86a847d00023d148e1f59f743 (patch)
tree2de0e606772707624172b10e83b85130280d8706 /block/qcow2-cluster.c
parentc7a4c37a0f768f7ad50f64414d578436019e1e96 (diff)
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>
Diffstat (limited to 'block/qcow2-cluster.c')
-rw-r--r--block/qcow2-cluster.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index d1602d4bdd..b8836ba009 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -706,30 +706,27 @@ err:
static int count_cow_clusters(BDRVQcowState *s, int nb_clusters,
uint64_t *l2_table, int l2_index)
{
- int i = 0;
- uint64_t cluster_offset;
+ int i;
- while (i < nb_clusters) {
- i += count_contiguous_clusters(nb_clusters - i, s->cluster_size,
- &l2_table[l2_index], i,
- QCOW_OFLAG_COPIED | QCOW_OFLAG_COMPRESSED);
- if ((i >= nb_clusters) || be64_to_cpu(l2_table[l2_index + i])) {
- break;
- }
+ for (i = 0; i < nb_clusters; i++) {
+ uint64_t l2_entry = be64_to_cpu(l2_table[l2_index + i]);
+ int cluster_type = qcow2_get_cluster_type(l2_entry);
- i += count_contiguous_free_clusters(nb_clusters - i,
- &l2_table[l2_index + i]);
- if (i >= nb_clusters) {
+ switch(cluster_type) {
+ case QCOW2_CLUSTER_NORMAL:
+ if (l2_entry & QCOW_OFLAG_COPIED) {
+ goto out;
+ }
break;
- }
-
- cluster_offset = be64_to_cpu(l2_table[l2_index + i]);
-
- if ((cluster_offset & QCOW_OFLAG_COPIED) ||
- (cluster_offset & QCOW_OFLAG_COMPRESSED))
+ case QCOW2_CLUSTER_UNALLOCATED:
+ case QCOW2_CLUSTER_COMPRESSED:
break;
+ default:
+ abort();
+ }
}
+out:
assert(i <= nb_clusters);
return i;
}