diff mbox

[1/2] Fix error message about compressed clusters with OFLAG_COPIED

Message ID 0f687957feb72e80c740403191a47e607c2463fe.1523376013.git.berto@igalia.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alberto Garcia April 10, 2018, 4:05 p.m. UTC
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 <berto@igalia.com>
---
 block/qcow2-refcount.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Eric Blake April 10, 2018, 4:18 p.m. UTC | #1
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 <berto@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,
>          case QCOW2_CLUSTER_COMPRESSED:
>              /* 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 <eblake@redhat.com>
Alberto Garcia April 10, 2018, 4:45 p.m. UTC | #2
On Tue 10 Apr 2018 06:18:28 PM CEST, Eric Blake wrote:
> 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 <berto@igalia.com>
>> ---
>>  block/qcow2-refcount.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>> 
>
> Do we have iotests coverage of this?

I have one half-written, but I was thinking to put it in 214, so I'll
wait until Max's patch is merged.

Berto
diff mbox

Patch

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,
         case QCOW2_CLUSTER_COMPRESSED:
             /* 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;
                 res->corruptions++;
             }