[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH v3 07/10] block: add delayed bitmap successor cleanu
From: |
John Snow |
Subject: |
[Qemu-block] [PATCH v3 07/10] block: add delayed bitmap successor cleanup |
Date: |
Wed, 22 Apr 2015 20:04:50 -0400 |
Allow bitmap successors to carry reference counts.
We can in a later patch use this ability to clean up the dirty bitmap
according to both the individual job's success and the success of all
jobs in the transaction group.
The code for cleaning up a bitmap is also moved from backup_run to
backup_complete.
Signed-off-by: John Snow <address@hidden>
Reviewed-by: Max Reitz <address@hidden>
---
block.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++-----
block/backup.c | 20 ++++++----------
include/block/block.h | 10 ++++----
3 files changed, 70 insertions(+), 25 deletions(-)
diff --git a/block.c b/block.c
index b29aafe..0e7308c 100644
--- a/block.c
+++ b/block.c
@@ -51,6 +51,12 @@
#include <windows.h>
#endif
+typedef enum BitmapSuccessorAction {
+ SUCCESSOR_ACTION_UNDEFINED = 0,
+ SUCCESSOR_ACTION_ABDICATE,
+ SUCCESSOR_ACTION_RECLAIM
+} BitmapSuccessorAction;
+
/**
* A BdrvDirtyBitmap can be in three possible states:
* (1) successor is NULL and disabled is false: full r/w mode
@@ -65,6 +71,8 @@ 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 */
+ int successor_refcount; /* Number of active handles to the successor */
+ BitmapSuccessorAction act; /* Action to take on successor upon release */
QLIST_ENTRY(BdrvDirtyBitmap) list;
};
@@ -5540,6 +5548,7 @@ int bdrv_dirty_bitmap_create_successor(BlockDriverState
*bs,
/* Install the successor and freeze the parent */
bitmap->successor = child;
+ bitmap->successor_refcount = 1;
return 0;
}
@@ -5547,9 +5556,9 @@ int bdrv_dirty_bitmap_create_successor(BlockDriverState
*bs,
* For a bitmap with a successor, yield our name to the successor,
* delete the old bitmap, and return a handle to the new bitmap.
*/
-BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
- BdrvDirtyBitmap *bitmap,
- Error **errp)
+static BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
+ BdrvDirtyBitmap *bitmap,
+ Error **errp)
{
char *name;
BdrvDirtyBitmap *successor = bitmap->successor;
@@ -5574,9 +5583,9 @@ BdrvDirtyBitmap
*bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
* we may wish to re-join the parent and child/successor.
* The merged parent will be un-frozen, but not explicitly re-enabled.
*/
-BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
- BdrvDirtyBitmap *parent,
- Error **errp)
+static BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
+ BdrvDirtyBitmap *parent,
+ Error **errp)
{
BdrvDirtyBitmap *successor = parent->successor;
@@ -5595,6 +5604,50 @@ BdrvDirtyBitmap
*bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
return parent;
}
+static BdrvDirtyBitmap *bdrv_free_bitmap_successor(BlockDriverState *bs,
+ BdrvDirtyBitmap *parent)
+{
+ assert(!parent->successor_refcount);
+
+ switch (parent->act) {
+ case SUCCESSOR_ACTION_RECLAIM:
+ return bdrv_reclaim_dirty_bitmap(bs, parent, NULL);
+ case SUCCESSOR_ACTION_ABDICATE:
+ return bdrv_dirty_bitmap_abdicate(bs, parent, NULL);
+ case SUCCESSOR_ACTION_UNDEFINED:
+ default:
+ g_assert_not_reached();
+ }
+}
+
+BdrvDirtyBitmap *bdrv_frozen_bitmap_decref(BlockDriverState *bs,
+ BdrvDirtyBitmap *parent,
+ int ret)
+{
+ assert(bdrv_dirty_bitmap_frozen(parent));
+ assert(parent->successor);
+
+ if (ret) {
+ parent->act = SUCCESSOR_ACTION_RECLAIM;
+ } else if (parent->act != SUCCESSOR_ACTION_RECLAIM) {
+ parent->act = SUCCESSOR_ACTION_ABDICATE;
+ }
+
+ parent->successor_refcount--;
+ if (parent->successor_refcount == 0) {
+ return bdrv_free_bitmap_successor(bs, parent);
+ }
+ return parent;
+}
+
+void bdrv_dirty_bitmap_incref(BdrvDirtyBitmap *parent)
+{
+ assert(bdrv_dirty_bitmap_frozen(parent));
+ assert(parent->successor);
+
+ parent->successor_refcount++;
+}
+
/**
* Truncates _all_ bitmaps attached to a BDS.
*/
diff --git a/block/backup.c b/block/backup.c
index a297df6..62f8d2b 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -240,6 +240,12 @@ static void backup_complete(BlockJob *job, void *opaque)
bdrv_unref(s->target);
+ if (s->sync_bitmap) {
+ BdrvDirtyBitmap *bm;
+ bm = bdrv_frozen_bitmap_decref(job->bs, s->sync_bitmap, data->ret);
+ assert(bm);
+ }
+
block_job_completed(job, data->ret);
g_free(data);
}
@@ -428,18 +434,6 @@ static void coroutine_fn backup_run(void *opaque)
qemu_co_rwlock_wrlock(&job->flush_rwlock);
qemu_co_rwlock_unlock(&job->flush_rwlock);
- if (job->sync_bitmap) {
- BdrvDirtyBitmap *bm;
- if (ret < 0) {
- /* Merge the successor back into the parent, delete nothing. */
- bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
- assert(bm);
- } else {
- /* Everything is fine, delete this bitmap and install the backup.
*/
- bm = bdrv_dirty_bitmap_abdicate(bs, job->sync_bitmap, NULL);
- assert(bm);
- }
- }
hbitmap_free(job->bitmap);
bdrv_iostatus_disable(target);
@@ -543,6 +537,6 @@ void backup_start(BlockDriverState *bs, BlockDriverState
*target,
error:
if (sync_bitmap) {
- bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
+ bdrv_frozen_bitmap_decref(bs, sync_bitmap, -ECANCELED);
}
}
diff --git a/include/block/block.h b/include/block/block.h
index 36bdf04..7b548b1 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -456,12 +456,10 @@ BdrvDirtyBitmap
*bdrv_create_dirty_bitmap(BlockDriverState *bs,
int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
BdrvDirtyBitmap *bitmap,
Error **errp);
-BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
- BdrvDirtyBitmap *bitmap,
- Error **errp);
-BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
- BdrvDirtyBitmap *bitmap,
- Error **errp);
+BdrvDirtyBitmap *bdrv_frozen_bitmap_decref(BlockDriverState *bs,
+ BdrvDirtyBitmap *parent,
+ int ret);
+void bdrv_dirty_bitmap_incref(BdrvDirtyBitmap *parent);
BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs,
const char *name);
void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap);
--
2.1.0
- Re: [Qemu-block] [PATCH v3 01/10] qapi: Add transaction support to block-dirty-bitmap operations, (continued)
- [Qemu-block] [PATCH v3 03/10] block: rename BlkTransactionState and BdrvActionOps, John Snow, 2015/04/22
- [Qemu-block] [PATCH v3 04/10] block: re-add BlkTransactionState, John Snow, 2015/04/22
- [Qemu-block] [PATCH v3 06/10] block: add refcount to Job object, John Snow, 2015/04/22
- [Qemu-block] [PATCH v3 05/10] block: add transactional callbacks feature, John Snow, 2015/04/22
- [Qemu-block] [PATCH v3 08/10] qmp: Add an implementation wrapper for qmp_drive_backup, John Snow, 2015/04/22
- [Qemu-block] [PATCH v3 09/10] block: drive_backup transaction callback support, John Snow, 2015/04/22
- [Qemu-block] [PATCH v3 07/10] block: add delayed bitmap successor cleanup,
John Snow <=
- [Qemu-block] [PATCH v3 10/10] iotests: 124 - transactional failure test, John Snow, 2015/04/22