From: Stefan Hajnoczi <stefanha@redhat.com>
To: 蒙聪 <mengcong@meituan.com>
Cc: Kevin Wolf <kwolf@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] qcow2: preallocate() extands image less enough
Date: Wed, 30 Jul 2014 14:31:43 +0100 [thread overview]
Message-ID: <20140730133143.GG597@stefanha-thinkpad.redhat.com> (raw)
In-Reply-To: <345629775.1268590.1401202679338.JavaMail.root@meituan.com>
[-- Attachment #1: Type: text/plain, Size: 2970 bytes --]
On Tue, May 27, 2014 at 10:57:59PM +0800, 蒙聪 wrote:
> cow2_alloc_cluster_offset() sets the host_offset pointing to the first
> byte of the cluster referenced by guest_offset other than to the exact
> byte referenced by guest_offset. In this case, preallocate() fails to
> extend the image large enough.
>
> This bug can be reproduced by following steps:
>
> $ /home/cmeng/work/qemu/qemu-git/qemu-img create -f qcow2 -o cluster_size=2M,preallocation=metadata t1 25G
> Formatting 't1', fmt=qcow2 size=26843545600 encryption=off cluster_size=2097152 preallocation='metadata' lazy_refcounts=off
>
> $ ll t1
> -rw-r--r-- 1 cmeng cmeng 26851940352 May 27 21:20 t1
>
> $ ./qcow2.py t1 get-cluster-offset 52428799
> l1_size, 1 l1_table_offset, 6291456 cluster_bits, 21 cluster_size, 2097152 l2_entries_per_cluster, 262144
> l1_entry (l1_refcount, l2_offset) : (1L, 8388608L)
> l2_entry (l2_compressed, l2_refcount_is_one, (cluster_offset, read_as_zero)) : (0L, 1L, (26851934208L, 0L))
> final offset : 26854030848
>
> I modified qcow2.py to get the offset into the host image file of the
> last sector of the virutal image. As shown above, the offset is
> 26854030848, which is a little bigger than 26851940352, the size of t1.
>
> Signed-off-by: Cong Meng <mengcong@meituan.com>
> ---
> block/qcow2.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/block/qcow2.c b/block/qcow2.c
> index a4b97e8..c315fb7 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -1538,6 +1538,7 @@ static int preallocate(BlockDriverState *bs)
> int num;
> int ret;
> QCowL2Meta *meta;
> + BDRVQcowState *s = bs->opaque;
>
> nb_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
> offset = 0;
> @@ -1582,6 +1583,8 @@ static int preallocate(BlockDriverState *bs)
> if (host_offset != 0) {
> uint8_t buf[BDRV_SECTOR_SIZE];
> memset(buf, 0, BDRV_SECTOR_SIZE);
> + host_offset += offset_into_cluster(s,
> + offset - (num << BDRV_SECTOR_BITS));
> ret = bdrv_write(bs->file, (host_offset >> BDRV_SECTOR_BITS) + num - 1,
> buf, 1);
I don't understand what problem this calculation is supposed to fix.
Can you explain the root cause?
It seems that the issue stems from:
while (nb_sectors) {
num = MIN(nb_sectors, INT_MAX >> BDRV_SECTOR_BITS);
ret = qcow2_alloc_cluster_offset(bs, offset, &num,
&host_offset,
&meta);
INT_MAX >> BDRV_SECTOR_BITS is not a multiple of cluster size. That
means 'num' will not be a multiple of cluster size, even though full
clusters were allocated by qcow2_alloc_cluster_offset().
Try changing it to:
(INT_MAX & ~(s->cluster_size - 1)) >> BDRV_SECTOR_BITS
Now the loop will allocate full clusters until the last iteration.
Stefan
[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]
parent reply other threads:[~2014-07-30 13:32 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <345629775.1268590.1401202679338.JavaMail.root@meituan.com>]
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=20140730133143.GG597@stefanha-thinkpad.redhat.com \
--to=stefanha@redhat.com \
--cc=kwolf@redhat.com \
--cc=mengcong@meituan.com \
--cc=qemu-devel@nongnu.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).