qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Eric Blake <eblake@redhat.com>, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v10 03/17] qcow2: Reuse preallocated zero clusters
Date: Fri, 28 Apr 2017 19:51:10 +0200	[thread overview]
Message-ID: <5957bbf1-3093-e95a-73c5-ea5f5b9da3db@redhat.com> (raw)
In-Reply-To: <20170427014626.11553-4-eblake@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 5942 bytes --]

On 27.04.2017 03:46, Eric Blake wrote:
> From: Max Reitz <mreitz@redhat.com>
> 
> Instead of just freeing preallocated zero clusters and completely
> allocating them from scratch, reuse them.
> 
> We cannot do this in handle_copied(), however, since this is a COW
> operation. Therefore, we have to add the new logic to handle_alloc() and
> simply return the existing offset if it exists. The only catch is that
> we have to convince qcow2_alloc_cluster_link_l2() not to free the old
> clusters (because we have reused them).
> 
> Reported-by: Eric Blake <eblake@redhat.com>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> 
> ---
> v10: new patch. Max hasn't posted the patch directly on list, but
> did mention it here:
> https://lists.gnu.org/archive/html/qemu-devel/2017-04/msg03936.html
> and that he would post it once he has tests. Well, my later patches
> add a test that requires this one :)  The other two patches that
> he mentioned there are also good, but not essential for my series
> (and I didn't want to write tests to expose the behavior difference,
> because it would deprive Max of that fun).

Well, the main reason I didn't send the patches yet is because I was
tired while writing them ("Date: Sat Apr 22 01:17:52 2017 +0200") and I
wanted to take another look before sending them. I guess now's as good a
time as any.

> ---
>  block/qcow2.h         |  3 ++
>  block/qcow2-cluster.c | 83 +++++++++++++++++++++++++++++++++++----------------
>  2 files changed, 60 insertions(+), 26 deletions(-)

[...]

> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index d1063df..db3d937 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c

[...]

> @@ -1192,31 +1199,53 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
>       * wrong with our code. */
>      assert(nb_clusters > 0);
> 
> +    if (!*host_offset && qcow2_get_cluster_type(entry) == QCOW2_CLUSTER_ZERO &&
> +        (entry & L2E_OFFSET_MASK) != 0 && (entry & QCOW_OFLAG_COPIED))

*host_offset works with this, too, if
start_of_cluster(s, *host_offset) == (entry & L2E_OFFSET_MASK).

If !(entry & QCOW_OFLAG_COPIED), we should check whether the refcount
maybe is 1 and then set OFLAG_COPIED. But that is something we don't
even do for normal clusters yet, so it's something to fix another day.

