diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 770c5dbc83..aae52607eb 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1669,12 +1669,18 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, /* Correct offsets are cluster aligned */ if (offset_into_cluster(s, offset)) { + bool contains_data; res->corruptions++; - if (qcow2_get_cluster_type(bs, l2_entry) == - QCOW2_CLUSTER_ZERO_ALLOC) - { - fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero " + if (has_subclusters(s)) { + uint64_t l2_bitmap = get_l2_bitmap(s, l2_table, i); + contains_data = (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC); + } else { + contains_data = !(l2_entry & QCOW_OFLAG_ZERO); + } + + if (!contains_data) { + fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated " "cluster is not properly aligned; L2 entry " "corrupted.\n", fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", @@ -1686,7 +1692,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, int ign = active ? QCOW2_OL_ACTIVE_L2 : QCOW2_OL_INACTIVE_L2; - l2_entry = QCOW_OFLAG_ZERO; + l2_entry = has_subclusters(s) ? 0 : QCOW_OFLAG_ZERO; set_l2_entry(s, l2_table, i, l2_entry); ret = qcow2_pre_write_overlap_check(bs, ign, l2e_offset, l2_entry_size(s), false); diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index e574c38797..b2804a0d07 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -320,7 +320,7 @@ discard 65536/65536 bytes at offset 0 qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 unaligned (guest offset: 0); further corruption events will be suppressed write failed: Input/output error --- Repairing --- -Repairing offset=2a00: Preallocated zero cluster is not properly aligned; L2 entry corrupted. +Repairing offset=2a00: Preallocated cluster is not properly aligned; L2 entry corrupted. The following inconsistencies were found and repaired: 0 leaked clusters