From: Max Reitz <mreitz@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-devel@nongnu.org, "Stefan Hajnoczi" <stefanha@redhat.com>,
"Benoît Canet" <benoit.canet@nodalink.com>
Subject: Re: [Qemu-devel] [PATCH v6 09/11] qcow2: Clean up after refcount rebuild
Date: Tue, 21 Oct 2014 17:17:29 +0200 [thread overview]
Message-ID: <54467909.8070504@redhat.com> (raw)
In-Reply-To: <20141021151134.GL4409@noname.redhat.com>
On 2014-10-21 at 17:11, Kevin Wolf wrote:
> Am 21.10.2014 um 16:55 hat Max Reitz geschrieben:
>> On 2014-10-21 at 12:16, Max Reitz wrote:
>>> On 2014-10-21 at 11:59, Kevin Wolf wrote:
>>>> Am 20.10.2014 um 16:35 hat Max Reitz geschrieben:
>>>>> Because the old refcount structure will be leaked after having rebuilt
>>>>> it, we need to recalculate the refcounts and run a leak-fixing
>>>>> operation
>>>>> afterwards (if leaks should be fixed at all).
>>>>>
>>>>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>>>>> Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>
>>>>> ---
>>>>> block/qcow2-refcount.c | 35 +++++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 35 insertions(+)
>>>>>
>>>>> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
>>>>> index 75e726b..3730be2 100644
>>>>> --- a/block/qcow2-refcount.c
>>>>> +++ b/block/qcow2-refcount.c
>>>>> @@ -1956,12 +1956,47 @@ int
>>>>> qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult
>>>>> *res,
>>>>> nb_clusters);
>>>>> if (rebuild && (fix & BDRV_FIX_ERRORS)) {
>>>>> + BdrvCheckResult old_res = *res;
>>>>> +
>>>>> fprintf(stderr, "Rebuilding refcount structure\n");
>>>>> ret = rebuild_refcount_structure(bs, res, &refcount_table,
>>>>> &nb_clusters);
>>>>> if (ret < 0) {
>>>>> goto fail;
>>>>> }
>>>>> +
>>>>> + res->corruptions = 0;
>>>>> + res->leaks = 0;
>>>>> +
>>>>> + /* Because the old reftable has been exchanged for a
>>>>> new one the
>>>>> + * references have to be recalculated */
>>>>> + rebuild = false;
>>>>> + memset(refcount_table, 0, nb_clusters * sizeof(uint16_t));
>>>>> + ret = calculate_refcounts(bs, res, 0, &rebuild,
>>>>> &refcount_table,
>>>>> + &nb_clusters);
>>>>> + if (ret < 0) {
>>>>> + goto fail;
>>>>> + }
>>>>> +
>>>>> + if (fix & BDRV_FIX_LEAKS) {
>>>>> + /* The old refcount structures are now leaked,
>>>>> fix it; the result
>>>>> + * can be ignored */
>>>>> + pre_compare_res = *res;
>>>> I would prefer using another local variable here. At the first sight
>>>> it's not quite clear which references to pre_compare_res correspond to
>>>> which state.
>>> Why not.
>>>
>>>>> + compare_refcounts(bs, res, BDRV_FIX_LEAKS, &rebuild,
>>>>> + &highest_cluster,
>>>>> refcount_table, nb_clusters);
>>>>> + if (rebuild) {
>>>>> + fprintf(stderr, "ERROR rebuilt refcount
>>>>> structure is still "
>>>>> + "broken\n");
>>>>> + }
>>>>> + *res = pre_compare_res;
>>>>> + }
>>>>> +
>>>>> + if (res->corruptions < old_res.corruptions) {
>>>>> + res->corruptions_fixed += old_res.corruptions -
>>>>> res->corruptions;
>>>>> + }
>>>>> + if (res->leaks < old_res.leaks) {
>>>>> + res->leaks_fixed += old_res.leaks - res->leaks;
>>>>> + }
>>>> For these numbers to be accurate, don't we need to run
>>>> compare_refcounts() unconditionally and only make BDRV_FIX_LEAKS
>>>> conditional?
>>> Actually, there is no difference, because at the point of this
>>> patch, you cannot use BDRV_FIX_ERRORS without BDRV_FIX_LEAKS. But
>>> it'd be more correct, right.
>> Wait, it would not be more correct. The result of the
>> compare_refcounts() call inside of the "if (fix & BDRV_FIX_LEAKS)"
>> conditional block is ignored, its only purpose is to fix leaks
>> resulting from rebuild_refcount_structure().
>>
>> So the question is whether we should discard the result of that
>> compare_refcounts() call. I think we should. Its sole purpose is to
>> fix leaks due to the rebuilt refcount structures, and qemu-img will
>> double check anyway.
> Right, the other leaks should have been fixed by rebuilding the refcount
> structures. So what you're saying is that we could do this:
>
> if (res->corruptions < old_res.corruptions) {
> res->corruptions_fixed += old_res.corruptions - res->corruptions;
> }
> assert(res->leaks == 0);
> res->leaks_fixed = old_res.leaks;
>
> If this weren't true, we'd ignore leaked clusters even with
> BDRV_FIX_LEAKS set.
Okay, so for obvious reasons this is not nice. Well, I don't know what
will be worse. Writing the code which takes the leak fix result into
account or having to review it. I think I'll just see how many new leaks
appeared due to the rebuild and how many of those could not be fixed,
and then add that result to res->leaks. That should work out without
being too complicated.
Max
next prev parent reply other threads:[~2014-10-21 15:17 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-20 14:35 [Qemu-devel] [PATCH v6 00/11] qcow2: Fix image repairing Max Reitz
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 01/11] qcow2: Calculate refcount block entry count Max Reitz
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 02/11] qcow2: Fix leaks in dirty images Max Reitz
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 03/11] qcow2: Split qcow2_check_refcounts() Max Reitz
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 04/11] qcow2: Pull check_refblocks() up Max Reitz
2014-10-20 15:07 ` Kevin Wolf
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 05/11] qcow2: Reuse refcount table in calculate_refcounts() Max Reitz
2014-10-20 15:09 ` Kevin Wolf
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 06/11] qcow2: Fix refcount blocks beyond image end Max Reitz
2014-10-20 16:44 ` Kevin Wolf
2014-10-21 7:14 ` Max Reitz
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 07/11] qcow2: Do not perform potentially damaging repairs Max Reitz
2014-10-21 7:52 ` Kevin Wolf
2014-10-21 10:10 ` Max Reitz
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 08/11] qcow2: Rebuild refcount structure during check Max Reitz
2014-10-21 9:31 ` Kevin Wolf
2014-10-21 9:52 ` Max Reitz
2014-10-21 10:12 ` Kevin Wolf
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 09/11] qcow2: Clean up after refcount rebuild Max Reitz
2014-10-21 9:59 ` Kevin Wolf
2014-10-21 10:16 ` Max Reitz
2014-10-21 14:55 ` Max Reitz
2014-10-21 15:11 ` Kevin Wolf
2014-10-21 15:17 ` Max Reitz [this message]
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 10/11] iotests: Fix test outputs Max Reitz
2014-10-21 13:42 ` Kevin Wolf
2014-10-20 14:35 ` [Qemu-devel] [PATCH v6 11/11] iotests: Add test for potentially damaging repairs Max Reitz
2014-10-21 14:12 ` Kevin Wolf
2014-10-21 14:20 ` Max Reitz
2014-10-21 15:16 ` Kevin Wolf
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=54467909.8070504@redhat.com \
--to=mreitz@redhat.com \
--cc=benoit.canet@nodalink.com \
--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.