Message ID | 20170602112158.232757-15-vsementsov@virtuozzo.com |
---|---|
State | New |
Headers | show |
On 06/02/2017 07:21 AM, Vladimir Sementsov-Ogievskiy wrote: > Realize bdrv_reopen_bitmaps_rw interface. > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: John Snow <jsnow@redhat.com> > --- > block/qcow2-bitmap.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > block/qcow2.c | 2 ++ > block/qcow2.h | 1 + > 3 files changed, 64 insertions(+) > > diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c > index 2c7b057e21..a21fab8ce8 100644 > --- a/block/qcow2-bitmap.c > +++ b/block/qcow2-bitmap.c > @@ -826,3 +826,64 @@ fail: > > return false; > } > + > +int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp) > +{ > + BDRVQcow2State *s = bs->opaque; > + Qcow2BitmapList *bm_list; > + Qcow2Bitmap *bm; > + GSList *ro_dirty_bitmaps = NULL; > + int ret = 0; > + > + if (s->nb_bitmaps == 0) { > + /* No bitmaps - nothing to do */ > + return 0; > + } > + > + if (!can_write(bs)) { > + error_setg(errp, "Can't write to the image on reopening bitmaps rw"); > + return -EINVAL; > + } > + > + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, > + s->bitmap_directory_size, errp); > + if (bm_list == NULL) { > + return -EINVAL; > + } > + > + QSIMPLEQ_FOREACH(bm, bm_list, entry) { > + if (!(bm->flags & BME_FLAG_IN_USE)) { > + BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name); > + if (bitmap == NULL) { > + continue; > + } > + > + if (!bdrv_dirty_bitmap_readonly(bitmap)) { > + error_setg(errp, "Bitmap %s is not readonly but not marked" > + "'IN_USE' in the image. Something went wrong," > + "all the bitmaps may be corrupted", bm->name); > + ret = -EINVAL; > + goto out; > + } > + > + bm->flags |= BME_FLAG_IN_USE; > + ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap); > + } > + } > + > + if (ro_dirty_bitmaps != NULL) { > + /* in_use flags must be updated */ > + ret = update_ext_header_and_dir_in_place(bs, bm_list); > + if (ret < 0) { > + error_setg_errno(errp, -ret, "Can't update bitmap directory"); > + goto out; > + } > + g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false); > + } > + > +out: > + g_slist_free(ro_dirty_bitmaps); > + bitmap_list_free(bm_list); > + > + return ret; > +} > diff --git a/block/qcow2.c b/block/qcow2.c > index a70d284b75..ec00db7e49 100644 > --- a/block/qcow2.c > +++ b/block/qcow2.c > @@ -3596,6 +3596,8 @@ BlockDriver bdrv_qcow2 = { > > .bdrv_detach_aio_context = qcow2_detach_aio_context, > .bdrv_attach_aio_context = qcow2_attach_aio_context, > + > + .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw, > }; > > static void bdrv_qcow2_init(void) > diff --git a/block/qcow2.h b/block/qcow2.h > index 67c61de008..3e23bb7361 100644 > --- a/block/qcow2.h > +++ b/block/qcow2.h > @@ -630,5 +630,6 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, > void **refcount_table, > int64_t *refcount_table_size); > bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); > +int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); > > #endif >
On 2017-06-02 13:21, Vladimir Sementsov-Ogievskiy wrote: > Realize bdrv_reopen_bitmaps_rw interface. > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > --- > block/qcow2-bitmap.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > block/qcow2.c | 2 ++ > block/qcow2.h | 1 + > 3 files changed, 64 insertions(+) Reviewed-by: Max Reitz <mreitz@redhat.com>
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 2c7b057e21..a21fab8ce8 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -826,3 +826,64 @@ fail: return false; } + +int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp) +{ + BDRVQcow2State *s = bs->opaque; + Qcow2BitmapList *bm_list; + Qcow2Bitmap *bm; + GSList *ro_dirty_bitmaps = NULL; + int ret = 0; + + if (s->nb_bitmaps == 0) { + /* No bitmaps - nothing to do */ + return 0; + } + + if (!can_write(bs)) { + error_setg(errp, "Can't write to the image on reopening bitmaps rw"); + return -EINVAL; + } + + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, + s->bitmap_directory_size, errp); + if (bm_list == NULL) { + return -EINVAL; + } + + QSIMPLEQ_FOREACH(bm, bm_list, entry) { + if (!(bm->flags & BME_FLAG_IN_USE)) { + BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name); + if (bitmap == NULL) { + continue; + } + + if (!bdrv_dirty_bitmap_readonly(bitmap)) { + error_setg(errp, "Bitmap %s is not readonly but not marked" + "'IN_USE' in the image. Something went wrong," + "all the bitmaps may be corrupted", bm->name); + ret = -EINVAL; + goto out; + } + + bm->flags |= BME_FLAG_IN_USE; + ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap); + } + } + + if (ro_dirty_bitmaps != NULL) { + /* in_use flags must be updated */ + ret = update_ext_header_and_dir_in_place(bs, bm_list); + if (ret < 0) { + error_setg_errno(errp, -ret, "Can't update bitmap directory"); + goto out; + } + g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false); + } + +out: + g_slist_free(ro_dirty_bitmaps); + bitmap_list_free(bm_list); + + return ret; +} diff --git a/block/qcow2.c b/block/qcow2.c index a70d284b75..ec00db7e49 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3596,6 +3596,8 @@ BlockDriver bdrv_qcow2 = { .bdrv_detach_aio_context = qcow2_detach_aio_context, .bdrv_attach_aio_context = qcow2_attach_aio_context, + + .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw, }; static void bdrv_qcow2_init(void) diff --git a/block/qcow2.h b/block/qcow2.h index 67c61de008..3e23bb7361 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -630,5 +630,6 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size); bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); +int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); #endif
Realize bdrv_reopen_bitmaps_rw interface. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> --- block/qcow2-bitmap.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2.c | 2 ++ block/qcow2.h | 1 + 3 files changed, 64 insertions(+)