[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 49/58] qcow2: Correctly report status of preallocated
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 49/58] qcow2: Correctly report status of preallocated zero clusters |
Date: |
Thu, 11 May 2017 16:32:52 +0200 |
From: Eric Blake <address@hidden>
We were throwing away the preallocation information associated with
zero clusters. But we should be matching the well-defined semantics
in bdrv_get_block_status(), where (BDRV_BLOCK_ZERO |
BDRV_BLOCK_OFFSET_VALID) informs the user which offset is reserved,
while still reminding the user that reading from that offset is
likely to read garbage.
count_contiguous_clusters_by_type() is now used only for unallocated
cluster runs, hence it gets renamed and tightened.
Making this change lets us see which portions of an image are zero
but preallocated, when using qemu-img map --output=json. The
--output=human side intentionally ignores all zero clusters, whether
or not they are preallocated.
The fact that there is no change to qemu-iotests './check -qcow2'
merely means that we aren't yet testing this aspect of qemu-img;
a later patch will add a test.
Signed-off-by: Eric Blake <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
Message-id: address@hidden
Signed-off-by: Max Reitz <address@hidden>
---
block/qcow2-cluster.c | 45 +++++++++++++++++++++++++++++++++++----------
1 file changed, 35 insertions(+), 10 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 335a505..f3bfce6 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -334,16 +334,23 @@ static int count_contiguous_clusters(int nb_clusters, int
cluster_size,
return i;
}
-static int count_contiguous_clusters_by_type(int nb_clusters,
- uint64_t *l2_table,
- int wanted_type)
+/*
+ * Checks how many consecutive unallocated clusters in a given L2
+ * table have the same cluster type.
+ */
+static int count_contiguous_clusters_unallocated(int nb_clusters,
+ uint64_t *l2_table,
+ int wanted_type)
{
int i;
+ assert(wanted_type == QCOW2_CLUSTER_ZERO ||
+ wanted_type == QCOW2_CLUSTER_UNALLOCATED);
for (i = 0; i < nb_clusters; i++) {
- int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i]));
+ uint64_t entry = be64_to_cpu(l2_table[i]);
+ int type = qcow2_get_cluster_type(entry);
- if (type != wanted_type) {
+ if (type != wanted_type || entry & L2E_OFFSET_MASK) {
break;
}
}
@@ -565,14 +572,32 @@ int qcow2_get_cluster_offset(BlockDriverState *bs,
uint64_t offset,
ret = -EIO;
goto fail;
}
- c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index],
- QCOW2_CLUSTER_ZERO);
- *cluster_offset = 0;
+ /* Distinguish between pure zero clusters and pre-allocated ones */
+ if (*cluster_offset & L2E_OFFSET_MASK) {
+ c = count_contiguous_clusters(nb_clusters, s->cluster_size,
+ &l2_table[l2_index],
QCOW_OFLAG_ZERO);
+ *cluster_offset &= L2E_OFFSET_MASK;
+ if (offset_into_cluster(s, *cluster_offset)) {
+ qcow2_signal_corruption(bs, true, -1, -1,
+ "Preallocated zero cluster offset %#"
+ PRIx64 " unaligned (L2 offset: %#"
+ PRIx64 ", L2 index: %#x)",
+ *cluster_offset, l2_offset, l2_index);
+ ret = -EIO;
+ goto fail;
+ }
+ } else {
+ c = count_contiguous_clusters_unallocated(nb_clusters,
+ &l2_table[l2_index],
+ QCOW2_CLUSTER_ZERO);
+ *cluster_offset = 0;
+ }
break;
case QCOW2_CLUSTER_UNALLOCATED:
/* how many empty clusters ? */
- c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index],
- QCOW2_CLUSTER_UNALLOCATED);
+ c = count_contiguous_clusters_unallocated(nb_clusters,
+ &l2_table[l2_index],
+ QCOW2_CLUSTER_UNALLOCATED);
*cluster_offset = 0;
break;
case QCOW2_CLUSTER_NORMAL:
--
1.8.3.1
- [Qemu-block] [PULL 39/58] qemu-io: Switch 'map' output to byte-based reporting, (continued)
- [Qemu-block] [PULL 39/58] qemu-io: Switch 'map' output to byte-based reporting, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 37/58] qemu-io: Improve alignment checks, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 41/58] blkdebug: Refactor error injection, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 42/58] blkdebug: Add pass-through write_zero and discard support, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 44/58] blkdebug: Add ability to override unmap geometries, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 43/58] blkdebug: Simplify override logic, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 47/58] qcow2: Use consistent switch indentation, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 46/58] qcow2: Nicer variable names in qcow2_update_snapshot_refcount(), Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 45/58] tests: Add coverage for recent block geometry fixes, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 48/58] block: Update comments on BDRV_BLOCK_* meanings, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 49/58] qcow2: Correctly report status of preallocated zero clusters,
Kevin Wolf <=
- [Qemu-block] [PULL 50/58] qcow2: Name typedef for cluster type, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 51/58] qcow2: Make distinction between zero cluster types obvious, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 52/58] qcow2: Optimize zero_single_l2() to minimize L2 churn, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 53/58] iotests: Improve _filter_qemu_img_map, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 54/58] iotests: Add test 179 to cover write zeroes with unmap, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 56/58] qcow2: Assert that cluster operations are aligned, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 57/58] qcow2: Discard/zero clusters by byte count, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 55/58] qcow2: Optimize write zero of unaligned tail cluster, Kevin Wolf, 2017/05/11
- [Qemu-block] [PULL 58/58] MAINTAINERS: Add qemu-progress to the block layer, Kevin Wolf, 2017/05/11
- Re: [Qemu-block] [PULL 00/58] Block layer patches, Stefan Hajnoczi, 2017/05/12