From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Cc: Uri Lublin <uril@redhat.com>
Subject: Re: [Qemu-devel] [PATCH] qcow2 format: keep 'num_free_bytes', and show it upon 'info blockstats'
Date: Thu, 15 Jan 2009 13:55:00 -0600 [thread overview]
Message-ID: <496F9494.9040402@codemonkey.ws> (raw)
In-Reply-To: <1231858339-18205-1-git-send-email-uril@redhat.com>
Uri Lublin wrote:
> 'num_free_bytes' is the number of non-allocated bytes below highest-allocation.
>
> Added bookkeeping to block-qcow2.c
> Export it using BlockDeviceInfo
> Show it upon 'info blockstats' if BlockDeviceInfo exists
>
What is the use case for this?
Regards,
Anthony Liguori
> Signed-off-by: Uri Lublin <uril@redhat.com>
> ---
> block-qcow2.c | 36 ++++++++++++++++++++++++++++--------
> block.c | 5 +++--
> block.h | 1 +
> 3 files changed, 32 insertions(+), 10 deletions(-)
>
> diff --git a/block-qcow2.c b/block-qcow2.c
> index b8ef825..f16186e 100644
> --- a/block-qcow2.c
> +++ b/block-qcow2.c
> @@ -145,6 +145,7 @@ typedef struct BDRVQcowState {
> AES_KEY aes_decrypt_key;
>
> int64_t highest_alloc; /* highest cluester allocated (in clusters) */
> + int64_t nc_free; /* num of free clusters below highest_alloc */
>
> uint64_t snapshots_offset;
> int snapshots_size;
> @@ -173,7 +174,7 @@ static void free_clusters(BlockDriverState *bs,
> #ifdef DEBUG_ALLOC
> static void check_refcounts(BlockDriverState *bs);
> #endif
> -static void scan_refcount(BlockDriverState *bs, int64_t *high);
> +static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free);
>
>
> static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
> @@ -283,7 +284,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
> if (refcount_init(bs) < 0)
> goto fail;
>
> - scan_refcount(bs, &s->highest_alloc);
> + scan_refcount(bs, &s->highest_alloc, &s->nc_free);
>
> /* read the backing file name */
> if (header.backing_file_offset != 0) {
> @@ -1672,6 +1673,7 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
> bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
> (s->cluster_bits + s->l2_bits);
> bdi->highest_alloc = s->highest_alloc << s->cluster_bits;
> + bdi->num_free_bytes = s->nc_free << s->cluster_bits;
> return 0;
> }
>
> @@ -2206,25 +2208,35 @@ static int load_refcount_block(BlockDriverState *bs,
> return 0;
> }
>
> -static void scan_refcount(BlockDriverState *bs, int64_t *high)
> +static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free)
> {
> BDRVQcowState *s = bs->opaque;
> - int64_t refcnt_index, cluster_index, cluster_end, h = 0;
> + int64_t refcnt_index, cluster_index, cluster_end, h = 0, f = 0;
> + int64_t tail = 0; /* do not count last consecutive free entries */
>
> for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){
> if (s->refcount_table[refcnt_index] == 0) {
> + f += 1 << (s->cluster_bits - REFCOUNT_SHIFT);
> + tail += 1 << (s->cluster_bits - REFCOUNT_SHIFT);
> continue;
> }
> cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT);
> cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT);
> for ( ; cluster_index < cluster_end; cluster_index++) {
> - if (get_refcount(bs, cluster_index) == 0)
> - /* do nothing -- reserved for free counting */;
> - else
> + if (get_refcount(bs, cluster_index) == 0) {
> + f++;
> + tail++;
> + }
> + else {
> h = cluster_index;
> + tail = 0;
> + }
> }
> }
>
> + f -= tail;
> + if (free)
> + *free = f;
> if (high)
> *high = (h+1);
> }
> @@ -2270,8 +2282,10 @@ retry:
> (s->free_cluster_index - nb_clusters) << s->cluster_bits);
> #endif
>
> - if (s->highest_alloc < s->free_cluster_index)
> + if (s->highest_alloc < s->free_cluster_index) {
> + s->nc_free += (s->free_cluster_index - s->highest_alloc);
> s->highest_alloc = s->free_cluster_index;
> + }
>
> return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
> }
> @@ -2448,6 +2462,12 @@ static int update_cluster_refcount(BlockDriverState *bs,
> block_index = cluster_index &
> ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
> refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
> +
> + if (refcount == 1 && addend == -1)
> + s->nc_free += 1;
> + else if (refcount == 0 && addend == 1)
> + s->nc_free -= 1;
> +
> refcount += addend;
> if (refcount < 0 || refcount > 0xffff)
> return -EINVAL;
> diff --git a/block.c b/block.c
> index 5305b27..a65fc09 100644
> --- a/block.c
> +++ b/block.c
> @@ -1137,8 +1137,9 @@ void bdrv_info_stats (void)
> bs->rd_bytes, bs->wr_bytes,
> bs->rd_ops, bs->wr_ops);
> if (bdrv_get_info(bs, &bdi) == 0)
> - term_printf(" high=%" PRIu64,
> - bdi.highest_alloc);
> + term_printf(" high=%" PRId64
> + " bytes_free=%" PRId64,
> + bdi.highest_alloc, bdi.num_free_bytes);
> term_printf("\n");
> }
> }
> diff --git a/block.h b/block.h
> index 9c64af3..dca17db 100644
> --- a/block.h
> +++ b/block.h
> @@ -26,6 +26,7 @@ typedef struct BlockDriverInfo {
> /* offset at which the VM state can be saved (0 if not possible) */
> int64_t vm_state_offset;
> int64_t highest_alloc; /* highest allocated block offset (in bytes) */
> + int64_t num_free_bytes; /* below highest_alloc */
> } BlockDriverInfo;
>
> typedef struct QEMUSnapshotInfo {
>
next prev parent reply other threads:[~2009-01-15 19:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-13 14:52 [Qemu-devel] [PATCH] qcow2 format: keep 'num_free_bytes', and show it upon 'info blockstats' Uri Lublin
2009-01-15 19:55 ` Anthony Liguori [this message]
2009-01-18 13:15 ` Uri Lublin
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=496F9494.9040402@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.org \
--cc=uril@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.