On 04/10/2018 11:05 AM, Alberto Garcia wrote:
> Compressed clusters are not supposed to have the COPIED bit set.
> "qemu-img check" detects that and prints an error message reporting
> the number of the affected host cluster. This doesn't make much sense
> because compressed clusters are not aligned to host clusters, so it
> would be better to report the offset instead. Plus, the calculation is
> wrong and it uses the raw L2 entry as if it was simply an offset.
> This patch fixes the error message and reports the offset of the
> compressed cluster.
> Signed-off-by: Alberto Garcia <be...@igalia.com>
> ---
>  block/qcow2-refcount.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Do we have iotests coverage of this?

Should the qcow2 spec be explicit that OFLAG_COPIED should never be set
on a compressed cluster? The current documentation for L2 table entry
mentions that bit 63 is '1' for a cluster with a refcount of exactly 1
if it is an L2 table reachable from the active L1 table, with no mention
of a restriction that it must not be set when bit 62 is set.  Or is it
feasible that although qemu itself (should) never set OFLAG_COPIED on a
compressed cluster, that some third-party tool could still validly set
the bit for a compressed cluster that happens to occupy a host cluster
with a refcount of exactly 1 (and where writing to that cluster could be
done by replacing the cluster in-place with uncompressed data, or by
again writing compressed data - compression is rather wasteful in that
sense as the tail of the host cluster is unused, and the only way to use
the tail of the cluster is with another compressed cluster at which
point the refcount is no longer 1).

> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> index 6b8b63514a..2dc23005b7 100644
> --- a/block/qcow2-refcount.c
> +++ b/block/qcow2-refcount.c
> @@ -1577,9 +1577,9 @@ static int check_refcounts_l2(BlockDriverState *bs, 
> BdrvCheckResult *res,
>              /* Compressed clusters don't have QCOW_OFLAG_COPIED */
>              if (l2_entry & QCOW_OFLAG_COPIED) {
> -                fprintf(stderr, "ERROR: cluster %" PRId64 ": "
> +                fprintf(stderr, "ERROR: coffset=0x%" PRIx64 ": "
>                      "copied flag must never be set for compressed "
> -                    "clusters\n", l2_entry >> s->cluster_bits);
> +                    "clusters\n", l2_entry & s->cluster_offset_mask);
>                  l2_entry &= ~QCOW_OFLAG_COPIED;

At any rate, regardless of the answers to my questions, the error
message cleanup makes sense.
Reviewed-by: Eric Blake <ebl...@redhat.com>

Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to