All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frediano Ziglio <freddy77@gmail.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: stefanha@gmail.com, qemu-devel@nongnu.org, hahn@univention.de
Subject: Re: [Qemu-devel] [PATCH v2 0.15.0] qcow2: Fix L1 table size after bdrv_snapshot_goto
Date: Fri, 5 Aug 2011 10:28:57 +0200	[thread overview]
Message-ID: <CAHt6W4c1yi8vA6DcXdz9meYGOs5TXGe7T292G_JtGeoK6FWfwA@mail.gmail.com> (raw)
In-Reply-To: <4E3BA0EB.9050604@redhat.com>

2011/8/5 Kevin Wolf <kwolf@redhat.com>:
> Am 05.08.2011 08:35, schrieb Frediano Ziglio:
>> 2011/8/4 Kevin Wolf <kwolf@redhat.com>:
>>> When loading an internal snapshot whose L1 table is smaller than the current L1
>>> table, the size of the current L1 would be shrunk to the snapshot's L1 size in
>>> memory, but not on disk. This lead to incorrect refcount updates and eventuelly
>>> to image corruption.
>>>
>>> Instead of writing the new L1 size to disk, this simply retains the bigger L1
>>> size that is currently in use and makes sure that the unused part is zeroed.
>>>
>>> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
>>> ---
>>>
>>> And the moment you send it out, you notice that it's wrong... *sigh*
>>>
>>> v2:
>>> - Check for s->l1_size > sn->l1_size in order to avoid disasters...
>>>
>>> Philipp, I think this should fix your corruption. Please give it a try.
>>>
>>> Anthony, this must go into 0.15. Given the short time until -rc2, do you prefer
>>> to pick it up directly or should I send a pull request tomorrow? The patch
>>> looks obvious, is tested with the given testcase and survives a basic
>>> qemu-iotests run (though qemu-iotests doesn't exercise snapshots a lot)
>>>
>>> Stefan, please review :-)
>>>
>>>  block/qcow2-snapshot.c |    5 ++++-
>>>  1 files changed, 4 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
>>> index 74823a5..6972e66 100644
>>> --- a/block/qcow2-snapshot.c
>>> +++ b/block/qcow2-snapshot.c
>>> @@ -330,8 +330,11 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
>>>     if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0)
>>>         goto fail;
>>>
>>> -    s->l1_size = sn->l1_size;
>>> +    if (s->l1_size > sn->l1_size) {
>>> +        memset(s->l1_table + sn->l1_size, 0, s->l1_size - sn->l1_size);
>>> +    }
>>>     l1_size2 = s->l1_size * sizeof(uint64_t);
>>> +
>>>     /* copy the snapshot l1 table to the current l1 table */
>>>     if (bdrv_pread(bs->file, sn->l1_table_offset,
>>>                    s->l1_table, l1_size2) != l1_size2)
>>> --
>>> 1.7.6
>>>
>>
>> This patch looked odd at first sight. First a qcow2_grow_l1_table is
>> called to shrink L1 so perhaps should be qcow2_resize_l1_table.
>
> No, it doesn't shrink the table:
>
>    if (min_size <= s->l1_size)
>        return 0;
>

Yes, but perhaps returning success and not clipping anything is not
that correct, perhaps qcow2_snapshot_goto should not call
qcow2_grow_l1_table with a shorter value.

>> Perhaps also it would be better to clean entries in
>> qcow2_grow_l1_table instead of  qcow2_snapshot_goto to avoid same
>> problem in different calls to qcow2_grow_l1_table. The other oddity
>> (still to understand) is: why does some code use l1_table above
>> l1_size ??
>
> Which code do you mean specifically?
>
> Kevin
>

I think this is the issue

# 1204 -> 128 cluster per L2 entry -> 128k per L2 entry
# 128 cluster per L1 entry -> 16M per L1 entry
qemu-img create -f qcow2 /tmp/sn.qcow2 16m -o cluster_size=1024
qemu-img snapshot -c foo /tmp/sn.qcow2
# extend L1
qemu-io -c 'write -b 0 4M' /tmp/sn.qcow2
# shrink
qemu-img snapshot -a foo /tmp/sn.qcow2
qemu-img check /tmp/sn.qcow2

Well... I was trying to get a leak and got a core instead. I removed
your patch and got leaks.

also, should not be

    memset(s->l1_table + sn->l1_size, 0, (s->l1_size - sn->l1_size) *
sizeof(uint64_t));

instead of

    memset(s->l1_table + sn->l1_size, 0, s->l1_size - sn->l1_size);

Frediano

  reply	other threads:[~2011-08-05  8:29 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Message-Id: <1312474673-2705-1-git-send-email-kwolf@redhat.com>
2011-08-04 16:17 ` [Qemu-devel] [PATCH 0.15.0] qcow2: Fix L1 table size after bdrv_snapshot_goto Kevin Wolf
2011-08-04 16:24 ` [Qemu-devel] [PATCH v2 " Kevin Wolf
2011-08-04 17:19   ` Philipp Hahn
2011-08-05  6:35   ` Frediano Ziglio
2011-08-05  7:51     ` Kevin Wolf
2011-08-05  8:28       ` Frediano Ziglio [this message]
2011-08-05  9:37         ` Frediano Ziglio

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=CAHt6W4c1yi8vA6DcXdz9meYGOs5TXGe7T292G_JtGeoK6FWfwA@mail.gmail.com \
    --to=freddy77@gmail.com \
    --cc=hahn@univention.de \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.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.