qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Hanna Czenczek <hreitz@redhat.com>
To: Jean-Louis Dupond <jean-louis@dupond.be>,
	qemu-devel@nongnu.org, kwolf@redhat.com,
	andrey.drobyshev@virtuozzo.com
Subject: Re: [PATCH v2 1/2] qcow2: handle discard-no-unref in measure
Date: Wed, 10 Jul 2024 14:58:57 +0200	[thread overview]
Message-ID: <80a77456-da98-4346-aa56-a7389934cdcf@redhat.com> (raw)
In-Reply-To: <20240605132539.3668497-2-jean-louis@dupond.be>

On 05.06.24 15:25, Jean-Louis Dupond wrote:
> When doing a measure on an image with a backing file and
> discard-no-unref is enabled, the code should take this into account.

That doesn’t make sense to me.  As far as I understand, 'measure' is 
supposed to report how much space you need for a given image, i.e. if 
you were to convert it to a new image.  discard-no-unref doesn’t factor 
into that, because for a 'convert' target (a new image), nothing can be 
discarded.

Reading the issue, I understand that oVirt uses measure to determine the 
size of the target of a 'commit' operation.  Seems a bit like abuse to 
me, precisely because of the issue you’re facing.  More specifically, a 
'commit' operation is a complex thing with a lot of variables, so the 
outcome depends on a lot.

For example, this patch just checks the discard-no-unref setting on the 
top image.  But AFAIU it doesn’t matter what the setting on the top 
image is, it matters what the setting on the commit target is. 'measure' 
can’t know this because it doesn’t know what the commit target is.  As 
far as I can see, this patch actually assumes the commit target is the 
first backing image (it specifically checks in the image whether a block 
is allocated) – why?

So to me that means if 'measure' is supposed to give reliable data on 
the commit case, it needs to be extended.  Best thing I can come up with 
off the top of my head would be to add an option e.g. 
'commit=<target-node-name>', so we (A) that we’re looking at a commit 
and not a convert, and (B) we know what data will be collapsed into 
which image and where we need to check for discard-no-unref.

Hanna

> If for example you have a snapshot image with a base, and you do a
> discard within the snapshot, it will be ZERO and ALLOCATED, but without
> host offset.
> Now if we commit this snapshot, and the clusters in the base image have
> a host offset, the clusters will only be set to ZERO, but the host offset
> will not be cleared.
> Therefor non-data clusters in the top image need to check the
> base to see if space will be freed or not, to have a correct measure
> output.
>
> Bug-Url: https://gitlab.com/qemu-project/qemu/-/issues/2369
> Signed-off-by: Jean-Louis Dupond <jean-louis@dupond.be>
> ---
>   block/qcow2.c | 32 +++++++++++++++++++++++++++++---
>   1 file changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 956128b409..50354e5b98 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -5163,9 +5163,16 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
>           } else {
>               int64_t offset;
>               int64_t pnum = 0;
> +            BlockDriverState *parent = bdrv_filter_or_cow_bs(in_bs);
> +            BDRVQcow2State *s = NULL;
> +
> +            if (parent) {
> +                s = parent->opaque;
> +            }
>   
>               for (offset = 0; offset < ssize; offset += pnum) {
>                   int ret;
> +                int retp = 0;
>   
>                   ret = bdrv_block_status_above(in_bs, NULL, offset,
>                                                 ssize - offset, &pnum, NULL,
> @@ -5176,10 +5183,29 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
>                       goto err;
>                   }
>   
> -                if (ret & BDRV_BLOCK_ZERO) {
> +                /* If we have a parent in the chain and the current block is not data,
> +                 * then we want to check the allocation state of the parent block.
> +                 * If it has a valid offset, then we want to include it into
> +                 * the calculation, cause blocks with an offset will not be freed when
> +                 * committing the top into base with discard-no-unref enabled.
> +                 */
> +                if (parent && s->discard_no_unref && !(ret & BDRV_BLOCK_DATA)) {
> +                        int64_t pnum_parent = 0;
> +                        retp = bdrv_block_status_above(parent, NULL, offset,
> +                                              ssize - offset, &pnum_parent, NULL,
> +                                              NULL);
> +                        /* If the parent continuous block is smaller, use that pnum,
> +                         * so the next iteration starts with the smallest offset.
> +                         */
> +                        if (pnum_parent < pnum) {
> +                            pnum = pnum_parent;
> +                        }
> +                }
> +                if (ret & BDRV_BLOCK_ZERO && !parent && !(parent && s->discard_no_unref)) {
>                       /* Skip zero regions (safe with no backing file) */
> -                } else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==
> -                           (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) {
> +                } else if (((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==
> +                            (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ||
> +                           (retp & BDRV_BLOCK_OFFSET_VALID)) {
>                       /* Extend pnum to end of cluster for next iteration */
>                       pnum = ROUND_UP(offset + pnum, cluster_size) - offset;
>   



  parent reply	other threads:[~2024-07-10 12:59 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-05 13:25 [PATCH v2 1/2] qcow2: handle discard-no-unref in measure Jean-Louis Dupond
2024-06-05 13:25 ` [PATCH v2 2/2] qcow2: don't allow discard-no-unref when discard is not enabled Jean-Louis Dupond
2024-07-10 13:00   ` Hanna Czenczek
2025-02-17 15:35     ` Jean-Louis Dupond
2024-07-10 12:58 ` Hanna Czenczek [this message]
2025-02-17 15:34   ` [PATCH v2 1/2] qcow2: handle discard-no-unref in measure Jean-Louis Dupond
2025-03-27  9:16     ` Jean-Louis Dupond

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=80a77456-da98-4346-aa56-a7389934cdcf@redhat.com \
    --to=hreitz@redhat.com \
    --cc=andrey.drobyshev@virtuozzo.com \
    --cc=jean-louis@dupond.be \
    --cc=kwolf@redhat.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).