From: Eric Blake <eblake@redhat.com>
To: Max Reitz <mreitz@redhat.com>, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v3] qcow2: Rewrite qcow2_alloc_bytes()
Date: Fri, 06 Feb 2015 08:27:01 -0700 [thread overview]
Message-ID: <54D4DD45.5010809@redhat.com> (raw)
In-Reply-To: <1423233556-19394-1-git-send-email-mreitz@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 3017 bytes --]
On 02/06/2015 07:39 AM, Max Reitz wrote:
> qcow2_alloc_bytes() is a function with insufficient error handling and
> an unnecessary goto. This patch rewrites it.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> v3:
> - Use alloc_clusters_noref() and update_refcount() [Kevin]
Ouch. Not done quite right. Kevin, you may want to remove this from
your staging area, while Max works on a v4.
> +
> + free_in_cluster = s->cluster_size - offset_into_cluster(s, offset);
> + if (!offset || free_in_cluster < size) {
Let's consider all four possibilities:
Case 1: !offset
we won't be modifying any existing clusters. When we are done, the new
cluster needs a refcount of 1
Case 2: free_in_cluster >= size
we will only be modifying an existing cluster, assume it starts with
refcount of 1. When we are done, it needs a refcount of 2
Case 3: free_in_cluster < size, allocation is not contiguous
we won't be modifying any existing clusters. When we are done, the new
cluster needs a refcount of 1
Case 4: free_in_cluster < size, allocation is contiguous
we will be placing data into both an existing cluster and a new one;
assume the existing cluster starts with a refcount of 1. When we are
done, the old cluster needs a refcount of 2, and the new cluster needs a
refcount of 1
> + int64_t new_cluster = alloc_clusters_noref(bs, s->cluster_size);
This says the new cluster has a refcount of 0.
> + if (new_cluster < 0) {
> + return new_cluster;
> + }
> +
> + if (!offset || ROUND_UP(offset, s->cluster_size) != new_cluster) {
> + offset = new_cluster;
> }
> }
>
> - /* The cluster refcount was incremented, either by qcow2_alloc_clusters()
> - * or explicitly by qcow2_update_cluster_refcount(). Refcount blocks must
> - * be flushed before the caller's L2 table updates.
> - */
> + assert(offset);
> + ret = update_refcount(bs, offset, size, 1, QCOW2_DISCARD_NEVER);
Case 1: This incremented the new cluster. Good
Case 2: This incremented the old cluster. Good
Case 3: This incremented the new cluster. Good
Case 4: This incremented the old cluster. But the new cluster remains at
refcount 0. BAD.
v2 got it right, because it always put the NEW cluster at refcount 1 (if
there was a new cluster), then incremented the old cluster when needed.
> + if (ret < 0) {
> + return ret;
> + }
> +
> + /* The cluster refcount was incremented; refcount blocks must be flushed
> + * before the caller's L2 table updates. */
> qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache);
> +
> + s->free_byte_offset = offset + size;
> + if (!offset_into_cluster(s, s->free_byte_offset)) {
> + s->free_byte_offset = 0;
> + }
> +
> return offset;
> }
>
>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
next prev parent reply other threads:[~2015-02-06 15:27 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-06 14:39 [Qemu-devel] [PATCH v3] qcow2: Rewrite qcow2_alloc_bytes() Max Reitz
2015-02-06 15:01 ` Kevin Wolf
2015-02-06 15:27 ` Eric Blake [this message]
2015-02-06 15:31 ` Eric Blake
2015-02-06 16:22 ` 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=54D4DD45.5010809@redhat.com \
--to=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@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.