[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/7] qcow2: add .bdrv_get_format_allocated_size
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[Qemu-devel] [PATCH 3/7] qcow2: add .bdrv_get_format_allocated_size |
Date: |
Thu, 25 May 2017 18:26:24 +0300 |
Realize .bdrv_get_format_allocated_size interface.
Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
---
block/qcow2-refcount.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
block/qcow2.c | 2 ++
block/qcow2.h | 2 ++
3 files changed, 65 insertions(+)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 7c06061aae..45adf6bd1d 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -2931,3 +2931,64 @@ done:
qemu_vfree(new_refblock);
return ret;
}
+
+typedef struct NbAllocatedClustersCo {
+ BlockDriverState *bs;
+ int64_t ret;
+} NbAllocatedClustersCo;
+
+static void coroutine_fn qcow2_get_format_allocated_size_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 << s->cluster_bits;
+}
+
+int64_t qcow2_get_format_allocated_size(BlockDriverState *bs)
+{
+ NbAllocatedClustersCo nbco = {
+ .bs = bs,
+ .ret = -EINPROGRESS
+ };
+
+ if (qemu_in_coroutine()) {
+ qcow2_get_format_allocated_size_co_entry(&nbco);
+ } else {
+ Coroutine *co =
+ qemu_coroutine_create(qcow2_get_format_allocated_size_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..274f213d16 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3469,6 +3469,8 @@ BlockDriver bdrv_qcow2 = {
.bdrv_detach_aio_context = qcow2_detach_aio_context,
.bdrv_attach_aio_context = qcow2_attach_aio_context,
+
+ .bdrv_get_format_allocated_size = qcow2_get_format_allocated_size,
};
static void bdrv_qcow2_init(void)
diff --git a/block/qcow2.h b/block/qcow2.h
index 1801dc30dc..8cc63d9e0e 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_get_format_allocated_size(BlockDriverState *bs);
+
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size);
--
2.11.1
- [Qemu-devel] [PATCH 4/7] common: make get_human_readable_size public, (continued)
- [Qemu-devel] [PATCH 4/7] common: make get_human_readable_size public, Vladimir Sementsov-Ogievskiy, 2017/05/25
- [Qemu-devel] [PATCH 6/7] qemu-img check: add file-size, Vladimir Sementsov-Ogievskiy, 2017/05/25
- [Qemu-devel] [PATCH 7/7] block: rename _get_allocated_file_size() to _get_fs_allocated_size(), Vladimir Sementsov-Ogievskiy, 2017/05/25
- [Qemu-devel] [PATCH 2/7] block: add bdrv_get_format_allocated_size format interface, Vladimir Sementsov-Ogievskiy, 2017/05/25
- [Qemu-devel] [PATCH 5/7] qemu-img check: add format unallocated size, Vladimir Sementsov-Ogievskiy, 2017/05/25
- [Qemu-devel] [PATCH 3/7] qcow2: add .bdrv_get_format_allocated_size,
Vladimir Sementsov-Ogievskiy <=