[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 29/29] qcow2-dirty-bitmap: refcounts
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[Qemu-block] [PATCH 29/29] qcow2-dirty-bitmap: refcounts |
Date: |
Mon, 8 Aug 2016 18:05:20 +0300 |
Calculate refcounts for dirty bitmaps.
Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
Signed-off-by: Denis V. Lunev <address@hidden>
---
block/qcow2-bitmap.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--
block/qcow2-refcount.c | 14 +++++++-----
block/qcow2.h | 5 +++++
3 files changed, 70 insertions(+), 7 deletions(-)
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index def2005..b24fa27 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -253,6 +253,62 @@ static int load_autoload_bitmaps(BlockDriverState *bs,
Error **errp)
return 0;
}
+static int bitmap_table_load(BlockDriverState *bs, QCow2BitmapHeader *bmh,
+ uint64_t **table);
+int qcow2_dirty_bitmaps_refcounts(BlockDriverState *bs,
+ BdrvCheckResult *res,
+ void **refcount_table,
+ int64_t *refcount_table_size)
+{
+ BDRVQcow2State *s = bs->opaque;
+ QCow2BitmapHeader *h,
+ *begin = (QCow2BitmapHeader *)s->bitmap_directory,
+ *end = (QCow2BitmapHeader *)
+ (s->bitmap_directory + s->bitmap_directory_size);
+
+ int i;
+ int ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
+ s->bitmap_directory_offset,
+ s->bitmap_directory_size);
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (h = begin; h < end; h = next_dir_entry(h)) {
+ uint64_t *bitmap_table = NULL;
+
+ ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
+ h->bitmap_table_offset,
+ h->bitmap_table_size);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = bitmap_table_load(bs, h, &bitmap_table);
+ if (ret < 0) {
+ return ret;
+ }
+
+ for (i = 0; i < h->bitmap_table_size; ++i) {
+ uint64_t off = be64_to_cpu(bitmap_table[i]);
+ if (off <= 1) {
+ continue;
+ }
+
+ ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
+ off, s->cluster_size);
+ if (ret < 0) {
+ g_free(bitmap_table);
+ return ret;
+ }
+ }
+
+ g_free(bitmap_table);
+ }
+
+ return 0;
+}
+
static int handle_in_use_bitmaps(BlockDriverState *bs);
int qcow2_read_bitmaps(BlockDriverState *bs, Error **errp)
{
@@ -351,8 +407,6 @@ static void do_free_bitmap_clusters(BlockDriverState *bs,
QCOW2_DISCARD_ALWAYS);
}
-static int bitmap_table_load(BlockDriverState *bs, QCow2BitmapHeader *bmh,
- uint64_t **table);
static int free_bitmap_clusters(BlockDriverState *bs, QCow2BitmapHeader *bmh)
{
int ret;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index cbfb3fe..05bcc57 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1309,11 +1309,9 @@ static int realloc_refcount_array(BDRVQcow2State *s,
void **array,
*
* Modifies the number of errors in res.
*/
-static int inc_refcounts(BlockDriverState *bs,
- BdrvCheckResult *res,
- void **refcount_table,
- int64_t *refcount_table_size,
- int64_t offset, int64_t size)
+int inc_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ void **refcount_table, int64_t *refcount_table_size,
+ int64_t offset, int64_t size)
{
BDRVQcow2State *s = bs->opaque;
uint64_t start, last, cluster_offset, k, refcount;
@@ -1843,6 +1841,12 @@ static int calculate_refcounts(BlockDriverState *bs,
BdrvCheckResult *res,
return ret;
}
+ /* dirty bitmaps */
+ ret = qcow2_dirty_bitmaps_refcounts(bs, res, refcount_table, nb_clusters);
+ if (ret < 0) {
+ return ret;
+ }
+
return check_refblocks(bs, res, fix, rebuild, refcount_table, nb_clusters);
}
diff --git a/block/qcow2.h b/block/qcow2.h
index 74d395b..3359c14 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -564,6 +564,9 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int
ign, int64_t offset,
int64_t size);
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t
offset,
int64_t size);
+int inc_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ void **refcount_table, int64_t *refcount_table_size,
+ int64_t offset, int64_t size);
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb,
@@ -623,6 +626,8 @@ BdrvDirtyBitmap *qcow2_bitmap_load(BlockDriverState *bs,
const char *name,
void qcow2_bitmap_store(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
Error **errp);
int qcow2_delete_bitmaps(BlockDriverState *bs);
+int qcow2_dirty_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ void **refcount_table, int64_t *refcount_table_size);
/* qcow2-cache.c functions */
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables);
--
1.8.3.1
- [Qemu-block] [PATCH 12/29] qcow2: add qcow2_delete_bitmaps, (continued)
- [Qemu-block] [PATCH 17/29] qcow2-bitmap: add autoclear bit, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 10/29] qcow2-bitmap: add IN_USE flag, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 20/29] qcow2-bitmap: add AUTO flag, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 03/29] block: fix bdrv_dirty_bitmap_granularity signature, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 29/29] qcow2-dirty-bitmap: refcounts,
Vladimir Sementsov-Ogievskiy <=
- [Qemu-block] [PATCH 19/29] block/dirty-bitmap: add autoload field to BdrvDirtyBitmap, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 23/29] qmp: add autoload parameter to block-dirty-bitmap-add, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 16/29] block: add bdrv_load_dirty_bitmap(), Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 05/29] qcow2-bitmap: structs and consts, Vladimir Sementsov-Ogievskiy, 2016/08/08
- [Qemu-block] [PATCH 08/29] qcow2-bitmap: delete bitmap from qcow2 after load, Vladimir Sementsov-Ogievskiy, 2016/08/08