On 01/26/2016 05:38 AM, Fam Zheng wrote: > By implementing bdrv_dirty_bitmap_set_persistent, a driver can support > the persistent dirty bitmap feature. > > Once a dirty bitmap is made persistent, the driver is responsible for saving > the dirty bitmap when appropriate, for example before close; if a persistent > bitmap is removed or made non-persistent, .bdrv_dirty_bitmap_set_persistent > will be called, the driver should then remove the dirty bitmap from the disk. > > This operation is not recursed in block layer, a filter such as blkdebug needs > to implement the callback and explicitly pass down to bs->file, etc. > > Signed-off-by: Fam Zheng <f...@redhat.com> > --- > block/dirty-bitmap.c | 38 ++++++++++++++++++++++++++++++++++++++ > include/block/block_int.h | 8 ++++++++ > include/block/dirty-bitmap.h | 4 ++++ > 3 files changed, 50 insertions(+) > > diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c > index 1aa7f76..882a0db 100644 > --- a/block/dirty-bitmap.c > +++ b/block/dirty-bitmap.c > @@ -43,6 +43,7 @@ struct BdrvDirtyBitmap { > int64_t size; /* Size of the bitmap (Number of sectors) */ > bool disabled; /* Bitmap is read-only */ > int active_iterators; /* How many iterators are active */ > + bool persistent; /* Whether this bitmap is persistent. */ > QLIST_ENTRY(BdrvDirtyBitmap) list; > }; > > @@ -71,6 +72,37 @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap) > bitmap->name = NULL; > } > > +int bdrv_dirty_bitmap_set_persistent(BlockDriverState *bs, > + BdrvDirtyBitmap *bitmap, > + bool persistent, bool flag_only, > + Error **errp) > +{ > + int ret = 0; > + > + if (!bitmap->name) { > + error_setg(errp, "Cannot change the persistent status of an > anonymous" > + "bitmap"); > + return -EINVAL; > + } > + > + if (persistent == bitmap->persistent) { > + return 0; > + } > + > + if (!flag_only) { > + if (!bs->drv || !bs->drv->bdrv_dirty_bitmap_set_persistent) { > + error_setg(errp, "Not supported in this format."); > + return -ENOTSUP; > + } > + ret = bs->drv->bdrv_dirty_bitmap_set_persistent(bs, bitmap, > persistent, > + errp); > + } > + if (!ret) { > + bitmap->persistent = persistent; > + } > + return ret; > +} > + > BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, > uint32_t granularity, > const char *name, > @@ -194,6 +226,12 @@ int bdrv_dirty_bitmap_create_successor(BlockDriverState > *bs, > uint64_t granularity; > BdrvDirtyBitmap *child; > > + if (bitmap->persistent) { > + error_setg(errp, "Cannot create a successor for a bitmap that is " > + "persistent"); > + return -1; > + } > +
Oh? so we can't make backups with persistent bitmaps? (I'll keep reading forward in the series...) > if (bdrv_dirty_bitmap_frozen(bitmap)) { > error_setg(errp, "Cannot create a successor for a bitmap that is " > "currently frozen"); > diff --git a/include/block/block_int.h b/include/block/block_int.h > index 5fa58e8..fbc34af 100644 > --- a/include/block/block_int.h > +++ b/include/block/block_int.h > @@ -305,6 +305,14 @@ struct BlockDriver { > */ > void (*bdrv_drain)(BlockDriverState *bs); > > + /** > + * Make the dirty bitmap persistent if persistent=true or transient > + * otherwise. > + */ > + int (*bdrv_dirty_bitmap_set_persistent)(BlockDriverState *bs, > + BdrvDirtyBitmap *bitmap, > + bool persistent, Error **errp); > + > QLIST_ENTRY(BlockDriver) list; > }; > > diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h > index d14d923..5885720 100644 > --- a/include/block/dirty-bitmap.h > +++ b/include/block/dirty-bitmap.h > @@ -24,6 +24,10 @@ BdrvDirtyBitmap > *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, > BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, > const char *name); > void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap); > +int bdrv_dirty_bitmap_set_persistent(BlockDriverState *bs, > + BdrvDirtyBitmap *bitmap, > + bool persistent, bool flag_only, > + Error **errp); > void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap > *bitmap); > void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap); > void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap); > -- —js