From: Juan Quintela <quintela@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: hch@lst.de, qemu-devel@nongnu.org, gleb@redhat.com, armbru@redhat.com
Subject: [Qemu-devel] Re: [PATCH 2/3] qcow2: Rewrite alloc_refcount_block/grow_refcount_table
Date: Thu, 18 Feb 2010 13:02:18 +0100 [thread overview]
Message-ID: <m3d402ycol.fsf@neno.neno> (raw)
In-Reply-To: <1266250769-5816-3-git-send-email-kwolf@redhat.com> (Kevin Wolf's message of "Mon, 15 Feb 2010 17:19:28 +0100")
Kevin Wolf <kwolf@redhat.com> wrote:
> + /* Find the refcount block for the given cluster */
> + refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
> + if (refcount_table_index >= s->refcount_table_size) {
> + refcount_block_offset = 0;
> + } else {
> + refcount_block_offset = s->refcount_table[refcount_table_index];
> + }
> +
> + /* If it's already there, we're done */
> + if (refcount_block_offset) {
> + if (refcount_block_offset != s->refcount_block_cache_offset) {
> + ret = load_refcount_block(bs, refcount_block_offset);
> + if (ret < 0) {
> + return ret;
> + }
> + }
> + return refcount_block_offset;
> + }
I would merge this if in the previous one. as a bonus,
refcount_block_offset can be local to that if branch and no need of the
else one.
> +
> + /*
> + * If we came here, we need to allocate something. Something is at least
> + * a cluster for the new refcount block. It may also include a new refcount
> + * table if the old refcount table is too small.
> + *
> + * Note that allocating clusters here needs some special care:
> + *
> + * - We can't use the normal qcow2_alloc_clusters(), it would try to
> + * increase the refcount and very likely we would end up with an endless
> + * recursion. Instead we must place the refcount blocks in a way that
> + * they can describe them themselves.
> + *
> + * - We need to consider that at this point we are inside update_refcounts
> + * and doing the initial refcount increase. This means that some clusters
> + * have already been allocated by the caller, but their refcount isn't
> + * accurate yet. free_cluster_index tells us where this allocation ends
> + * as long as we don't overwrite it by freeing clusters.
> + *
> + * - alloc_clusters_noref and qcow2_free_clusters may load a different
> + * refcount block into the cache
> + */
> +
> + if (cache_refcount_updates) {
> + write_refcount_block(s);
write_refconut_blocks() can return -EIO. It is not handled anywhere
else either.
> + /* Calculate the number of refcount blocks needed so far */
> + uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT);
> + uint64_t blocks_used = (s->free_cluster_index +
> + refcount_block_clusters - 1) / refcount_block_clusters;
> +
> + /* And now we need at least one block more for the new metadata */
> + uint64_t table_size = next_refcount_table_size(s, blocks_used + 1);
> + uint64_t last_table_size = table_size;
only place where last_table_size is assigned to.
> + uint64_t blocks_clusters;
> + do {
> + uint64_t table_clusters = size_to_clusters(s, table_size);
> + blocks_clusters = 1 +
> + ((table_clusters + refcount_block_clusters - 1)
> + / refcount_block_clusters);
> + uint64_t meta_clusters = table_clusters + blocks_clusters;
> +
> + table_size = next_refcount_table_size(s, blocks_used +
> + ((meta_clusters + refcount_block_clusters - 1)
> + / refcount_block_clusters));
this value can be the same than previous next_refcount_table_size()
call or bigger.
> +
> + } while (last_table_size != table_size);
how can this converge? (already discussed on irc with keving that a
last_table_size = table_size is missing somewhere in the loop.
Later, Juan.
next prev parent reply other threads:[~2010-02-18 12:03 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-15 16:19 [Qemu-devel] [PATCH 0/3] qcow2: Rewrite alloc_refcount_block Kevin Wolf
2010-02-15 16:19 ` [Qemu-devel] [PATCH 1/3] qcow2: Factor next_refcount_table_size out Kevin Wolf
2010-02-18 10:40 ` [Qemu-devel] " Juan Quintela
2010-02-15 16:19 ` [Qemu-devel] [PATCH 2/3] qcow2: Rewrite alloc_refcount_block/grow_refcount_table Kevin Wolf
2010-02-18 12:02 ` Juan Quintela [this message]
2010-02-15 16:19 ` [Qemu-devel] [PATCH 3/3] qcow2: More checks for qemu-img check Kevin Wolf
2010-02-18 12:11 ` [Qemu-devel] " Juan Quintela
2010-02-19 21:13 ` [Qemu-devel] [PATCH 0/3] qcow2: Rewrite alloc_refcount_block Anthony Liguori
2010-02-20 1:49 ` [Qemu-devel] " Juan Quintela
2010-02-20 17:02 ` Anthony Liguori
2010-02-22 8:54 ` Kevin Wolf
2010-02-22 9:55 ` Markus Armbruster
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=m3d402ycol.fsf@neno.neno \
--to=quintela@redhat.com \
--cc=armbru@redhat.com \
--cc=gleb@redhat.com \
--cc=hch@lst.de \
--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 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.