Message ID | 20170203154757.36140-11-vsementsov@virtuozzo.com |
---|---|
State | New |
Headers | show |
On Fri, 02/03 18:47, Vladimir Sementsov-Ogievskiy wrote: > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > --- > block/dirty-bitmap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ > include/block/block_int.h | 4 ++++ > include/block/dirty-bitmap.h | 3 +++ > 3 files changed, 60 insertions(+) > > diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c > index 3b7db1d78c..394d4328d5 100644 > --- a/block/dirty-bitmap.c > +++ b/block/dirty-bitmap.c > @@ -545,3 +545,56 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, > return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : > QLIST_NEXT(bitmap, list); > } > + > +typedef struct BDRVLoadBitmapCo { > + BlockDriverState *bs; > + const char *name; > + Error **errp; > + BdrvDirtyBitmap *ret; > + bool in_progress; > +} BDRVLoadBitmapCo; > + > +static void bdrv_load_dity_bitmap_co_entry(void *opaque) Add coroutine_fn? > +{ > + BDRVLoadBitmapCo *lbco = opaque; > + BlockDriver *drv = lbco->bs->drv; > + > + if (!!drv && !!drv->bdrv_dirty_bitmap_load) { > + lbco->ret = drv->bdrv_dirty_bitmap_load(lbco->bs, lbco->name, > + lbco->errp); > + } else if (lbco->bs->file) { > + BlockDriverState *bs = lbco->bs; > + lbco->bs = lbco->bs->file->bs; > + bdrv_load_dity_bitmap_co_entry(lbco); > + if (lbco->ret != NULL) { > + QLIST_REMOVE(lbco->ret, list); > + QLIST_INSERT_HEAD(&bs->dirty_bitmaps, lbco->ret, list); > + } > + } else { > + lbco->ret = NULL; > + } > + > + lbco->in_progress = false; > +} > + > +BdrvDirtyBitmap *bdrv_load_dirty_bitmap(BlockDriverState *bs, const char *name, > + Error **errp) > +{ > + Coroutine *co; > + BDRVLoadBitmapCo lbco = { > + .bs = bs, > + .name = name, > + .errp = errp, > + .in_progress = true > + }; > + > + if (qemu_in_coroutine()) { > + bdrv_load_dity_bitmap_co_entry(&lbco); > + } else { > + co = qemu_coroutine_create(bdrv_load_dity_bitmap_co_entry, &lbco); > + qemu_coroutine_enter(co); > + BDRV_POLL_WHILE(bs, lbco.in_progress); > + } > + > + return lbco.ret; > +} > diff --git a/include/block/block_int.h b/include/block/block_int.h > index 83a423c580..d3770db539 100644 > --- a/include/block/block_int.h > +++ b/include/block/block_int.h > @@ -222,6 +222,10 @@ struct BlockDriver { > int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); > ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs); > > + BdrvDirtyBitmap *(*bdrv_dirty_bitmap_load)(BlockDriverState *bs, > + const char *name, > + Error **errp); > + > int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs, > QEMUIOVector *qiov, > int64_t pos); > diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h > index ff8163ba02..c0c70a8c67 100644 > --- a/include/block/dirty-bitmap.h > +++ b/include/block/dirty-bitmap.h > @@ -77,4 +77,7 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t start); > BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, > BdrvDirtyBitmap *bitmap); > > +BdrvDirtyBitmap *bdrv_load_dirty_bitmap(BlockDriverState *bs, const char *name, > + Error **errp); > + > #endif > -- > 2.11.0 > Otherwise looks good! Fam
On 02/03/2017 06:47 PM, Vladimir Sementsov-Ogievskiy wrote: > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > --- > block/dirty-bitmap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ > include/block/block_int.h | 4 ++++ > include/block/dirty-bitmap.h | 3 +++ > 3 files changed, 60 insertions(+) > > diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c > index 3b7db1d78c..394d4328d5 100644 > --- a/block/dirty-bitmap.c > +++ b/block/dirty-bitmap.c > @@ -545,3 +545,56 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, > return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : > QLIST_NEXT(bitmap, list); > } > + > +typedef struct BDRVLoadBitmapCo { > + BlockDriverState *bs; > + const char *name; > + Error **errp; > + BdrvDirtyBitmap *ret; > + bool in_progress; > +} BDRVLoadBitmapCo; > + > +static void bdrv_load_dity_bitmap_co_entry(void *opaque) > +{ > + BDRVLoadBitmapCo *lbco = opaque; > + BlockDriver *drv = lbco->bs->drv; > + > + if (!!drv && !!drv->bdrv_dirty_bitmap_load) { > + lbco->ret = drv->bdrv_dirty_bitmap_load(lbco->bs, lbco->name, > + lbco->errp); > + } else if (lbco->bs->file) { > + BlockDriverState *bs = lbco->bs; > + lbco->bs = lbco->bs->file->bs; > + bdrv_load_dity_bitmap_co_entry(lbco); > + if (lbco->ret != NULL) { > + QLIST_REMOVE(lbco->ret, list); > + QLIST_INSERT_HEAD(&bs->dirty_bitmaps, lbco->ret, list); > + } > + } else { > + lbco->ret = NULL; > + } > + > + lbco->in_progress = false; > +} > + > +BdrvDirtyBitmap *bdrv_load_dirty_bitmap(BlockDriverState *bs, const char *name, > + Error **errp) > +{ I think that you'd better check bs->drv here and not call coroutine in this case at all. > + Coroutine *co; > + BDRVLoadBitmapCo lbco = { > + .bs = bs, > + .name = name, > + .errp = errp, > + .in_progress = true > + }; > + > + if (qemu_in_coroutine()) { > + bdrv_load_dity_bitmap_co_entry(&lbco); > + } else { > + co = qemu_coroutine_create(bdrv_load_dity_bitmap_co_entry, &lbco); > + qemu_coroutine_enter(co); > + BDRV_POLL_WHILE(bs, lbco.in_progress); > + } > + > + return lbco.ret; > +} > diff --git a/include/block/block_int.h b/include/block/block_int.h > index 83a423c580..d3770db539 100644 > --- a/include/block/block_int.h > +++ b/include/block/block_int.h > @@ -222,6 +222,10 @@ struct BlockDriver { > int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); > ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs); > > + BdrvDirtyBitmap *(*bdrv_dirty_bitmap_load)(BlockDriverState *bs, > + const char *name, > + Error **errp); > + > int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs, > QEMUIOVector *qiov, > int64_t pos); > diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h > index ff8163ba02..c0c70a8c67 100644 > --- a/include/block/dirty-bitmap.h > +++ b/include/block/dirty-bitmap.h > @@ -77,4 +77,7 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t start); > BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, > BdrvDirtyBitmap *bitmap); > > +BdrvDirtyBitmap *bdrv_load_dirty_bitmap(BlockDriverState *bs, const char *name, > + Error **errp); > + > #endif
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 3b7db1d78c..394d4328d5 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -545,3 +545,56 @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : QLIST_NEXT(bitmap, list); } + +typedef struct BDRVLoadBitmapCo { + BlockDriverState *bs; + const char *name; + Error **errp; + BdrvDirtyBitmap *ret; + bool in_progress; +} BDRVLoadBitmapCo; + +static void bdrv_load_dity_bitmap_co_entry(void *opaque) +{ + BDRVLoadBitmapCo *lbco = opaque; + BlockDriver *drv = lbco->bs->drv; + + if (!!drv && !!drv->bdrv_dirty_bitmap_load) { + lbco->ret = drv->bdrv_dirty_bitmap_load(lbco->bs, lbco->name, + lbco->errp); + } else if (lbco->bs->file) { + BlockDriverState *bs = lbco->bs; + lbco->bs = lbco->bs->file->bs; + bdrv_load_dity_bitmap_co_entry(lbco); + if (lbco->ret != NULL) { + QLIST_REMOVE(lbco->ret, list); + QLIST_INSERT_HEAD(&bs->dirty_bitmaps, lbco->ret, list); + } + } else { + lbco->ret = NULL; + } + + lbco->in_progress = false; +} + +BdrvDirtyBitmap *bdrv_load_dirty_bitmap(BlockDriverState *bs, const char *name, + Error **errp) +{ + Coroutine *co; + BDRVLoadBitmapCo lbco = { + .bs = bs, + .name = name, + .errp = errp, + .in_progress = true + }; + + if (qemu_in_coroutine()) { + bdrv_load_dity_bitmap_co_entry(&lbco); + } else { + co = qemu_coroutine_create(bdrv_load_dity_bitmap_co_entry, &lbco); + qemu_coroutine_enter(co); + BDRV_POLL_WHILE(bs, lbco.in_progress); + } + + return lbco.ret; +} diff --git a/include/block/block_int.h b/include/block/block_int.h index 83a423c580..d3770db539 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -222,6 +222,10 @@ struct BlockDriver { int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs); + BdrvDirtyBitmap *(*bdrv_dirty_bitmap_load)(BlockDriverState *bs, + const char *name, + Error **errp); + int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index ff8163ba02..c0c70a8c67 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -77,4 +77,7 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t start); BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +BdrvDirtyBitmap *bdrv_load_dirty_bitmap(BlockDriverState *bs, const char *name, + Error **errp); + #endif
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> --- block/dirty-bitmap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ include/block/block_int.h | 4 ++++ include/block/dirty-bitmap.h | 3 +++ 3 files changed, 60 insertions(+)