All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Lan Tianyu <tianyu.lan@intel.com>
Cc: penberg@kernel.org, kvm@vger.kernel.org, asias.hejun@gmail.com,
	levinsasha928@gmail.com, prasadjoshi124@gmail.com
Subject: Re: [RFC PATCH] kvm tools, qcow: Add support for growing refcount blocks
Date: Mon, 12 Dec 2011 10:55:44 +0100	[thread overview]
Message-ID: <4EE5CFA0.5000203@redhat.com> (raw)
In-Reply-To: <1323655410-32000-1-git-send-email-tianyu.lan@intel.com>

Am 12.12.2011 03:03, schrieb Lan Tianyu:
> This patch enables allocating new refcount blocks and so then kvm tools
> could expand qcow2 image much larger.
> 
> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
> ---
>  tools/kvm/disk/qcow.c |  105 +++++++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 89 insertions(+), 16 deletions(-)
> 
> diff --git a/tools/kvm/disk/qcow.c b/tools/kvm/disk/qcow.c
> index e139fa5..929ba69 100644
> --- a/tools/kvm/disk/qcow.c
> +++ b/tools/kvm/disk/qcow.c
> @@ -12,6 +12,7 @@
>  #include <string.h>
>  #include <unistd.h>
>  #include <fcntl.h>
> +#include <errno.h>
>  #ifdef CONFIG_HAS_ZLIB
>  #include <zlib.h>
>  #endif
> @@ -20,6 +21,10 @@
>  #include <linux/kernel.h>
>  #include <linux/types.h>
>  
> +static int update_cluster_refcount(struct qcow *q, u64 clust_idx, u16 append);
> +static int qcow_write_refcount_table(struct qcow *q);
> +static u64 qcow_alloc_clusters(struct qcow *q, u64 size, int update_ref);
> +static void  qcow_free_clusters(struct qcow *q, u64 clust_start, u64 size);
>  
>  static inline int qcow_pwrite_sync(int fd,
>  	void *buf, size_t count, off_t offset)
> @@ -657,6 +662,56 @@ static struct qcow_refcount_block *refcount_block_search(struct qcow *q, u64 off
>  	return rfb;
>  }
>  
> +static struct qcow_refcount_block *qcow_grow_refcount_block(struct qcow *q,
> +	u64 clust_idx)
> +{
> +	struct qcow_header *header = q->header;
> +	struct qcow_refcount_table *rft = &q->refcount_table;
> +	struct qcow_refcount_block *rfb;
> +	u64 new_block_offset;
> +	u64 rft_idx;
> +
> +	rft_idx = clust_idx >> (header->cluster_bits -
> +		QCOW_REFCOUNT_BLOCK_SHIFT);
> +
> +	if (rft_idx >= rft->rf_size) {
> +		pr_warning("Don't support grow refcount block table");
> +		return NULL;
> +	}
> +
> +	new_block_offset = qcow_alloc_clusters(q, q->cluster_size, 0);
> +	if (new_block_offset < 0)
> +		return NULL;
> +
> +	rfb = new_refcount_block(q, new_block_offset);
> +	if (!rfb)
> +		return NULL;
> +
> +	memset(rfb->entries, 0x00, q->cluster_size);
> +	rfb->dirty = 1;
> +
> +	/* write refcount block */
> +	if (write_refcount_block(q, rfb) < 0)
> +		goto free_rfb;
> +
> +	if (cache_refcount_block(q, rfb) < 0)
> +		goto free_rfb;
> +
> +	rft->rf_table[rft_idx] = cpu_to_be64(new_block_offset);
> +	if (qcow_write_refcount_table(q) < 0)
> +		goto free_rfb;
> +
> +	if (update_cluster_refcount(q, new_block_offset >>
> +		    header->cluster_bits, 1) < 0)
> +		goto free_rfb;

This order is unsafe, you could end up with a refcount block that is
already in use, but still has a refcount of 0.

> +
> +	return rfb;
> +
> +free_rfb:
> +	free(rfb);
> +	return NULL;
> +}
> +
>  static struct qcow_refcount_block *qcow_read_refcount_block(struct qcow *q, u64 clust_idx)
>  {
>  	struct qcow_header *header = q->header;
> @@ -667,14 +722,11 @@ static struct qcow_refcount_block *qcow_read_refcount_block(struct qcow *q, u64
>  
>  	rft_idx = clust_idx >> (header->cluster_bits - QCOW_REFCOUNT_BLOCK_SHIFT);
>  	if (rft_idx >= rft->rf_size)
> -		return NULL;
> +		return (void *)-ENOSPC;

Is this allowed style in kvm-tool? :-/

Kevin

  reply	other threads:[~2011-12-12  9:52 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-12  2:03 [RFC PATCH] kvm tools, qcow: Add support for growing refcount blocks Lan Tianyu
2011-12-12  9:55 ` Kevin Wolf [this message]
2011-12-12 10:58   ` Pekka Enberg
2011-12-12 11:15     ` Kevin Wolf
2011-12-12 11:17       ` Kevin Wolf
2011-12-13  3:41       ` lan,Tianyu
2011-12-13  8:57         ` Kevin Wolf
2011-12-13  9:14           ` Pekka Enberg
2011-12-14  1:22           ` lan,Tianyu
2011-12-13  3:16     ` lan,Tianyu
2011-12-13  9:13       ` Pekka Enberg
2011-12-13  3:05   ` lan,Tianyu
2011-12-13  9:03     ` 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=4EE5CFA0.5000203@redhat.com \
    --to=kwolf@redhat.com \
    --cc=asias.hejun@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=levinsasha928@gmail.com \
    --cc=penberg@kernel.org \
    --cc=prasadjoshi124@gmail.com \
    --cc=tianyu.lan@intel.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.