diff options
author | Kevin Wolf <kwolf@redhat.com> | 2015-11-04 18:16:24 +0100 |
---|---|---|
committer | Max Reitz <mreitz@redhat.com> | 2015-11-11 16:55:29 +0100 |
commit | a99dfb45f26bface6830ee5465e57bcdbc53c6c8 (patch) | |
tree | e6d948e6c24c2e01fc0c1316b172e916328e6123 /block | |
parent | 342075fd0ec9dce87139d71a81e1dbbe5ab5d021 (diff) | |
download | qemu-a99dfb45f26bface6830ee5465e57bcdbc53c6c8.zip qemu-a99dfb45f26bface6830ee5465e57bcdbc53c6c8.tar.gz qemu-a99dfb45f26bface6830ee5465e57bcdbc53c6c8.tar.bz2 |
qcow2: Fix qcow2_get_cluster_offset() for zero clusters
When searching for contiguous zero clusters, we only need to check the
cluster type. Before this patch, an increasing offset (L2E_OFFSET_MASK)
was expected, so that the function never returned more than a single
zero cluster in practice. This patch fixes it to actually return as many
contiguous zero clusters as it can.
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1446657384-5907-1-git-send-email-kwolf@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/qcow2-cluster.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 67be0ce..24a60e2 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -312,7 +312,7 @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size, if (!offset) return 0; - assert(qcow2_get_cluster_type(first_entry) != QCOW2_CLUSTER_COMPRESSED); + assert(qcow2_get_cluster_type(first_entry) == QCOW2_CLUSTER_NORMAL); for (i = 0; i < nb_clusters; i++) { uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask; @@ -324,14 +324,16 @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size, return i; } -static int count_contiguous_free_clusters(int nb_clusters, uint64_t *l2_table) +static int count_contiguous_clusters_by_type(int nb_clusters, + uint64_t *l2_table, + int wanted_type) { int i; for (i = 0; i < nb_clusters; i++) { int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i])); - if (type != QCOW2_CLUSTER_UNALLOCATED) { + if (type != wanted_type) { break; } } @@ -554,13 +556,14 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, ret = -EIO; goto fail; } - c = count_contiguous_clusters(nb_clusters, s->cluster_size, - &l2_table[l2_index], QCOW_OFLAG_ZERO); + c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index], + QCOW2_CLUSTER_ZERO); *cluster_offset = 0; break; case QCOW2_CLUSTER_UNALLOCATED: /* how many empty clusters ? */ - c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]); + c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index], + QCOW2_CLUSTER_UNALLOCATED); *cluster_offset = 0; break; case QCOW2_CLUSTER_NORMAL: |