All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: "Benoît Canet" <benoit.canet@irqsave.net>
Cc: Kevin Wolf <kwolf@redhat.com>,
	qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 3/8] qcow2: Fix refcount blocks beyond image end
Date: Fri, 15 Aug 2014 14:36:10 +0200	[thread overview]
Message-ID: <53EDFEBA.10601@redhat.com> (raw)
In-Reply-To: <20140814121120.GH2009@irqsave.net>

On 14.08.2014 14:11, Benoît Canet wrote:
> The Wednesday 13 Aug 2014 à 23:01:45 (+0200), Max Reitz wrote :
>> If the qcow2 check function detects a refcount block located beyond the
>> image end, grow the image appropriately. This cannot break anything and
>> is the logical fix for such a case.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>>   block/qcow2-refcount.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
>>   1 file changed, 46 insertions(+), 4 deletions(-)
>>
>> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
>> index d1da8d5..a1d93e5 100644
>> --- a/block/qcow2-refcount.c
>> +++ b/block/qcow2-refcount.c
>> @@ -1504,7 +1504,8 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
>>                              int64_t *nb_clusters)
>>   {
>>       BDRVQcowState *s = bs->opaque;
>> -    int64_t i;
>> +    int64_t i, size;
>> +    int ret;
>>   
>>       for (i = 0; i < s->refcount_table_size; i++) {
>>           uint64_t offset, cluster;
>> @@ -1520,9 +1521,50 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
>>           }
>>   
>>           if (cluster >= *nb_clusters) {
>> -            fprintf(stderr, "ERROR refcount block %" PRId64
>> -                    " is outside image\n", i);
>> -            res->corruptions++;
>> +            fprintf(stderr, "%s refcount block %" PRId64 " is outside image\n",
>> +                    fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
>> +
>> +            if (fix & BDRV_FIX_ERRORS) {
>> +                int64_t old_nb_clusters = *nb_clusters;
>> +
>> +                ret = bdrv_truncate(bs->file, offset + s->cluster_size);
>> +                if (ret < 0) {
>> +                    goto resize_fail;
>> +                }
>> +                size = bdrv_getlength(bs->file);
>> +                if (size < 0) {
>> +                    ret = size;
>> +                    goto resize_fail;
>> +                }
>> +
>> +                *nb_clusters = size_to_clusters(s, size);
>> +                assert(*nb_clusters >= old_nb_clusters);
>> +
>> +                *refcount_table = g_try_realloc(*refcount_table,
>> +                        *nb_clusters * sizeof(uint16_t));
>> +                if (!*refcount_table) {
>> +                    res->check_errors++;
>> +                    return -ENOMEM;
> So you really want to make sure the code is not trying anything more
> by directly returning -ENOMEM and not doing goto resize_fail.
>
> This makes sense though.
>
>> +                }
>> +
>> +                memset(*refcount_table + old_nb_clusters, 0,
>> +                       (*nb_clusters - old_nb_clusters) * sizeof(uint16_t));
>> +
>> +                if (cluster >= *nb_clusters) {
>> +                    ret = -EINVAL;
>> +                    goto resize_fail;
>> +                }
>> +
>> +                res->corruptions_fixed++;
>> +                continue;
>> +
>> +resize_fail:
>> +                res->corruptions++;
>> +                fprintf(stderr, "ERROR could not resize image: %s\n",
>> +                        strerror(-ret));
> Isn't a "return ret;" missing here ?
> the code will fall in the continue statement without it.

And that it should. A corruption is reported to stderr, res->corruptions 
is incremented and that's it - just as it was without this patch. The 
only reason I see why we should completely abort here is because 
resizing the file should always work; if it doesn't, something may be 
completely wrong. But even that is no real reason to jump the shark; we 
can still continue with the check and if everything is indeed completely 
broken, we'll receive EIOs soon enough.

Perhaps I should add a *rebuild = true; here and in the else branch in 
the next patch, though.

Max

>> +            } else {
>> +                res->corruptions++;
>> +            }
>>               continue;
>>           }
>>   
>> -- 
>> 2.0.3
>>
>>

  reply	other threads:[~2014-08-15 12:36 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-13 21:01 [Qemu-devel] [PATCH 0/8] qcow2: Fix image repairing Max Reitz
2014-08-13 21:01 ` [Qemu-devel] [PATCH 1/8] qcow2: Factor out refcount accounting for check Max Reitz
2014-08-14 11:56   ` Benoît Canet
2014-08-13 21:01 ` [Qemu-devel] [PATCH 2/8] qcow2: Factor out refcount comparison " Max Reitz
2014-08-14 12:02   ` Benoît Canet
2014-08-15 12:31     ` Max Reitz
2014-08-15 13:47       ` Max Reitz
2014-08-13 21:01 ` [Qemu-devel] [PATCH 3/8] qcow2: Fix refcount blocks beyond image end Max Reitz
2014-08-14 12:11   ` Benoît Canet
2014-08-15 12:36     ` Max Reitz [this message]
2014-08-13 21:01 ` [Qemu-devel] [PATCH 4/8] qcow2: Do not perform potentially damaging repairs Max Reitz
2014-08-14 12:33   ` Benoît Canet
2014-08-15 12:42     ` Max Reitz
2014-08-13 21:01 ` [Qemu-devel] [PATCH 5/8] qcow2: Rebuild refcount structure during check Max Reitz
2014-08-14 12:58   ` Benoît Canet
2014-08-15 12:49     ` Max Reitz
2014-08-13 21:01 ` [Qemu-devel] [PATCH 6/8] qcow2: Clean up after refcount rebuild Max Reitz
2014-08-13 21:01 ` [Qemu-devel] [PATCH 7/8] iotests: Fix test outputs Max Reitz
2014-08-13 21:01 ` [Qemu-devel] [PATCH 8/8] iotests: Add test for potentially damaging repairs Max Reitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53EDFEBA.10601@redhat.com \
    --to=mreitz@redhat.com \
    --cc=benoit.canet@irqsave.net \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.