From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-devel@nongnu.org, qemu-block@nongnu.org
Cc: eblake@redhat.com, armbru@redhat.com, mreitz@redhat.com,
kwolf@redhat.com, vsementsov@virtuozzo.com, den@openvz.org
Subject: [Qemu-devel] [PATCH] qcow2: add allocated-size to image specific info
Date: Thu, 18 May 2017 13:09:25 +0300 [thread overview]
Message-ID: <20170518100925.28682-1-vsementsov@virtuozzo.com> (raw)
Shows, how much data qcow2 allocates in underlying file. This should
be helpful on non-sparse file systems, when qemu-img info "disk size"
doesn't provide this information.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
Hi all.
Here is an allocated-size feature for qemu-img info.
block/qcow2-refcount.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
block/qcow2.c | 4 ++++
block/qcow2.h | 2 ++
qapi/block-core.json | 6 ++++-
4 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 7c06061aae..a2f7696a0a 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -2931,3 +2931,63 @@ done:
qemu_vfree(new_refblock);
return ret;
}
+
+typedef struct NbAllocatedClustersCo {
+ BlockDriverState *bs;
+ int64_t ret;
+} NbAllocatedClustersCo;
+
+static void coroutine_fn qcow2_nb_allocated_clusters_co_entry(void *opaque)
+{
+ NbAllocatedClustersCo *nbco = opaque;
+ BlockDriverState *bs = nbco->bs;
+ BDRVQcow2State *s = bs->opaque;
+ int64_t size, nb_clusters, nb_allocated = 0, i;
+ int ret = 0;
+
+ size = bdrv_getlength(bs->file->bs);
+ if (size < 0) {
+ nbco->ret = size;
+ return;
+ }
+
+ nb_clusters = size_to_clusters(s, size);
+
+ qemu_co_mutex_lock(&s->lock);
+
+ for (i = 0; i < nb_clusters; ++i) {
+ uint64_t refcount;
+ ret = qcow2_get_refcount(bs, i, &refcount);
+ if (ret < 0) {
+ nbco->ret = ret;
+ qemu_co_mutex_unlock(&s->lock);
+ return;
+ }
+ if (refcount > 0) {
+ nb_allocated++;
+ }
+ }
+
+ qemu_co_mutex_unlock(&s->lock);
+
+ nbco->ret = nb_allocated;
+}
+
+int64_t qcow2_nb_allocated_clusters(BlockDriverState *bs)
+{
+ NbAllocatedClustersCo nbco = {
+ .bs = bs,
+ .ret = -EINPROGRESS
+ };
+
+ if (qemu_in_coroutine()) {
+ qcow2_nb_allocated_clusters_co_entry(&nbco);
+ } else {
+ Coroutine *co =
+ qemu_coroutine_create(qcow2_nb_allocated_clusters_co_entry, &nbco);
+ qemu_coroutine_enter(co);
+ BDRV_POLL_WHILE(bs, nbco.ret == -EINPROGRESS);
+ }
+
+ return nbco.ret;
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index a8d61f0981..9a64b89ba2 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2927,6 +2927,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
.refcount_bits = s->refcount_bits,
};
} else if (s->qcow_version == 3) {
+ int64_t nb_allocated = qcow2_nb_allocated_clusters(bs);
+
*spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){
.compat = g_strdup("1.1"),
.lazy_refcounts = s->compatible_features &
@@ -2936,6 +2938,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
QCOW2_INCOMPAT_CORRUPT,
.has_corrupt = true,
.refcount_bits = s->refcount_bits,
+ .allocated_size = MAX(0, nb_allocated) << s->cluster_bits,
+ .has_allocated_size = nb_allocated >= 0,
};
} else {
/* if this assertion fails, this probably means a new version was
diff --git a/block/qcow2.h b/block/qcow2.h
index 1801dc30dc..a0f0bf9358 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -532,6 +532,8 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp);
+int64_t qcow2_nb_allocated_clusters(BlockDriverState *bs);
+
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6b974b952f..ddaffff830 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -44,6 +44,9 @@
#
# @refcount-bits: width of a refcount entry in bits (since 2.3)
#
+# @allocated-size: number of allocated clusters (including metadata)
+# if available; only valid for compat >= 1.1 (since v2.10)
+#
# Since: 1.7
##
{ 'struct': 'ImageInfoSpecificQCow2',
@@ -51,7 +54,8 @@
'compat': 'str',
'*lazy-refcounts': 'bool',
'*corrupt': 'bool',
- 'refcount-bits': 'int'
+ 'refcount-bits': 'int',
+ '*allocated-size': 'uint64'
} }
##
--
2.11.1
next reply other threads:[~2017-05-18 10:09 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-18 10:09 Vladimir Sementsov-Ogievskiy [this message]
2017-05-18 10:25 ` [Qemu-devel] [PATCH] qcow2: add allocated-size to image specific info Kevin Wolf
2017-05-18 10:38 ` Denis V. Lunev
2017-05-18 11:04 ` Vladimir Sementsov-Ogievskiy
2017-05-18 12:10 ` Kevin Wolf
2017-05-18 12:22 ` Denis V. Lunev
2017-05-18 14:54 ` Kevin Wolf
2017-05-18 15:02 ` Denis V. Lunev
2017-05-18 12:33 ` Vladimir Sementsov-Ogievskiy
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=20170518100925.28682-1-vsementsov@virtuozzo.com \
--to=vsementsov@virtuozzo.com \
--cc=armbru@redhat.com \
--cc=den@openvz.org \
--cc=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@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 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.