1ebab2259SFam Zheng /* 2ebab2259SFam Zheng * Block Dirty Bitmap 3ebab2259SFam Zheng * 41b6cc579SEric Blake * Copyright (c) 2016-2017 Red Hat. Inc 5ebab2259SFam Zheng * 6ebab2259SFam Zheng * Permission is hereby granted, free of charge, to any person obtaining a copy 7ebab2259SFam Zheng * of this software and associated documentation files (the "Software"), to deal 8ebab2259SFam Zheng * in the Software without restriction, including without limitation the rights 9ebab2259SFam Zheng * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10ebab2259SFam Zheng * copies of the Software, and to permit persons to whom the Software is 11ebab2259SFam Zheng * furnished to do so, subject to the following conditions: 12ebab2259SFam Zheng * 13ebab2259SFam Zheng * The above copyright notice and this permission notice shall be included in 14ebab2259SFam Zheng * all copies or substantial portions of the Software. 15ebab2259SFam Zheng * 16ebab2259SFam Zheng * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17ebab2259SFam Zheng * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18ebab2259SFam Zheng * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19ebab2259SFam Zheng * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20ebab2259SFam Zheng * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21ebab2259SFam Zheng * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22ebab2259SFam Zheng * THE SOFTWARE. 23ebab2259SFam Zheng */ 24ebab2259SFam Zheng #include "qemu/osdep.h" 25da34e65cSMarkus Armbruster #include "qapi/error.h" 26ebab2259SFam Zheng #include "qemu-common.h" 27ebab2259SFam Zheng #include "trace.h" 28ebab2259SFam Zheng #include "block/block_int.h" 29ebab2259SFam Zheng #include "block/blockjob.h" 30ebab2259SFam Zheng 31ebab2259SFam Zheng /** 32ebab2259SFam Zheng * A BdrvDirtyBitmap can be in three possible states: 33ebab2259SFam Zheng * (1) successor is NULL and disabled is false: full r/w mode 34ebab2259SFam Zheng * (2) successor is NULL and disabled is true: read only mode ("disabled") 35ebab2259SFam Zheng * (3) successor is set: frozen mode. 36ebab2259SFam Zheng * A frozen bitmap cannot be renamed, deleted, anonymized, cleared, set, 37ebab2259SFam Zheng * or enabled. A frozen bitmap can only abdicate() or reclaim(). 38ebab2259SFam Zheng */ 39ebab2259SFam Zheng struct BdrvDirtyBitmap { 40b64bd51eSPaolo Bonzini QemuMutex *mutex; 41ca759622SEric Blake HBitmap *bitmap; /* Dirty bitmap implementation */ 42fb933437SFam Zheng HBitmap *meta; /* Meta dirty bitmap */ 434f43e953SVladimir Sementsov-Ogievskiy bool qmp_locked; /* Bitmap is locked, it can't be modified 444f43e953SVladimir Sementsov-Ogievskiy through QMP */ 45ebab2259SFam Zheng BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */ 46ebab2259SFam Zheng char *name; /* Optional non-empty unique ID */ 47993e6525SEric Blake int64_t size; /* Size of the bitmap, in bytes */ 488bfc932eSVladimir Sementsov-Ogievskiy bool disabled; /* Bitmap is disabled. It ignores all writes to 498bfc932eSVladimir Sementsov-Ogievskiy the device */ 50dc162c8eSFam Zheng int active_iterators; /* How many iterators are active */ 51d6883bc9SVladimir Sementsov-Ogievskiy bool readonly; /* Bitmap is read-only. This field also 52d6883bc9SVladimir Sementsov-Ogievskiy prevents the respective image from being 53d6883bc9SVladimir Sementsov-Ogievskiy modified (i.e. blocks writes and discards). 54d6883bc9SVladimir Sementsov-Ogievskiy Such operations must fail and both the image 55d6883bc9SVladimir Sementsov-Ogievskiy and this bitmap must remain unchanged while 56d6883bc9SVladimir Sementsov-Ogievskiy this flag is set. */ 57a88b179fSVladimir Sementsov-Ogievskiy bool persistent; /* bitmap must be saved to owner disk image */ 58ebab2259SFam Zheng QLIST_ENTRY(BdrvDirtyBitmap) list; 59ebab2259SFam Zheng }; 60ebab2259SFam Zheng 61dc162c8eSFam Zheng struct BdrvDirtyBitmapIter { 62dc162c8eSFam Zheng HBitmapIter hbi; 63dc162c8eSFam Zheng BdrvDirtyBitmap *bitmap; 64dc162c8eSFam Zheng }; 65dc162c8eSFam Zheng 662119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs) 672119882cSPaolo Bonzini { 682119882cSPaolo Bonzini qemu_mutex_lock(&bs->dirty_bitmap_mutex); 692119882cSPaolo Bonzini } 702119882cSPaolo Bonzini 712119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs) 722119882cSPaolo Bonzini { 732119882cSPaolo Bonzini qemu_mutex_unlock(&bs->dirty_bitmap_mutex); 742119882cSPaolo Bonzini } 752119882cSPaolo Bonzini 76b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap) 77b64bd51eSPaolo Bonzini { 78b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 79b64bd51eSPaolo Bonzini } 80b64bd51eSPaolo Bonzini 81b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap) 82b64bd51eSPaolo Bonzini { 83b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 84b64bd51eSPaolo Bonzini } 85b64bd51eSPaolo Bonzini 862119882cSPaolo Bonzini /* Called with BQL or dirty_bitmap lock taken. */ 87ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name) 88ebab2259SFam Zheng { 89ebab2259SFam Zheng BdrvDirtyBitmap *bm; 90ebab2259SFam Zheng 91ebab2259SFam Zheng assert(name); 92ebab2259SFam Zheng QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 93ebab2259SFam Zheng if (bm->name && !strcmp(name, bm->name)) { 94ebab2259SFam Zheng return bm; 95ebab2259SFam Zheng } 96ebab2259SFam Zheng } 97ebab2259SFam Zheng return NULL; 98ebab2259SFam Zheng } 99ebab2259SFam Zheng 1002119882cSPaolo Bonzini /* Called with BQL taken. */ 101ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, 102ebab2259SFam Zheng uint32_t granularity, 103ebab2259SFam Zheng const char *name, 104ebab2259SFam Zheng Error **errp) 105ebab2259SFam Zheng { 106ebab2259SFam Zheng int64_t bitmap_size; 107ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 108ebab2259SFam Zheng 109993e6525SEric Blake assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE); 110ebab2259SFam Zheng 111ebab2259SFam Zheng if (name && bdrv_find_dirty_bitmap(bs, name)) { 112ebab2259SFam Zheng error_setg(errp, "Bitmap already exists: %s", name); 113ebab2259SFam Zheng return NULL; 114ebab2259SFam Zheng } 115993e6525SEric Blake bitmap_size = bdrv_getlength(bs); 116ebab2259SFam Zheng if (bitmap_size < 0) { 117ebab2259SFam Zheng error_setg_errno(errp, -bitmap_size, "could not get length of device"); 118ebab2259SFam Zheng errno = -bitmap_size; 119ebab2259SFam Zheng return NULL; 120ebab2259SFam Zheng } 121ebab2259SFam Zheng bitmap = g_new0(BdrvDirtyBitmap, 1); 122b64bd51eSPaolo Bonzini bitmap->mutex = &bs->dirty_bitmap_mutex; 123ca759622SEric Blake bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity)); 124ebab2259SFam Zheng bitmap->size = bitmap_size; 125ebab2259SFam Zheng bitmap->name = g_strdup(name); 126ebab2259SFam Zheng bitmap->disabled = false; 1272119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 128ebab2259SFam Zheng QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list); 1292119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 130ebab2259SFam Zheng return bitmap; 131ebab2259SFam Zheng } 132ebab2259SFam Zheng 133fb933437SFam Zheng /* bdrv_create_meta_dirty_bitmap 134fb933437SFam Zheng * 135fb933437SFam Zheng * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e. 136fb933437SFam Zheng * when a dirty status bit in @bitmap is changed (either from reset to set or 137fb933437SFam Zheng * the other way around), its respective meta dirty bitmap bit will be marked 138fb933437SFam Zheng * dirty as well. 139fb933437SFam Zheng * 140fb933437SFam Zheng * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap. 141fb933437SFam Zheng * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap 142fb933437SFam Zheng * track. 143fb933437SFam Zheng */ 144fb933437SFam Zheng void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap, 145fb933437SFam Zheng int chunk_size) 146fb933437SFam Zheng { 147fb933437SFam Zheng assert(!bitmap->meta); 148b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 149fb933437SFam Zheng bitmap->meta = hbitmap_create_meta(bitmap->bitmap, 150fb933437SFam Zheng chunk_size * BITS_PER_BYTE); 151b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 152fb933437SFam Zheng } 153fb933437SFam Zheng 154fb933437SFam Zheng void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap) 155fb933437SFam Zheng { 156fb933437SFam Zheng assert(bitmap->meta); 157b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 158fb933437SFam Zheng hbitmap_free_meta(bitmap->bitmap); 159fb933437SFam Zheng bitmap->meta = NULL; 160b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 161fb933437SFam Zheng } 162fb933437SFam Zheng 16315891facSFam Zheng int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap) 16415891facSFam Zheng { 165993e6525SEric Blake return bitmap->size; 16615891facSFam Zheng } 16715891facSFam Zheng 16815891facSFam Zheng const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap) 16915891facSFam Zheng { 17015891facSFam Zheng return bitmap->name; 17115891facSFam Zheng } 17215891facSFam Zheng 1732119882cSPaolo Bonzini /* Called with BQL taken. */ 174ebab2259SFam Zheng bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap) 175ebab2259SFam Zheng { 176ebab2259SFam Zheng return bitmap->successor; 177ebab2259SFam Zheng } 178ebab2259SFam Zheng 1794f43e953SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked) 1804f43e953SVladimir Sementsov-Ogievskiy { 1814f43e953SVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 1824f43e953SVladimir Sementsov-Ogievskiy bitmap->qmp_locked = qmp_locked; 1834f43e953SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 1844f43e953SVladimir Sementsov-Ogievskiy } 1854f43e953SVladimir Sementsov-Ogievskiy 1864f43e953SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap) 1874f43e953SVladimir Sementsov-Ogievskiy { 1884f43e953SVladimir Sementsov-Ogievskiy return bitmap->qmp_locked; 1894f43e953SVladimir Sementsov-Ogievskiy } 1904f43e953SVladimir Sementsov-Ogievskiy 1912119882cSPaolo Bonzini /* Called with BQL taken. */ 192ebab2259SFam Zheng bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap) 193ebab2259SFam Zheng { 194ebab2259SFam Zheng return !(bitmap->disabled || bitmap->successor); 195ebab2259SFam Zheng } 196ebab2259SFam Zheng 1972119882cSPaolo Bonzini /* Called with BQL taken. */ 198ebab2259SFam Zheng DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap) 199ebab2259SFam Zheng { 200ebab2259SFam Zheng if (bdrv_dirty_bitmap_frozen(bitmap)) { 201ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_FROZEN; 2024f43e953SVladimir Sementsov-Ogievskiy } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { 2034f43e953SVladimir Sementsov-Ogievskiy return DIRTY_BITMAP_STATUS_LOCKED; 204ebab2259SFam Zheng } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { 205ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_DISABLED; 206ebab2259SFam Zheng } else { 207ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_ACTIVE; 208ebab2259SFam Zheng } 209ebab2259SFam Zheng } 210ebab2259SFam Zheng 211ebab2259SFam Zheng /** 212ebab2259SFam Zheng * Create a successor bitmap destined to replace this bitmap after an operation. 213ebab2259SFam Zheng * Requires that the bitmap is not frozen and has no successor. 2142119882cSPaolo Bonzini * Called with BQL taken. 215ebab2259SFam Zheng */ 216ebab2259SFam Zheng int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs, 217ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, Error **errp) 218ebab2259SFam Zheng { 219ebab2259SFam Zheng uint64_t granularity; 220ebab2259SFam Zheng BdrvDirtyBitmap *child; 221ebab2259SFam Zheng 222ebab2259SFam Zheng if (bdrv_dirty_bitmap_frozen(bitmap)) { 223ebab2259SFam Zheng error_setg(errp, "Cannot create a successor for a bitmap that is " 224ebab2259SFam Zheng "currently frozen"); 225ebab2259SFam Zheng return -1; 226ebab2259SFam Zheng } 227ebab2259SFam Zheng assert(!bitmap->successor); 228ebab2259SFam Zheng 229ebab2259SFam Zheng /* Create an anonymous successor */ 230ebab2259SFam Zheng granularity = bdrv_dirty_bitmap_granularity(bitmap); 231ebab2259SFam Zheng child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); 232ebab2259SFam Zheng if (!child) { 233ebab2259SFam Zheng return -1; 234ebab2259SFam Zheng } 235ebab2259SFam Zheng 236ebab2259SFam Zheng /* Successor will be on or off based on our current state. */ 237ebab2259SFam Zheng child->disabled = bitmap->disabled; 238ebab2259SFam Zheng 239ebab2259SFam Zheng /* Install the successor and freeze the parent */ 240ebab2259SFam Zheng bitmap->successor = child; 241ebab2259SFam Zheng return 0; 242ebab2259SFam Zheng } 243ebab2259SFam Zheng 244e73a265eSVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 245e73a265eSVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap) 246e73a265eSVladimir Sementsov-Ogievskiy { 247e73a265eSVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 248e73a265eSVladimir Sementsov-Ogievskiy bdrv_enable_dirty_bitmap(bitmap->successor); 249e73a265eSVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 250e73a265eSVladimir Sementsov-Ogievskiy } 251e73a265eSVladimir Sementsov-Ogievskiy 252b133c27fSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */ 253b133c27fSPaolo Bonzini static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap) 254604ab74bSVladimir Sementsov-Ogievskiy { 255b133c27fSPaolo Bonzini assert(!bitmap->active_iterators); 256b133c27fSPaolo Bonzini assert(!bdrv_dirty_bitmap_frozen(bitmap)); 257b133c27fSPaolo Bonzini assert(!bitmap->meta); 258b133c27fSPaolo Bonzini QLIST_REMOVE(bitmap, list); 259b133c27fSPaolo Bonzini hbitmap_free(bitmap->bitmap); 260b133c27fSPaolo Bonzini g_free(bitmap->name); 261b133c27fSPaolo Bonzini g_free(bitmap); 262604ab74bSVladimir Sementsov-Ogievskiy } 263604ab74bSVladimir Sementsov-Ogievskiy 264ebab2259SFam Zheng /** 265ebab2259SFam Zheng * For a bitmap with a successor, yield our name to the successor, 266ebab2259SFam Zheng * delete the old bitmap, and return a handle to the new bitmap. 2672119882cSPaolo Bonzini * Called with BQL taken. 268ebab2259SFam Zheng */ 269ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs, 270ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, 271ebab2259SFam Zheng Error **errp) 272ebab2259SFam Zheng { 273ebab2259SFam Zheng char *name; 274ebab2259SFam Zheng BdrvDirtyBitmap *successor = bitmap->successor; 275ebab2259SFam Zheng 276ebab2259SFam Zheng if (successor == NULL) { 277ebab2259SFam Zheng error_setg(errp, "Cannot relinquish control if " 278ebab2259SFam Zheng "there's no successor present"); 279ebab2259SFam Zheng return NULL; 280ebab2259SFam Zheng } 281ebab2259SFam Zheng 282ebab2259SFam Zheng name = bitmap->name; 283ebab2259SFam Zheng bitmap->name = NULL; 284ebab2259SFam Zheng successor->name = name; 285ebab2259SFam Zheng bitmap->successor = NULL; 286a88b179fSVladimir Sementsov-Ogievskiy successor->persistent = bitmap->persistent; 287a88b179fSVladimir Sementsov-Ogievskiy bitmap->persistent = false; 288ebab2259SFam Zheng bdrv_release_dirty_bitmap(bs, bitmap); 289ebab2259SFam Zheng 290ebab2259SFam Zheng return successor; 291ebab2259SFam Zheng } 292ebab2259SFam Zheng 293ebab2259SFam Zheng /** 294ebab2259SFam Zheng * In cases of failure where we can no longer safely delete the parent, 295ebab2259SFam Zheng * we may wish to re-join the parent and child/successor. 296ebab2259SFam Zheng * The merged parent will be un-frozen, but not explicitly re-enabled. 297044ee8e1SVladimir Sementsov-Ogievskiy * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. 298ebab2259SFam Zheng */ 299044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs, 300ebab2259SFam Zheng BdrvDirtyBitmap *parent, 301ebab2259SFam Zheng Error **errp) 302ebab2259SFam Zheng { 303044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *successor = parent->successor; 304ebab2259SFam Zheng 305ebab2259SFam Zheng if (!successor) { 306ebab2259SFam Zheng error_setg(errp, "Cannot reclaim a successor when none is present"); 307ebab2259SFam Zheng return NULL; 308ebab2259SFam Zheng } 309ebab2259SFam Zheng 310ebab2259SFam Zheng if (!hbitmap_merge(parent->bitmap, successor->bitmap)) { 311ebab2259SFam Zheng error_setg(errp, "Merging of parent and successor bitmap failed"); 312ebab2259SFam Zheng return NULL; 313ebab2259SFam Zheng } 314b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(successor); 315ebab2259SFam Zheng parent->successor = NULL; 316ebab2259SFam Zheng 317044ee8e1SVladimir Sementsov-Ogievskiy return parent; 318044ee8e1SVladimir Sementsov-Ogievskiy } 319044ee8e1SVladimir Sementsov-Ogievskiy 320044ee8e1SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 321044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, 322044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *parent, 323044ee8e1SVladimir Sementsov-Ogievskiy Error **errp) 324044ee8e1SVladimir Sementsov-Ogievskiy { 325044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *ret; 326044ee8e1SVladimir Sementsov-Ogievskiy 327044ee8e1SVladimir Sementsov-Ogievskiy qemu_mutex_lock(parent->mutex); 328044ee8e1SVladimir Sementsov-Ogievskiy ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp); 329604ab74bSVladimir Sementsov-Ogievskiy qemu_mutex_unlock(parent->mutex); 330604ab74bSVladimir Sementsov-Ogievskiy 331044ee8e1SVladimir Sementsov-Ogievskiy return ret; 332ebab2259SFam Zheng } 333ebab2259SFam Zheng 334ebab2259SFam Zheng /** 335ebab2259SFam Zheng * Truncates _all_ bitmaps attached to a BDS. 3362119882cSPaolo Bonzini * Called with BQL taken. 337ebab2259SFam Zheng */ 3381b6cc579SEric Blake void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes) 339ebab2259SFam Zheng { 340ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 341ebab2259SFam Zheng 3422119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 343ebab2259SFam Zheng QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { 344ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 345dc162c8eSFam Zheng assert(!bitmap->active_iterators); 346ca759622SEric Blake hbitmap_truncate(bitmap->bitmap, bytes); 347993e6525SEric Blake bitmap->size = bytes; 348ebab2259SFam Zheng } 3492119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 350ebab2259SFam Zheng } 351ebab2259SFam Zheng 3522119882cSPaolo Bonzini /* Called with BQL taken. */ 353ebab2259SFam Zheng void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) 354ebab2259SFam Zheng { 355b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 356b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(bitmap); 357b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 358ebab2259SFam Zheng } 359ebab2259SFam Zheng 360ebab2259SFam Zheng /** 361ebab2259SFam Zheng * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()). 362ebab2259SFam Zheng * There must not be any frozen bitmaps attached. 36356f364e6SVladimir Sementsov-Ogievskiy * This function does not remove persistent bitmaps from the storage. 3642119882cSPaolo Bonzini * Called with BQL taken. 365ebab2259SFam Zheng */ 366ebab2259SFam Zheng void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs) 367ebab2259SFam Zheng { 368b133c27fSPaolo Bonzini BdrvDirtyBitmap *bm, *next; 369b133c27fSPaolo Bonzini 370b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 371b133c27fSPaolo Bonzini QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { 372b133c27fSPaolo Bonzini if (bdrv_dirty_bitmap_name(bm)) { 373b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(bm); 374b133c27fSPaolo Bonzini } 375b133c27fSPaolo Bonzini } 376b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 377615b5dcfSVladimir Sementsov-Ogievskiy } 378615b5dcfSVladimir Sementsov-Ogievskiy 379615b5dcfSVladimir Sementsov-Ogievskiy /** 380615b5dcfSVladimir Sementsov-Ogievskiy * Release all persistent dirty bitmaps attached to a BDS (for use in 381615b5dcfSVladimir Sementsov-Ogievskiy * bdrv_inactivate_recurse()). 382615b5dcfSVladimir Sementsov-Ogievskiy * There must not be any frozen bitmaps attached. 383615b5dcfSVladimir Sementsov-Ogievskiy * This function does not remove persistent bitmaps from the storage. 384b133c27fSPaolo Bonzini * Called with BQL taken. 385615b5dcfSVladimir Sementsov-Ogievskiy */ 386615b5dcfSVladimir Sementsov-Ogievskiy void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs) 387615b5dcfSVladimir Sementsov-Ogievskiy { 388b133c27fSPaolo Bonzini BdrvDirtyBitmap *bm, *next; 389b133c27fSPaolo Bonzini 390b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 391b133c27fSPaolo Bonzini QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { 392b133c27fSPaolo Bonzini if (bdrv_dirty_bitmap_get_persistance(bm)) { 393b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(bm); 394b133c27fSPaolo Bonzini } 395b133c27fSPaolo Bonzini } 396b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 397ebab2259SFam Zheng } 398ebab2259SFam Zheng 39956f364e6SVladimir Sementsov-Ogievskiy /** 40056f364e6SVladimir Sementsov-Ogievskiy * Remove persistent dirty bitmap from the storage if it exists. 40156f364e6SVladimir Sementsov-Ogievskiy * Absence of bitmap is not an error, because we have the following scenario: 40256f364e6SVladimir Sementsov-Ogievskiy * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no 40356f364e6SVladimir Sementsov-Ogievskiy * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should 40456f364e6SVladimir Sementsov-Ogievskiy * not fail. 40556f364e6SVladimir Sementsov-Ogievskiy * This function doesn't release corresponding BdrvDirtyBitmap. 40656f364e6SVladimir Sementsov-Ogievskiy */ 40756f364e6SVladimir Sementsov-Ogievskiy void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, 40856f364e6SVladimir Sementsov-Ogievskiy const char *name, 40956f364e6SVladimir Sementsov-Ogievskiy Error **errp) 41056f364e6SVladimir Sementsov-Ogievskiy { 41156f364e6SVladimir Sementsov-Ogievskiy if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) { 41256f364e6SVladimir Sementsov-Ogievskiy bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp); 41356f364e6SVladimir Sementsov-Ogievskiy } 41456f364e6SVladimir Sementsov-Ogievskiy } 41556f364e6SVladimir Sementsov-Ogievskiy 416ebab2259SFam Zheng void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap) 417ebab2259SFam Zheng { 4188b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_lock(bitmap); 419ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 420ebab2259SFam Zheng bitmap->disabled = true; 4218b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_unlock(bitmap); 422ebab2259SFam Zheng } 423ebab2259SFam Zheng 424ebab2259SFam Zheng void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap) 425ebab2259SFam Zheng { 4268b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_lock(bitmap); 427ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 428ebab2259SFam Zheng bitmap->disabled = false; 4298b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_unlock(bitmap); 430ebab2259SFam Zheng } 431ebab2259SFam Zheng 432ebab2259SFam Zheng BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) 433ebab2259SFam Zheng { 434ebab2259SFam Zheng BdrvDirtyBitmap *bm; 435ebab2259SFam Zheng BlockDirtyInfoList *list = NULL; 436ebab2259SFam Zheng BlockDirtyInfoList **plist = &list; 437ebab2259SFam Zheng 4382119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 439ebab2259SFam Zheng QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 440ebab2259SFam Zheng BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1); 441ebab2259SFam Zheng BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1); 4429a46dba7SEric Blake info->count = bdrv_get_dirty_count(bm); 443ebab2259SFam Zheng info->granularity = bdrv_dirty_bitmap_granularity(bm); 444ebab2259SFam Zheng info->has_name = !!bm->name; 445ebab2259SFam Zheng info->name = g_strdup(bm->name); 446ebab2259SFam Zheng info->status = bdrv_dirty_bitmap_status(bm); 447ebab2259SFam Zheng entry->value = info; 448ebab2259SFam Zheng *plist = entry; 449ebab2259SFam Zheng plist = &entry->next; 450ebab2259SFam Zheng } 4512119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 452ebab2259SFam Zheng 453ebab2259SFam Zheng return list; 454ebab2259SFam Zheng } 455ebab2259SFam Zheng 456b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 4573b5d4df0SEric Blake bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, 4583b5d4df0SEric Blake int64_t offset) 459ebab2259SFam Zheng { 460ebab2259SFam Zheng if (bitmap) { 461ca759622SEric Blake return hbitmap_get(bitmap->bitmap, offset); 462ebab2259SFam Zheng } else { 4633b5d4df0SEric Blake return false; 464ebab2259SFam Zheng } 465ebab2259SFam Zheng } 466ebab2259SFam Zheng 467ebab2259SFam Zheng /** 468ebab2259SFam Zheng * Chooses a default granularity based on the existing cluster size, 469ebab2259SFam Zheng * but clamped between [4K, 64K]. Defaults to 64K in the case that there 470ebab2259SFam Zheng * is no cluster size information available. 471ebab2259SFam Zheng */ 472ebab2259SFam Zheng uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs) 473ebab2259SFam Zheng { 474ebab2259SFam Zheng BlockDriverInfo bdi; 475ebab2259SFam Zheng uint32_t granularity; 476ebab2259SFam Zheng 477ebab2259SFam Zheng if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) { 478ebab2259SFam Zheng granularity = MAX(4096, bdi.cluster_size); 479ebab2259SFam Zheng granularity = MIN(65536, granularity); 480ebab2259SFam Zheng } else { 481ebab2259SFam Zheng granularity = 65536; 482ebab2259SFam Zheng } 483ebab2259SFam Zheng 484ebab2259SFam Zheng return granularity; 485ebab2259SFam Zheng } 486ebab2259SFam Zheng 487ba06ff1aSVladimir Sementsov-Ogievskiy uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap) 488ebab2259SFam Zheng { 489ca759622SEric Blake return 1U << hbitmap_granularity(bitmap->bitmap); 490ebab2259SFam Zheng } 491ebab2259SFam Zheng 492715a74d8SEric Blake BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap) 493ebab2259SFam Zheng { 494dc162c8eSFam Zheng BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1); 495715a74d8SEric Blake hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0); 496dc162c8eSFam Zheng iter->bitmap = bitmap; 497dc162c8eSFam Zheng bitmap->active_iterators++; 498dc162c8eSFam Zheng return iter; 499dc162c8eSFam Zheng } 500dc162c8eSFam Zheng 5016d3f4049SFam Zheng BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap) 5026d3f4049SFam Zheng { 5036d3f4049SFam Zheng BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1); 5046d3f4049SFam Zheng hbitmap_iter_init(&iter->hbi, bitmap->meta, 0); 5056d3f4049SFam Zheng iter->bitmap = bitmap; 5066d3f4049SFam Zheng bitmap->active_iterators++; 5076d3f4049SFam Zheng return iter; 5086d3f4049SFam Zheng } 5096d3f4049SFam Zheng 510dc162c8eSFam Zheng void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter) 511dc162c8eSFam Zheng { 512dc162c8eSFam Zheng if (!iter) { 513dc162c8eSFam Zheng return; 514dc162c8eSFam Zheng } 515dc162c8eSFam Zheng assert(iter->bitmap->active_iterators > 0); 516dc162c8eSFam Zheng iter->bitmap->active_iterators--; 517dc162c8eSFam Zheng g_free(iter); 518dc162c8eSFam Zheng } 519dc162c8eSFam Zheng 520dc162c8eSFam Zheng int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter) 521dc162c8eSFam Zheng { 522a33fbb4fSMax Reitz return hbitmap_iter_next(&iter->hbi, true); 523ebab2259SFam Zheng } 524ebab2259SFam Zheng 525*72d10a94SMax Reitz /** 526*72d10a94SMax Reitz * Return the next consecutively dirty area in the dirty bitmap 527*72d10a94SMax Reitz * belonging to the given iterator @iter. 528*72d10a94SMax Reitz * 529*72d10a94SMax Reitz * @max_offset: Maximum value that may be returned for 530*72d10a94SMax Reitz * *offset + *bytes 531*72d10a94SMax Reitz * @offset: Will contain the start offset of the next dirty area 532*72d10a94SMax Reitz * @bytes: Will contain the length of the next dirty area 533*72d10a94SMax Reitz * 534*72d10a94SMax Reitz * Returns: True if a dirty area could be found before max_offset 535*72d10a94SMax Reitz * (which means that *offset and *bytes then contain valid 536*72d10a94SMax Reitz * values), false otherwise. 537*72d10a94SMax Reitz * 538*72d10a94SMax Reitz * Note that @iter is never advanced if false is returned. If an area 539*72d10a94SMax Reitz * is found (which means that true is returned), it will be advanced 540*72d10a94SMax Reitz * past that area. 541*72d10a94SMax Reitz */ 542*72d10a94SMax Reitz bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset, 543*72d10a94SMax Reitz uint64_t *offset, int *bytes) 544*72d10a94SMax Reitz { 545*72d10a94SMax Reitz uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap); 546*72d10a94SMax Reitz uint64_t gran_max_offset; 547*72d10a94SMax Reitz int64_t ret; 548*72d10a94SMax Reitz int size; 549*72d10a94SMax Reitz 550*72d10a94SMax Reitz if (max_offset == iter->bitmap->size) { 551*72d10a94SMax Reitz /* If max_offset points to the image end, round it up by the 552*72d10a94SMax Reitz * bitmap granularity */ 553*72d10a94SMax Reitz gran_max_offset = ROUND_UP(max_offset, granularity); 554*72d10a94SMax Reitz } else { 555*72d10a94SMax Reitz gran_max_offset = max_offset; 556*72d10a94SMax Reitz } 557*72d10a94SMax Reitz 558*72d10a94SMax Reitz ret = hbitmap_iter_next(&iter->hbi, false); 559*72d10a94SMax Reitz if (ret < 0 || ret + granularity > gran_max_offset) { 560*72d10a94SMax Reitz return false; 561*72d10a94SMax Reitz } 562*72d10a94SMax Reitz 563*72d10a94SMax Reitz *offset = ret; 564*72d10a94SMax Reitz size = 0; 565*72d10a94SMax Reitz 566*72d10a94SMax Reitz assert(granularity <= INT_MAX); 567*72d10a94SMax Reitz 568*72d10a94SMax Reitz do { 569*72d10a94SMax Reitz /* Advance iterator */ 570*72d10a94SMax Reitz ret = hbitmap_iter_next(&iter->hbi, true); 571*72d10a94SMax Reitz size += granularity; 572*72d10a94SMax Reitz } while (ret + granularity <= gran_max_offset && 573*72d10a94SMax Reitz hbitmap_iter_next(&iter->hbi, false) == ret + granularity && 574*72d10a94SMax Reitz size <= INT_MAX - granularity); 575*72d10a94SMax Reitz 576*72d10a94SMax Reitz *bytes = MIN(size, max_offset - *offset); 577*72d10a94SMax Reitz return true; 578*72d10a94SMax Reitz } 579*72d10a94SMax Reitz 580b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 581b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, 582e0d7f73eSEric Blake int64_t offset, int64_t bytes) 583ebab2259SFam Zheng { 584ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 585d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 586ca759622SEric Blake hbitmap_set(bitmap->bitmap, offset, bytes); 587ebab2259SFam Zheng } 588ebab2259SFam Zheng 589b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap, 590e0d7f73eSEric Blake int64_t offset, int64_t bytes) 591b64bd51eSPaolo Bonzini { 592b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 593e0d7f73eSEric Blake bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes); 594b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 595b64bd51eSPaolo Bonzini } 596b64bd51eSPaolo Bonzini 597b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 598b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, 599e0d7f73eSEric Blake int64_t offset, int64_t bytes) 600ebab2259SFam Zheng { 601ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 602d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 603ca759622SEric Blake hbitmap_reset(bitmap->bitmap, offset, bytes); 604ebab2259SFam Zheng } 605ebab2259SFam Zheng 606b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap, 607e0d7f73eSEric Blake int64_t offset, int64_t bytes) 608b64bd51eSPaolo Bonzini { 609b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 610e0d7f73eSEric Blake bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes); 611b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 612b64bd51eSPaolo Bonzini } 613b64bd51eSPaolo Bonzini 614ebab2259SFam Zheng void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out) 615ebab2259SFam Zheng { 616ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 617d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 618b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 619ebab2259SFam Zheng if (!out) { 620ebab2259SFam Zheng hbitmap_reset_all(bitmap->bitmap); 621ebab2259SFam Zheng } else { 622ebab2259SFam Zheng HBitmap *backup = bitmap->bitmap; 623ca759622SEric Blake bitmap->bitmap = hbitmap_alloc(bitmap->size, 624ebab2259SFam Zheng hbitmap_granularity(backup)); 625ebab2259SFam Zheng *out = backup; 626ebab2259SFam Zheng } 627b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 628ebab2259SFam Zheng } 629ebab2259SFam Zheng 630ebab2259SFam Zheng void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in) 631ebab2259SFam Zheng { 632ebab2259SFam Zheng HBitmap *tmp = bitmap->bitmap; 633ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 634d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 635ebab2259SFam Zheng bitmap->bitmap = in; 636ebab2259SFam Zheng hbitmap_free(tmp); 637ebab2259SFam Zheng } 638ebab2259SFam Zheng 639882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap, 64086f6ae67SEric Blake uint64_t offset, uint64_t bytes) 641882c36f5SVladimir Sementsov-Ogievskiy { 642ca759622SEric Blake return hbitmap_serialization_size(bitmap->bitmap, offset, bytes); 643882c36f5SVladimir Sementsov-Ogievskiy } 644882c36f5SVladimir Sementsov-Ogievskiy 645882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap) 646882c36f5SVladimir Sementsov-Ogievskiy { 647ca759622SEric Blake return hbitmap_serialization_align(bitmap->bitmap); 648882c36f5SVladimir Sementsov-Ogievskiy } 649882c36f5SVladimir Sementsov-Ogievskiy 650882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap, 65186f6ae67SEric Blake uint8_t *buf, uint64_t offset, 65286f6ae67SEric Blake uint64_t bytes) 653882c36f5SVladimir Sementsov-Ogievskiy { 654ca759622SEric Blake hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes); 655882c36f5SVladimir Sementsov-Ogievskiy } 656882c36f5SVladimir Sementsov-Ogievskiy 657882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap, 65886f6ae67SEric Blake uint8_t *buf, uint64_t offset, 65986f6ae67SEric Blake uint64_t bytes, bool finish) 660882c36f5SVladimir Sementsov-Ogievskiy { 661ca759622SEric Blake hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish); 662882c36f5SVladimir Sementsov-Ogievskiy } 663882c36f5SVladimir Sementsov-Ogievskiy 664882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap, 66586f6ae67SEric Blake uint64_t offset, uint64_t bytes, 666882c36f5SVladimir Sementsov-Ogievskiy bool finish) 667882c36f5SVladimir Sementsov-Ogievskiy { 668ca759622SEric Blake hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish); 669882c36f5SVladimir Sementsov-Ogievskiy } 670882c36f5SVladimir Sementsov-Ogievskiy 6716bdc8b71SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, 67286f6ae67SEric Blake uint64_t offset, uint64_t bytes, 6736bdc8b71SVladimir Sementsov-Ogievskiy bool finish) 6746bdc8b71SVladimir Sementsov-Ogievskiy { 675ca759622SEric Blake hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish); 6766bdc8b71SVladimir Sementsov-Ogievskiy } 6776bdc8b71SVladimir Sementsov-Ogievskiy 678882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap) 679882c36f5SVladimir Sementsov-Ogievskiy { 680882c36f5SVladimir Sementsov-Ogievskiy hbitmap_deserialize_finish(bitmap->bitmap); 681882c36f5SVladimir Sementsov-Ogievskiy } 682882c36f5SVladimir Sementsov-Ogievskiy 6830fdf1a4fSEric Blake void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes) 684ebab2259SFam Zheng { 685ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 6862119882cSPaolo Bonzini 6872119882cSPaolo Bonzini if (QLIST_EMPTY(&bs->dirty_bitmaps)) { 6882119882cSPaolo Bonzini return; 6892119882cSPaolo Bonzini } 6902119882cSPaolo Bonzini 6912119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 692ebab2259SFam Zheng QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { 693ebab2259SFam Zheng if (!bdrv_dirty_bitmap_enabled(bitmap)) { 694ebab2259SFam Zheng continue; 695ebab2259SFam Zheng } 696d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 697ca759622SEric Blake hbitmap_set(bitmap->bitmap, offset, bytes); 698ebab2259SFam Zheng } 6992119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 700ebab2259SFam Zheng } 701ebab2259SFam Zheng 702ebab2259SFam Zheng /** 703dc162c8eSFam Zheng * Advance a BdrvDirtyBitmapIter to an arbitrary offset. 704ebab2259SFam Zheng */ 705715a74d8SEric Blake void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset) 706ebab2259SFam Zheng { 707ca759622SEric Blake hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset); 708ebab2259SFam Zheng } 709ebab2259SFam Zheng 710ebab2259SFam Zheng int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap) 711ebab2259SFam Zheng { 712ca759622SEric Blake return hbitmap_count(bitmap->bitmap); 713ebab2259SFam Zheng } 7146d3f4049SFam Zheng 7156d3f4049SFam Zheng int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap) 7166d3f4049SFam Zheng { 7176d3f4049SFam Zheng return hbitmap_count(bitmap->meta); 7186d3f4049SFam Zheng } 719d6883bc9SVladimir Sementsov-Ogievskiy 720d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap) 721d6883bc9SVladimir Sementsov-Ogievskiy { 722d6883bc9SVladimir Sementsov-Ogievskiy return bitmap->readonly; 723d6883bc9SVladimir Sementsov-Ogievskiy } 724d6883bc9SVladimir Sementsov-Ogievskiy 725d6883bc9SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 726d6883bc9SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value) 727d6883bc9SVladimir Sementsov-Ogievskiy { 728d6883bc9SVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 729d6883bc9SVladimir Sementsov-Ogievskiy bitmap->readonly = value; 730d6883bc9SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 731d6883bc9SVladimir Sementsov-Ogievskiy } 732d6883bc9SVladimir Sementsov-Ogievskiy 733d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_has_readonly_bitmaps(BlockDriverState *bs) 734d6883bc9SVladimir Sementsov-Ogievskiy { 735d6883bc9SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bm; 736d6883bc9SVladimir Sementsov-Ogievskiy QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 737d6883bc9SVladimir Sementsov-Ogievskiy if (bm->readonly) { 738d6883bc9SVladimir Sementsov-Ogievskiy return true; 739d6883bc9SVladimir Sementsov-Ogievskiy } 740d6883bc9SVladimir Sementsov-Ogievskiy } 741d6883bc9SVladimir Sementsov-Ogievskiy 742d6883bc9SVladimir Sementsov-Ogievskiy return false; 743d6883bc9SVladimir Sementsov-Ogievskiy } 744a0319aacSVladimir Sementsov-Ogievskiy 745a0319aacSVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 746a88b179fSVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent) 747a88b179fSVladimir Sementsov-Ogievskiy { 748a88b179fSVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 749a88b179fSVladimir Sementsov-Ogievskiy bitmap->persistent = persistent; 750a88b179fSVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 751a88b179fSVladimir Sementsov-Ogievskiy } 752a88b179fSVladimir Sementsov-Ogievskiy 753a88b179fSVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap) 754a88b179fSVladimir Sementsov-Ogievskiy { 755a88b179fSVladimir Sementsov-Ogievskiy return bitmap->persistent; 756a88b179fSVladimir Sementsov-Ogievskiy } 757a88b179fSVladimir Sementsov-Ogievskiy 758a88b179fSVladimir Sementsov-Ogievskiy bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) 759a88b179fSVladimir Sementsov-Ogievskiy { 760a88b179fSVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bm; 761a88b179fSVladimir Sementsov-Ogievskiy QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 762a88b179fSVladimir Sementsov-Ogievskiy if (bm->persistent && !bm->readonly) { 763a88b179fSVladimir Sementsov-Ogievskiy return true; 764a88b179fSVladimir Sementsov-Ogievskiy } 765a88b179fSVladimir Sementsov-Ogievskiy } 766a88b179fSVladimir Sementsov-Ogievskiy 767a88b179fSVladimir Sementsov-Ogievskiy return false; 768a88b179fSVladimir Sementsov-Ogievskiy } 7693dd10a06SVladimir Sementsov-Ogievskiy 7703dd10a06SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, 7713dd10a06SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bitmap) 7723dd10a06SVladimir Sementsov-Ogievskiy { 7733dd10a06SVladimir Sementsov-Ogievskiy return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : 7743dd10a06SVladimir Sementsov-Ogievskiy QLIST_NEXT(bitmap, list); 7753dd10a06SVladimir Sementsov-Ogievskiy } 776a3b52535SVladimir Sementsov-Ogievskiy 777a3b52535SVladimir Sementsov-Ogievskiy char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp) 778a3b52535SVladimir Sementsov-Ogievskiy { 779a3b52535SVladimir Sementsov-Ogievskiy return hbitmap_sha256(bitmap->bitmap, errp); 780a3b52535SVladimir Sementsov-Ogievskiy } 78156207df5SVladimir Sementsov-Ogievskiy 78256207df5SVladimir Sementsov-Ogievskiy int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset) 78356207df5SVladimir Sementsov-Ogievskiy { 78456207df5SVladimir Sementsov-Ogievskiy return hbitmap_next_zero(bitmap->bitmap, offset); 78556207df5SVladimir Sementsov-Ogievskiy } 786b598e531SVladimir Sementsov-Ogievskiy 787b598e531SVladimir Sementsov-Ogievskiy void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, 788b598e531SVladimir Sementsov-Ogievskiy Error **errp) 789b598e531SVladimir Sementsov-Ogievskiy { 790b598e531SVladimir Sementsov-Ogievskiy /* only bitmaps from one bds are supported */ 791b598e531SVladimir Sementsov-Ogievskiy assert(dest->mutex == src->mutex); 792b598e531SVladimir Sementsov-Ogievskiy 793b598e531SVladimir Sementsov-Ogievskiy qemu_mutex_lock(dest->mutex); 794b598e531SVladimir Sementsov-Ogievskiy 795b598e531SVladimir Sementsov-Ogievskiy assert(bdrv_dirty_bitmap_enabled(dest)); 796b598e531SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(dest)); 797b598e531SVladimir Sementsov-Ogievskiy 798b598e531SVladimir Sementsov-Ogievskiy if (!hbitmap_merge(dest->bitmap, src->bitmap)) { 799b598e531SVladimir Sementsov-Ogievskiy error_setg(errp, "Bitmaps are incompatible and can't be merged"); 800b598e531SVladimir Sementsov-Ogievskiy } 801b598e531SVladimir Sementsov-Ogievskiy 802b598e531SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(dest->mutex); 803b598e531SVladimir Sementsov-Ogievskiy } 804