From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48271) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuP7q-0002eB-Em for qemu-devel@nongnu.org; Thu, 05 Nov 2015 13:19:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZuP7p-00069e-Hi for qemu-devel@nongnu.org; Thu, 05 Nov 2015 13:19:06 -0500 From: Kevin Wolf Date: Thu, 5 Nov 2015 19:18:05 +0100 Message-Id: <1446747485-6562-38-git-send-email-kwolf@redhat.com> In-Reply-To: <1446747485-6562-1-git-send-email-kwolf@redhat.com> References: <1446747485-6562-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PULL 37/37] qcow2: Fix qcow2_get_cluster_offset() for zero clusters List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org 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 Message-id: 1446657384-5907-1-git-send-email-kwolf@redhat.com Signed-off-by: Max Reitz --- block/qcow2-cluster.c | 15 +++++++++------ 1 file 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: -- 1.8.3.1