diff mbox

[13/22] block: store persistent dirty bitmaps

Message ID 1458072268-53705-14-git-send-email-vsementsov@virtuozzo.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vladimir Sementsov-Ogievskiy March 15, 2016, 8:04 p.m. UTC
Persistent dirty bitmaps are the bitmaps, for which the new field
BdrvDirtyBitmap.file is not NULL. We save all persistent dirty bitmaps
owned by BlockDriverState in corresponding bdrv_close().
BdrvDirtyBitmap.file is a BlockDriverState, where we want to save the
bitmap. It may be set in bdrv_dirty_bitmap_set_file() only once.
bdrv_ref/bdrv_unref are used for BdrvDirtyBitmap.file to be sure that
files will be closed and resources will be freed.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 block.c                      |  2 ++
 block/dirty-bitmap.c         | 35 +++++++++++++++++++++++++++++++++++
 include/block/dirty-bitmap.h |  5 +++++
 3 files changed, 42 insertions(+)
diff mbox

Patch

diff --git a/block.c b/block.c
index 59a18a3..b54875e 100644
--- a/block.c
+++ b/block.c
@@ -2144,6 +2144,8 @@  static void bdrv_close(BlockDriverState *bs)
     bdrv_flush(bs);
     bdrv_drain(bs); /* in case flush left pending I/O */
 
+    /* save and release persistent dirty bitmaps */
+    bdrv_finalize_persistent_dirty_bitmaps(bs);
     bdrv_release_named_dirty_bitmaps(bs);
     assert(QLIST_EMPTY(&bs->dirty_bitmaps));
 
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 7a44722..c9e999f 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -42,6 +42,7 @@  struct BdrvDirtyBitmap {
     char *name;                 /* Optional non-empty unique ID */
     int64_t size;               /* Size of the bitmap (Number of sectors) */
     bool disabled;              /* Bitmap is read-only */
+    bool internal_persistent;   /* bitmap must be saved to owner disk image */
     QLIST_ENTRY(BdrvDirtyBitmap) list;
 };
 
@@ -434,3 +435,37 @@  bool bdrv_load_check_dirty_bitmap(BlockDriverState *file, const char *name)
     }
     return false;
 }
+
+void bdrv_store_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
+                             Error **errp)
+{
+    if (bs == NULL || bs->drv == NULL ||
+            bs->drv->bdrv_dirty_bitmap_store == NULL) {
+        error_setg(errp, "Storing bitmap is unsupported for the format.");
+        return;
+    }
+
+    bs->drv->bdrv_dirty_bitmap_store(bs, bitmap, errp);
+}
+
+void bdrv_dirty_bitmap_set_internal_persistance(BdrvDirtyBitmap *bitmap,
+                                                bool persistent)
+{
+    bitmap->internal_persistent = persistent;
+}
+
+void bdrv_finalize_persistent_dirty_bitmaps(BlockDriverState *bs)
+{
+    BdrvDirtyBitmap *bm, *bm_next;
+
+    QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, bm_next) {
+        if (bm->internal_persistent) {
+            Error *local_err = NULL;
+            bdrv_store_dirty_bitmap(bs, bm, &local_err);
+            if (local_err) {
+                error_report_err(local_err);
+            }
+            bdrv_release_dirty_bitmap(bs, bm);
+        }
+    }
+}
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index f3cedaa..37b5f23 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -54,5 +54,10 @@  int bdrv_dirty_bitmap_store(const BdrvDirtyBitmap *bitmap, BlockDriverState *bs,
                             const uint64_t *table, uint32_t table_size,
                             uint32_t cluster_size);
 bool bdrv_load_check_dirty_bitmap(BlockDriverState *file, const char *name);
+void bdrv_dirty_bitmap_set_internal_persistance(BdrvDirtyBitmap *bitmap,
+                                                bool persistent);
+void bdrv_store_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
+                             Error **errp);
+void bdrv_finalize_persistent_dirty_bitmaps(BlockDriverState *bs);
 
 #endif