On 25.02.2017 18:07, Vladimir Sementsov-Ogievskiy wrote: > Auto loading bitmaps are bitmaps in Qcow2, with the AUTO flag set. They > are loaded when the image is opened and become BdrvDirtyBitmaps for the > corresponding drive. > > Extra data in bitmaps is not supported for now. > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> > --- > block/qcow2-bitmap.c | 367 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > block/qcow2.c | 7 + > block/qcow2.h | 2 + > 3 files changed, 376 insertions(+) > > diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c > index b8e472b3e8..73a6e87038 100644 > --- a/block/qcow2-bitmap.c > +++ b/block/qcow2-bitmap.c
[...] > +static int update_ext_header_and_dir_in_place(BlockDriverState *bs, > + Qcow2BitmapList *bm_list) > +{ > + BDRVQcow2State *s = bs->opaque; > + int ret; > + > + if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS) || > + bm_list == NULL || QSIMPLEQ_EMPTY(bm_list) || > + bitmap_list_count(bm_list) != s->nb_bitmaps) > + { > + return -EINVAL; > + } > + > + s->autoclear_features &= ~(uint64_t)QCOW2_AUTOCLEAR_BITMAPS; > + ret = update_header_sync(bs); > + if (ret < 0) { > + /* Two variants are possible here: > + * 1. Autoclear flag is dropped, all bitmaps will be lost. > + * 2. Autoclear flag is not dropped, old state is left. > + */ > + return ret; > + } > + > + /* autoclear bit is not set, so we can safely update bitmap directory */ > + > + ret = bitmap_list_store(bs, bm_list, &s->bitmap_directory_offset, > + &s->bitmap_directory_size, true); > + if (ret < 0) { > + /* autoclear bit is cleared, so all leaked clusters would be removed > on > + * qemu-img check */ > + return ret; > + } > + > + ret = update_header_sync(bs); > + if (ret < 0) { > + /* autoclear bit is cleared, so all leaked clusters would be removed > on > + * qemu-img check */ > + return ret; > + } > + > + s->autoclear_features |= QCOW2_AUTOCLEAR_BITMAPS; > + return update_header_sync(bs); > + /* If final update_header_sync() fails, two variants are possible: > + * 1. Autoclear flag is not set, all bitmaps will be lost. > + * 2. Autoclear flag is set, header and directory are successfully > updated. > + */ Oh, nice. Thanks for the explanations, too. This way I'm very much fine with update_header_sync() failing if bdrv_flush() fails. > +} > + > +/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */ > +static void release_dirty_bitmap_helper(gpointer bitmap, > + gpointer bs) > +{ > + bdrv_release_dirty_bitmap(bs, bitmap); > +} [...] > diff --git a/block/qcow2.c b/block/qcow2.c > index 6cd411f9c5..f4bb9d46de 100644 > --- a/block/qcow2.c > +++ b/block/qcow2.c > @@ -1237,6 +1237,13 @@ static int qcow2_open(BlockDriverState *bs, QDict > *options, int flags, > goto fail; > } > > + qcow2_load_autoloading_dirty_bitmaps(bs, &local_err); > + if (local_err != NULL) { > + error_propagate(errp, local_err); > + ret = -EINVAL; > + goto fail; > + } > + > /* Clear unknown autoclear feature bits */ > need_update_header |= s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK; > I think it would be better to load the dirty bitmaps after clearing unknown autoclear bits, because loading the bitmaps may result in modifications of the image file. Max
signature.asc
Description: OpenPGP digital signature