提交 a99dfb45 编写于 作者: K Kevin Wolf 提交者: Max Reitz

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: NKevin Wolf <kwolf@redhat.com>
Message-id: 1446657384-5907-1-git-send-email-kwolf@redhat.com
Signed-off-by: NMax Reitz <mreitz@redhat.com>
上级 342075fd
...@@ -312,7 +312,7 @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size, ...@@ -312,7 +312,7 @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size,
if (!offset) if (!offset)
return 0; 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++) { for (i = 0; i < nb_clusters; i++) {
uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask; 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, ...@@ -324,14 +324,16 @@ static int count_contiguous_clusters(int nb_clusters, int cluster_size,
return i; 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; int i;
for (i = 0; i < nb_clusters; i++) { for (i = 0; i < nb_clusters; i++) {
int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i])); int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i]));
if (type != QCOW2_CLUSTER_UNALLOCATED) { if (type != wanted_type) {
break; break;
} }
} }
...@@ -554,13 +556,14 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, ...@@ -554,13 +556,14 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
ret = -EIO; ret = -EIO;
goto fail; goto fail;
} }
c = count_contiguous_clusters(nb_clusters, s->cluster_size, c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index],
&l2_table[l2_index], QCOW_OFLAG_ZERO); QCOW2_CLUSTER_ZERO);
*cluster_offset = 0; *cluster_offset = 0;
break; break;
case QCOW2_CLUSTER_UNALLOCATED: case QCOW2_CLUSTER_UNALLOCATED:
/* how many empty clusters ? */ /* 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; *cluster_offset = 0;
break; break;
case QCOW2_CLUSTER_NORMAL: case QCOW2_CLUSTER_NORMAL:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册