> +    {
> +        /* Try to reuse preallocated zero clusters; contiguous normal clusters
> +         * would be fine, too, but count_cow_clusters() above has limited
> +         * nb_clusters already to a range of COW clusters */
> +        int preallocated_nb_clusters =
> +            count_contiguous_clusters(nb_clusters, s->cluster_size, l2_table,

s/l2_table/&l2_table[l2_index]/

> +                                      QCOW_OFLAG_COPIED);
> +
> +        if (preallocated_nb_clusters) {

preallocated_nb_clusters must be at least 1, so an assertion would be
better.

Max

> +            nb_clusters = preallocated_nb_clusters;
> +            alloc_cluster_offset = entry & L2E_OFFSET_MASK;
> +
> +            /* We want to reuse these clusters, so qcow2_alloc_cluster_link_l2()
> +             * should not free them. */
> +            keep_old_clusters = true;
> +        }
> +    }
> +
>      qcow2_cache_put(bs, s->l2_table_cache, (void **) &l2_table);
> 
> -    /* Allocate, if necessary at a given offset in the image file */
> -    alloc_cluster_offset = start_of_cluster(s, *host_offset);
> -    ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset,
> -                                  &nb_clusters);
> -    if (ret < 0) {
> -        goto fail;
> -    }
> -
> -    /* Can't extend contiguous allocation */
> -    if (nb_clusters == 0) {
> -        *bytes = 0;
> -        return 0;
> -    }
> -
> -    /* !*host_offset would overwrite the image header and is reserved for "no
> -     * host offset preferred". If 0 was a valid host offset, it'd trigger the
> -     * following overlap check; do that now to avoid having an invalid value in
> -     * *host_offset. */
>      if (!alloc_cluster_offset) {
> -        ret = qcow2_pre_write_overlap_check(bs, 0, alloc_cluster_offset,
> -                                            nb_clusters * s->cluster_size);
> -        assert(ret < 0);
> -        goto fail;
> +        /* Allocate, if necessary at a given offset in the image file */
> +        alloc_cluster_offset = start_of_cluster(s, *host_offset);
> +        ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset,
> +                                      &nb_clusters);
> +        if (ret < 0) {
> +            goto fail;
> +        }
> +
> +        /* Can't extend contiguous allocation */
> +        if (nb_clusters == 0) {
> +            *bytes = 0;
> +            return 0;
> +        }
> +
> +        /* !*host_offset would overwrite the image header and is reserved for
> +         * "no host offset preferred". If 0 was a valid host offset, it'd
> +         * trigger the following overlap check; do that now to avoid having an
> +         * invalid value in *host_offset. */
> +        if (!alloc_cluster_offset) {
> +            ret = qcow2_pre_write_overlap_check(bs, 0, alloc_cluster_offset,
> +                                                nb_clusters * s->cluster_size);
> +            assert(ret < 0);
> +            goto fail;
> +        }
>      }
> 
>      /*
> @@ -1247,6 +1276,8 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
>          .offset         = start_of_cluster(s, guest_offset),
>          .nb_clusters    = nb_clusters,
> 
> +        .keep_old_clusters  = keep_old_clusters,
> +
>          .cow_start = {
>              .offset     = 0,
>              .nb_bytes   = offset_into_cluster(s, guest_offset),
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

  reply	other threads:[~2017-04-28 17:51 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-27  1:46 [Qemu-devel] [PATCH v10 00/17] add blkdebug tests Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 01/17] block: Update comments on BDRV_BLOCK_* meanings Eric Blake
2017-04-28 17:12   ` Max Reitz
2017-04-28 20:18   ` Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 02/17] qcow2: Correctly report status of preallocated zero clusters Eric Blake
2017-04-28 17:35   ` Max Reitz
2017-04-28 19:04     ` Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 03/17] qcow2: Reuse " Eric Blake
2017-04-28 17:51   ` Max Reitz [this message]
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 04/17] qcow2: Optimize zero_single_l2() to minimize L2 churn Eric Blake
2017-04-28 18:00   ` Max Reitz
2017-04-28 19:11     ` Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 05/17] iotests: Add test 179 to cover write zeroes with unmap Eric Blake
2017-04-28 19:28   ` Max Reitz
2017-04-28 19:48     ` Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 06/17] qemu-io: Don't open-code QEMU_IS_ALIGNED Eric Blake
2017-04-28 19:30   ` Max Reitz
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 07/17] qemu-io: Switch 'alloc' command to byte-based length Eric Blake
2017-04-28 19:46   ` Max Reitz
2017-04-28 19:59     ` Eric Blake
2017-04-28 20:09       ` Max Reitz
2017-04-28 20:36         ` Eric Blake
2017-04-28 20:52           ` Max Reitz
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 08/17] qemu-io: Switch 'map' output to byte-based reporting Eric Blake
2017-04-28 19:53   ` Max Reitz
2017-04-28 20:03     ` Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 09/17] qcow2: Optimize write zero of unaligned tail cluster Eric Blake
2017-04-28 20:48   ` Max Reitz
2017-04-28 21:24     ` Eric Blake
2017-05-04  2:47       ` Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 10/17] qcow2: Assert that cluster operations are aligned Eric Blake
2017-05-03 17:56   ` Max Reitz
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 11/17] qcow2: Discard/zero clusters by byte count Eric Blake
2017-05-03 18:28   ` Max Reitz
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 12/17] blkdebug: Sanity check block layer guarantees Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 13/17] blkdebug: Refactor error injection Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 14/17] blkdebug: Add pass-through write_zero and discard support Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 15/17] blkdebug: Simplify override logic Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 16/17] blkdebug: Add ability to override unmap geometries Eric Blake
2017-04-27  1:46 ` [Qemu-devel] [PATCH v10 17/17] tests: Add coverage for recent block geometry fixes Eric Blake

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=5957bbf1-3093-e95a-73c5-ea5f5b9da3db@redhat.com \
    --to=mreitz@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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).