From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36195) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z1zVr-0001pb-7N for qemu-devel@nongnu.org; Mon, 08 Jun 2015 12:03:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z1zVn-0001F8-EK for qemu-devel@nongnu.org; Mon, 08 Jun 2015 12:02:59 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:38531 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z1zVn-00018U-00 for qemu-devel@nongnu.org; Mon, 08 Jun 2015 12:02:55 -0400 From: Vladimir Sementsov-Ogievskiy Date: Mon, 8 Jun 2015 18:21:21 +0300 Message-Id: <1433776886-27239-4-git-send-email-vsementsov@virtuozzo.com> In-Reply-To: <1433776886-27239-1-git-send-email-vsementsov@virtuozzo.com> References: <1433776886-27239-1-git-send-email-vsementsov@virtuozzo.com> Subject: [Qemu-devel] [PATCH 3/8] block: store persistent dirty bitmaps List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, Vladimir Sementsov-Ogievskiy , stefanha@redhat.com, pbonzini@redhat.com, den@openvz.org, jsnow@redhat.com From: Vladimir Sementsov-Ogievskiy 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 --- block.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/block/block.h | 4 ++++ 2 files changed, 49 insertions(+) diff --git a/block.c b/block.c index 575584d..74d4edc 100644 --- a/block.c +++ b/block.c @@ -70,6 +70,8 @@ struct BdrvDirtyBitmap { BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */ char *name; /* Optional non-empty unique ID */ int64_t size; /* Size of the bitmap (Number of sectors) */ + BlockDriverState *file; /* File where bitmap is loaded from (and should + be saved to) */ bool disabled; /* Bitmap is read-only */ QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -1710,6 +1712,7 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state) void bdrv_close(BlockDriverState *bs) { BdrvAioNotifier *ban, *ban_next; + BdrvDirtyBitmap *bm, *bm_next; if (bs->job) { block_job_cancel_sync(bs->job); @@ -1719,6 +1722,15 @@ void bdrv_close(BlockDriverState *bs) bdrv_drain_all(); /* in case flush left pending I/O */ notifier_list_notify(&bs->close_notifiers, bs); + /* save and release persistent dirty bitmaps */ + QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, bm_next) { + if (bm->file) { + bdrv_store_dirty_bitmap(bm); + bdrv_unref(bm->file); + bdrv_release_dirty_bitmap(bs, bm); + } + } + if (bs->drv) { if (bs->backing_hd) { BlockDriverState *backing_hd = bs->backing_hd; @@ -3097,6 +3109,30 @@ void bdrv_release_meta_bitmap(BdrvDirtyBitmap *bitmap) } } +int bdrv_store_dirty_bitmap(BdrvDirtyBitmap *bitmap) +{ + BlockDriverState *bs = bitmap->file; + uint8_t *buf; + uint64_t size; + assert(bs); + assert(bs->drv); + assert(bs->drv->bdrv_dirty_bitmap_store); + + size = hbitmap_data_size(bitmap->bitmap, bitmap->size); + size = (size + 3) & ~3; + buf = g_malloc(size); + + hbitmap_serialize_part(bitmap->bitmap, buf, 0, bitmap->size); + + int res = bs->drv->bdrv_dirty_bitmap_store(bs, buf, + bitmap->name, + bitmap->size, + bdrv_dirty_bitmap_granularity(bitmap)); + + g_free(buf); + return res; +} + BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, uint32_t granularity, const char *name, @@ -3257,6 +3293,15 @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) } } +void bdrv_dirty_bitmap_set_file(BdrvDirtyBitmap *bitmap, BlockDriverState *file) +{ + assert(bitmap->file == NULL); + bitmap->file = file; + if (file != NULL) { + bdrv_ref(file); + } +} + void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap) { assert(!bdrv_dirty_bitmap_frozen(bitmap)); diff --git a/include/block/block.h b/include/block/block.h index 593c29e..6e82597 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -468,6 +468,8 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name); void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_dirty_bitmap_set_file(BdrvDirtyBitmap *bitmap, + BlockDriverState *file); void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap); void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); @@ -506,6 +508,8 @@ HBitmap *bdrv_create_meta_bitmap(BdrvDirtyBitmap *bitmap, uint64_t granularity); void bdrv_release_meta_bitmap(BdrvDirtyBitmap *bitmap); +int bdrv_store_dirty_bitmap(BdrvDirtyBitmap *bitmap); + void bdrv_enable_copy_on_read(BlockDriverState *bs); void bdrv_disable_copy_on_read(BlockDriverState *bs); -- 1.9.1