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 */ 589c98f145SVladimir Sementsov-Ogievskiy bool migration; /* Bitmap is selected for migration, it should 599c98f145SVladimir Sementsov-Ogievskiy not be stored on the next inactivation 609c98f145SVladimir Sementsov-Ogievskiy (persistent flag doesn't matter until next 619c98f145SVladimir Sementsov-Ogievskiy invalidation).*/ 62ebab2259SFam Zheng QLIST_ENTRY(BdrvDirtyBitmap) list; 63ebab2259SFam Zheng }; 64ebab2259SFam Zheng 65dc162c8eSFam Zheng struct BdrvDirtyBitmapIter { 66dc162c8eSFam Zheng HBitmapIter hbi; 67dc162c8eSFam Zheng BdrvDirtyBitmap *bitmap; 68dc162c8eSFam Zheng }; 69dc162c8eSFam Zheng 702119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs) 712119882cSPaolo Bonzini { 722119882cSPaolo Bonzini qemu_mutex_lock(&bs->dirty_bitmap_mutex); 732119882cSPaolo Bonzini } 742119882cSPaolo Bonzini 752119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs) 762119882cSPaolo Bonzini { 772119882cSPaolo Bonzini qemu_mutex_unlock(&bs->dirty_bitmap_mutex); 782119882cSPaolo Bonzini } 792119882cSPaolo Bonzini 80b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap) 81b64bd51eSPaolo Bonzini { 82b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 83b64bd51eSPaolo Bonzini } 84b64bd51eSPaolo Bonzini 85b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap) 86b64bd51eSPaolo Bonzini { 87b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 88b64bd51eSPaolo Bonzini } 89b64bd51eSPaolo Bonzini 902119882cSPaolo Bonzini /* Called with BQL or dirty_bitmap lock taken. */ 91ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name) 92ebab2259SFam Zheng { 93ebab2259SFam Zheng BdrvDirtyBitmap *bm; 94ebab2259SFam Zheng 95ebab2259SFam Zheng assert(name); 96ebab2259SFam Zheng QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 97ebab2259SFam Zheng if (bm->name && !strcmp(name, bm->name)) { 98ebab2259SFam Zheng return bm; 99ebab2259SFam Zheng } 100ebab2259SFam Zheng } 101ebab2259SFam Zheng return NULL; 102ebab2259SFam Zheng } 103ebab2259SFam Zheng 1042119882cSPaolo Bonzini /* Called with BQL taken. */ 105ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, 106ebab2259SFam Zheng uint32_t granularity, 107ebab2259SFam Zheng const char *name, 108ebab2259SFam Zheng Error **errp) 109ebab2259SFam Zheng { 110ebab2259SFam Zheng int64_t bitmap_size; 111ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 112ebab2259SFam Zheng 113993e6525SEric Blake assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE); 114ebab2259SFam Zheng 115ebab2259SFam Zheng if (name && bdrv_find_dirty_bitmap(bs, name)) { 116ebab2259SFam Zheng error_setg(errp, "Bitmap already exists: %s", name); 117ebab2259SFam Zheng return NULL; 118ebab2259SFam Zheng } 119993e6525SEric Blake bitmap_size = bdrv_getlength(bs); 120ebab2259SFam Zheng if (bitmap_size < 0) { 121ebab2259SFam Zheng error_setg_errno(errp, -bitmap_size, "could not get length of device"); 122ebab2259SFam Zheng errno = -bitmap_size; 123ebab2259SFam Zheng return NULL; 124ebab2259SFam Zheng } 125ebab2259SFam Zheng bitmap = g_new0(BdrvDirtyBitmap, 1); 126b64bd51eSPaolo Bonzini bitmap->mutex = &bs->dirty_bitmap_mutex; 127ca759622SEric Blake bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity)); 128ebab2259SFam Zheng bitmap->size = bitmap_size; 129ebab2259SFam Zheng bitmap->name = g_strdup(name); 130ebab2259SFam Zheng bitmap->disabled = false; 1312119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 132ebab2259SFam Zheng QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list); 1332119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 134ebab2259SFam Zheng return bitmap; 135ebab2259SFam Zheng } 136ebab2259SFam Zheng 137fb933437SFam Zheng /* bdrv_create_meta_dirty_bitmap 138fb933437SFam Zheng * 139fb933437SFam Zheng * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e. 140fb933437SFam Zheng * when a dirty status bit in @bitmap is changed (either from reset to set or 141fb933437SFam Zheng * the other way around), its respective meta dirty bitmap bit will be marked 142fb933437SFam Zheng * dirty as well. 143fb933437SFam Zheng * 144fb933437SFam Zheng * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap. 145fb933437SFam Zheng * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap 146fb933437SFam Zheng * track. 147fb933437SFam Zheng */ 148fb933437SFam Zheng void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap, 149fb933437SFam Zheng int chunk_size) 150fb933437SFam Zheng { 151fb933437SFam Zheng assert(!bitmap->meta); 152b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 153fb933437SFam Zheng bitmap->meta = hbitmap_create_meta(bitmap->bitmap, 154fb933437SFam Zheng chunk_size * BITS_PER_BYTE); 155b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 156fb933437SFam Zheng } 157fb933437SFam Zheng 158fb933437SFam Zheng void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap) 159fb933437SFam Zheng { 160fb933437SFam Zheng assert(bitmap->meta); 161b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 162fb933437SFam Zheng hbitmap_free_meta(bitmap->bitmap); 163fb933437SFam Zheng bitmap->meta = NULL; 164b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 165fb933437SFam Zheng } 166fb933437SFam Zheng 16715891facSFam Zheng int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap) 16815891facSFam Zheng { 169993e6525SEric Blake return bitmap->size; 17015891facSFam Zheng } 17115891facSFam Zheng 17215891facSFam Zheng const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap) 17315891facSFam Zheng { 17415891facSFam Zheng return bitmap->name; 17515891facSFam Zheng } 17615891facSFam Zheng 1772119882cSPaolo Bonzini /* Called with BQL taken. */ 178ebab2259SFam Zheng bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap) 179ebab2259SFam Zheng { 180ebab2259SFam Zheng return bitmap->successor; 181ebab2259SFam Zheng } 182ebab2259SFam Zheng 183993edc0cSJohn Snow /* Both conditions disallow user-modification via QMP. */ 184993edc0cSJohn Snow bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap) { 185993edc0cSJohn Snow return bdrv_dirty_bitmap_frozen(bitmap) || 186993edc0cSJohn Snow bdrv_dirty_bitmap_qmp_locked(bitmap); 187993edc0cSJohn Snow } 188993edc0cSJohn Snow 1894f43e953SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked) 1904f43e953SVladimir Sementsov-Ogievskiy { 1914f43e953SVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 1924f43e953SVladimir Sementsov-Ogievskiy bitmap->qmp_locked = qmp_locked; 1934f43e953SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 1944f43e953SVladimir Sementsov-Ogievskiy } 1954f43e953SVladimir Sementsov-Ogievskiy 1964f43e953SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap) 1974f43e953SVladimir Sementsov-Ogievskiy { 1984f43e953SVladimir Sementsov-Ogievskiy return bitmap->qmp_locked; 1994f43e953SVladimir Sementsov-Ogievskiy } 2004f43e953SVladimir Sementsov-Ogievskiy 2012119882cSPaolo Bonzini /* Called with BQL taken. */ 202ebab2259SFam Zheng bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap) 203ebab2259SFam Zheng { 204ebab2259SFam Zheng return !(bitmap->disabled || bitmap->successor); 205ebab2259SFam Zheng } 206ebab2259SFam Zheng 2072119882cSPaolo Bonzini /* Called with BQL taken. */ 208ebab2259SFam Zheng DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap) 209ebab2259SFam Zheng { 210ebab2259SFam Zheng if (bdrv_dirty_bitmap_frozen(bitmap)) { 211ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_FROZEN; 2124f43e953SVladimir Sementsov-Ogievskiy } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { 2134f43e953SVladimir Sementsov-Ogievskiy return DIRTY_BITMAP_STATUS_LOCKED; 214ebab2259SFam Zheng } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { 215ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_DISABLED; 216ebab2259SFam Zheng } else { 217ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_ACTIVE; 218ebab2259SFam Zheng } 219ebab2259SFam Zheng } 220ebab2259SFam Zheng 221ebab2259SFam Zheng /** 222ebab2259SFam Zheng * Create a successor bitmap destined to replace this bitmap after an operation. 223ebab2259SFam Zheng * Requires that the bitmap is not frozen and has no successor. 2242119882cSPaolo Bonzini * Called with BQL taken. 225ebab2259SFam Zheng */ 226ebab2259SFam Zheng int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs, 227ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, Error **errp) 228ebab2259SFam Zheng { 229ebab2259SFam Zheng uint64_t granularity; 230ebab2259SFam Zheng BdrvDirtyBitmap *child; 231ebab2259SFam Zheng 232ebab2259SFam Zheng if (bdrv_dirty_bitmap_frozen(bitmap)) { 233ebab2259SFam Zheng error_setg(errp, "Cannot create a successor for a bitmap that is " 234ebab2259SFam Zheng "currently frozen"); 235ebab2259SFam Zheng return -1; 236ebab2259SFam Zheng } 237ebab2259SFam Zheng assert(!bitmap->successor); 238ebab2259SFam Zheng 239ebab2259SFam Zheng /* Create an anonymous successor */ 240ebab2259SFam Zheng granularity = bdrv_dirty_bitmap_granularity(bitmap); 241ebab2259SFam Zheng child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); 242ebab2259SFam Zheng if (!child) { 243ebab2259SFam Zheng return -1; 244ebab2259SFam Zheng } 245ebab2259SFam Zheng 246ebab2259SFam Zheng /* Successor will be on or off based on our current state. */ 247ebab2259SFam Zheng child->disabled = bitmap->disabled; 248ebab2259SFam Zheng 249ebab2259SFam Zheng /* Install the successor and freeze the parent */ 250ebab2259SFam Zheng bitmap->successor = child; 251ebab2259SFam Zheng return 0; 252ebab2259SFam Zheng } 253ebab2259SFam Zheng 25492bcea40SVladimir Sementsov-Ogievskiy void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap) 25592bcea40SVladimir Sementsov-Ogievskiy { 25692bcea40SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_frozen(bitmap)); 25792bcea40SVladimir Sementsov-Ogievskiy bitmap->disabled = false; 25892bcea40SVladimir Sementsov-Ogievskiy } 25992bcea40SVladimir Sementsov-Ogievskiy 260e73a265eSVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 261e73a265eSVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap) 262e73a265eSVladimir Sementsov-Ogievskiy { 26358f72b96SVladimir Sementsov-Ogievskiy assert(bitmap->mutex == bitmap->successor->mutex); 264e73a265eSVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 26558f72b96SVladimir Sementsov-Ogievskiy bdrv_enable_dirty_bitmap_locked(bitmap->successor); 266e73a265eSVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 267e73a265eSVladimir Sementsov-Ogievskiy } 268e73a265eSVladimir Sementsov-Ogievskiy 269b133c27fSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */ 270b133c27fSPaolo Bonzini static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap) 271604ab74bSVladimir Sementsov-Ogievskiy { 272b133c27fSPaolo Bonzini assert(!bitmap->active_iterators); 273b133c27fSPaolo Bonzini assert(!bdrv_dirty_bitmap_frozen(bitmap)); 274b133c27fSPaolo Bonzini assert(!bitmap->meta); 275b133c27fSPaolo Bonzini QLIST_REMOVE(bitmap, list); 276b133c27fSPaolo Bonzini hbitmap_free(bitmap->bitmap); 277b133c27fSPaolo Bonzini g_free(bitmap->name); 278b133c27fSPaolo Bonzini g_free(bitmap); 279604ab74bSVladimir Sementsov-Ogievskiy } 280604ab74bSVladimir Sementsov-Ogievskiy 281ebab2259SFam Zheng /** 282ebab2259SFam Zheng * For a bitmap with a successor, yield our name to the successor, 283ebab2259SFam Zheng * delete the old bitmap, and return a handle to the new bitmap. 2842119882cSPaolo Bonzini * Called with BQL taken. 285ebab2259SFam Zheng */ 286ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs, 287ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, 288ebab2259SFam Zheng Error **errp) 289ebab2259SFam Zheng { 290ebab2259SFam Zheng char *name; 291ebab2259SFam Zheng BdrvDirtyBitmap *successor = bitmap->successor; 292ebab2259SFam Zheng 293ebab2259SFam Zheng if (successor == NULL) { 294ebab2259SFam Zheng error_setg(errp, "Cannot relinquish control if " 295ebab2259SFam Zheng "there's no successor present"); 296ebab2259SFam Zheng return NULL; 297ebab2259SFam Zheng } 298ebab2259SFam Zheng 299ebab2259SFam Zheng name = bitmap->name; 300ebab2259SFam Zheng bitmap->name = NULL; 301ebab2259SFam Zheng successor->name = name; 302ebab2259SFam Zheng bitmap->successor = NULL; 303a88b179fSVladimir Sementsov-Ogievskiy successor->persistent = bitmap->persistent; 304a88b179fSVladimir Sementsov-Ogievskiy bitmap->persistent = false; 305ebab2259SFam Zheng bdrv_release_dirty_bitmap(bs, bitmap); 306ebab2259SFam Zheng 307ebab2259SFam Zheng return successor; 308ebab2259SFam Zheng } 309ebab2259SFam Zheng 310ebab2259SFam Zheng /** 311ebab2259SFam Zheng * In cases of failure where we can no longer safely delete the parent, 312ebab2259SFam Zheng * we may wish to re-join the parent and child/successor. 313ebab2259SFam Zheng * The merged parent will be un-frozen, but not explicitly re-enabled. 314044ee8e1SVladimir Sementsov-Ogievskiy * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. 315ebab2259SFam Zheng */ 316044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs, 317ebab2259SFam Zheng BdrvDirtyBitmap *parent, 318ebab2259SFam Zheng Error **errp) 319ebab2259SFam Zheng { 320044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *successor = parent->successor; 321ebab2259SFam Zheng 322ebab2259SFam Zheng if (!successor) { 323ebab2259SFam Zheng error_setg(errp, "Cannot reclaim a successor when none is present"); 324ebab2259SFam Zheng return NULL; 325ebab2259SFam Zheng } 326ebab2259SFam Zheng 327fa000f2fSVladimir Sementsov-Ogievskiy if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) { 328ebab2259SFam Zheng error_setg(errp, "Merging of parent and successor bitmap failed"); 329ebab2259SFam Zheng return NULL; 330ebab2259SFam Zheng } 331b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(successor); 332ebab2259SFam Zheng parent->successor = NULL; 333ebab2259SFam Zheng 334044ee8e1SVladimir Sementsov-Ogievskiy return parent; 335044ee8e1SVladimir Sementsov-Ogievskiy } 336044ee8e1SVladimir Sementsov-Ogievskiy 337044ee8e1SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 338044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, 339044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *parent, 340044ee8e1SVladimir Sementsov-Ogievskiy Error **errp) 341044ee8e1SVladimir Sementsov-Ogievskiy { 342044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *ret; 343044ee8e1SVladimir Sementsov-Ogievskiy 344044ee8e1SVladimir Sementsov-Ogievskiy qemu_mutex_lock(parent->mutex); 345044ee8e1SVladimir Sementsov-Ogievskiy ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp); 346604ab74bSVladimir Sementsov-Ogievskiy qemu_mutex_unlock(parent->mutex); 347604ab74bSVladimir Sementsov-Ogievskiy 348044ee8e1SVladimir Sementsov-Ogievskiy return ret; 349ebab2259SFam Zheng } 350ebab2259SFam Zheng 351ebab2259SFam Zheng /** 352ebab2259SFam Zheng * Truncates _all_ bitmaps attached to a BDS. 3532119882cSPaolo Bonzini * Called with BQL taken. 354ebab2259SFam Zheng */ 3551b6cc579SEric Blake void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes) 356ebab2259SFam Zheng { 357ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 358ebab2259SFam Zheng 3592119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 360ebab2259SFam Zheng QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { 361ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 362dc162c8eSFam Zheng assert(!bitmap->active_iterators); 363ca759622SEric Blake hbitmap_truncate(bitmap->bitmap, bytes); 364993e6525SEric Blake bitmap->size = bytes; 365ebab2259SFam Zheng } 3662119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 367ebab2259SFam Zheng } 368ebab2259SFam Zheng 3692119882cSPaolo Bonzini /* Called with BQL taken. */ 370ebab2259SFam Zheng void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) 371ebab2259SFam Zheng { 372b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 373b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(bitmap); 374b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 375ebab2259SFam Zheng } 376ebab2259SFam Zheng 377ebab2259SFam Zheng /** 378ebab2259SFam Zheng * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()). 379ebab2259SFam Zheng * There must not be any frozen bitmaps attached. 38056f364e6SVladimir Sementsov-Ogievskiy * This function does not remove persistent bitmaps from the storage. 3812119882cSPaolo Bonzini * Called with BQL taken. 382ebab2259SFam Zheng */ 383ebab2259SFam Zheng void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs) 384ebab2259SFam Zheng { 385b133c27fSPaolo Bonzini BdrvDirtyBitmap *bm, *next; 386b133c27fSPaolo Bonzini 387b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 388b133c27fSPaolo Bonzini QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { 389b133c27fSPaolo Bonzini if (bdrv_dirty_bitmap_name(bm)) { 390b133c27fSPaolo Bonzini bdrv_release_dirty_bitmap_locked(bm); 391b133c27fSPaolo Bonzini } 392b133c27fSPaolo Bonzini } 393b133c27fSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 394615b5dcfSVladimir Sementsov-Ogievskiy } 395615b5dcfSVladimir Sementsov-Ogievskiy 396615b5dcfSVladimir Sementsov-Ogievskiy /** 39756f364e6SVladimir Sementsov-Ogievskiy * Remove persistent dirty bitmap from the storage if it exists. 39856f364e6SVladimir Sementsov-Ogievskiy * Absence of bitmap is not an error, because we have the following scenario: 39956f364e6SVladimir Sementsov-Ogievskiy * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no 40056f364e6SVladimir Sementsov-Ogievskiy * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should 40156f364e6SVladimir Sementsov-Ogievskiy * not fail. 40256f364e6SVladimir Sementsov-Ogievskiy * This function doesn't release corresponding BdrvDirtyBitmap. 40356f364e6SVladimir Sementsov-Ogievskiy */ 40456f364e6SVladimir Sementsov-Ogievskiy void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, 40556f364e6SVladimir Sementsov-Ogievskiy const char *name, 40656f364e6SVladimir Sementsov-Ogievskiy Error **errp) 40756f364e6SVladimir Sementsov-Ogievskiy { 40856f364e6SVladimir Sementsov-Ogievskiy if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) { 40956f364e6SVladimir Sementsov-Ogievskiy bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp); 41056f364e6SVladimir Sementsov-Ogievskiy } 41156f364e6SVladimir Sementsov-Ogievskiy } 41256f364e6SVladimir Sementsov-Ogievskiy 413ebab2259SFam Zheng void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap) 414ebab2259SFam Zheng { 4158b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_lock(bitmap); 416ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 417ebab2259SFam Zheng bitmap->disabled = true; 4188b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_unlock(bitmap); 419ebab2259SFam Zheng } 420ebab2259SFam Zheng 421ebab2259SFam Zheng void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap) 422ebab2259SFam Zheng { 4238b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_lock(bitmap); 42492bcea40SVladimir Sementsov-Ogievskiy bdrv_enable_dirty_bitmap_locked(bitmap); 4258b1402ceSVladimir Sementsov-Ogievskiy bdrv_dirty_bitmap_unlock(bitmap); 426ebab2259SFam Zheng } 427ebab2259SFam Zheng 428ebab2259SFam Zheng BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) 429ebab2259SFam Zheng { 430ebab2259SFam Zheng BdrvDirtyBitmap *bm; 431ebab2259SFam Zheng BlockDirtyInfoList *list = NULL; 432ebab2259SFam Zheng BlockDirtyInfoList **plist = &list; 433ebab2259SFam Zheng 4342119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 435ebab2259SFam Zheng QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 436ebab2259SFam Zheng BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1); 437ebab2259SFam Zheng BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1); 4389a46dba7SEric Blake info->count = bdrv_get_dirty_count(bm); 439ebab2259SFam Zheng info->granularity = bdrv_dirty_bitmap_granularity(bm); 440ebab2259SFam Zheng info->has_name = !!bm->name; 441ebab2259SFam Zheng info->name = g_strdup(bm->name); 442ebab2259SFam Zheng info->status = bdrv_dirty_bitmap_status(bm); 443ebab2259SFam Zheng entry->value = info; 444ebab2259SFam Zheng *plist = entry; 445ebab2259SFam Zheng plist = &entry->next; 446ebab2259SFam Zheng } 4472119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 448ebab2259SFam Zheng 449ebab2259SFam Zheng return list; 450ebab2259SFam Zheng } 451ebab2259SFam Zheng 452b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 4533b5d4df0SEric Blake bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, 4543b5d4df0SEric Blake int64_t offset) 455ebab2259SFam Zheng { 456ebab2259SFam Zheng if (bitmap) { 457ca759622SEric Blake return hbitmap_get(bitmap->bitmap, offset); 458ebab2259SFam Zheng } else { 4593b5d4df0SEric Blake return false; 460ebab2259SFam Zheng } 461ebab2259SFam Zheng } 462ebab2259SFam Zheng 463ebab2259SFam Zheng /** 464ebab2259SFam Zheng * Chooses a default granularity based on the existing cluster size, 465ebab2259SFam Zheng * but clamped between [4K, 64K]. Defaults to 64K in the case that there 466ebab2259SFam Zheng * is no cluster size information available. 467ebab2259SFam Zheng */ 468ebab2259SFam Zheng uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs) 469ebab2259SFam Zheng { 470ebab2259SFam Zheng BlockDriverInfo bdi; 471ebab2259SFam Zheng uint32_t granularity; 472ebab2259SFam Zheng 473ebab2259SFam Zheng if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) { 474ebab2259SFam Zheng granularity = MAX(4096, bdi.cluster_size); 475ebab2259SFam Zheng granularity = MIN(65536, granularity); 476ebab2259SFam Zheng } else { 477ebab2259SFam Zheng granularity = 65536; 478ebab2259SFam Zheng } 479ebab2259SFam Zheng 480ebab2259SFam Zheng return granularity; 481ebab2259SFam Zheng } 482ebab2259SFam Zheng 483ba06ff1aSVladimir Sementsov-Ogievskiy uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap) 484ebab2259SFam Zheng { 485ca759622SEric Blake return 1U << hbitmap_granularity(bitmap->bitmap); 486ebab2259SFam Zheng } 487ebab2259SFam Zheng 488715a74d8SEric Blake BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap) 489ebab2259SFam Zheng { 490dc162c8eSFam Zheng BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1); 491715a74d8SEric Blake hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0); 492dc162c8eSFam Zheng iter->bitmap = bitmap; 493dc162c8eSFam Zheng bitmap->active_iterators++; 494dc162c8eSFam Zheng return iter; 495dc162c8eSFam Zheng } 496dc162c8eSFam Zheng 4976d3f4049SFam Zheng BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap) 4986d3f4049SFam Zheng { 4996d3f4049SFam Zheng BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1); 5006d3f4049SFam Zheng hbitmap_iter_init(&iter->hbi, bitmap->meta, 0); 5016d3f4049SFam Zheng iter->bitmap = bitmap; 5026d3f4049SFam Zheng bitmap->active_iterators++; 5036d3f4049SFam Zheng return iter; 5046d3f4049SFam Zheng } 5056d3f4049SFam Zheng 506dc162c8eSFam Zheng void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter) 507dc162c8eSFam Zheng { 508dc162c8eSFam Zheng if (!iter) { 509dc162c8eSFam Zheng return; 510dc162c8eSFam Zheng } 511dc162c8eSFam Zheng assert(iter->bitmap->active_iterators > 0); 512dc162c8eSFam Zheng iter->bitmap->active_iterators--; 513dc162c8eSFam Zheng g_free(iter); 514dc162c8eSFam Zheng } 515dc162c8eSFam Zheng 516dc162c8eSFam Zheng int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter) 517dc162c8eSFam Zheng { 518a33fbb4fSMax Reitz return hbitmap_iter_next(&iter->hbi, true); 519ebab2259SFam Zheng } 520ebab2259SFam Zheng 52172d10a94SMax Reitz /** 52272d10a94SMax Reitz * Return the next consecutively dirty area in the dirty bitmap 52372d10a94SMax Reitz * belonging to the given iterator @iter. 52472d10a94SMax Reitz * 52572d10a94SMax Reitz * @max_offset: Maximum value that may be returned for 52672d10a94SMax Reitz * *offset + *bytes 52772d10a94SMax Reitz * @offset: Will contain the start offset of the next dirty area 52872d10a94SMax Reitz * @bytes: Will contain the length of the next dirty area 52972d10a94SMax Reitz * 53072d10a94SMax Reitz * Returns: True if a dirty area could be found before max_offset 53172d10a94SMax Reitz * (which means that *offset and *bytes then contain valid 53272d10a94SMax Reitz * values), false otherwise. 53372d10a94SMax Reitz * 53472d10a94SMax Reitz * Note that @iter is never advanced if false is returned. If an area 53572d10a94SMax Reitz * is found (which means that true is returned), it will be advanced 53672d10a94SMax Reitz * past that area. 53772d10a94SMax Reitz */ 53872d10a94SMax Reitz bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset, 53972d10a94SMax Reitz uint64_t *offset, int *bytes) 54072d10a94SMax Reitz { 54172d10a94SMax Reitz uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap); 54272d10a94SMax Reitz uint64_t gran_max_offset; 54372d10a94SMax Reitz int64_t ret; 54472d10a94SMax Reitz int size; 54572d10a94SMax Reitz 54672d10a94SMax Reitz if (max_offset == iter->bitmap->size) { 54772d10a94SMax Reitz /* If max_offset points to the image end, round it up by the 54872d10a94SMax Reitz * bitmap granularity */ 54972d10a94SMax Reitz gran_max_offset = ROUND_UP(max_offset, granularity); 55072d10a94SMax Reitz } else { 55172d10a94SMax Reitz gran_max_offset = max_offset; 55272d10a94SMax Reitz } 55372d10a94SMax Reitz 55472d10a94SMax Reitz ret = hbitmap_iter_next(&iter->hbi, false); 55572d10a94SMax Reitz if (ret < 0 || ret + granularity > gran_max_offset) { 55672d10a94SMax Reitz return false; 55772d10a94SMax Reitz } 55872d10a94SMax Reitz 55972d10a94SMax Reitz *offset = ret; 56072d10a94SMax Reitz size = 0; 56172d10a94SMax Reitz 56272d10a94SMax Reitz assert(granularity <= INT_MAX); 56372d10a94SMax Reitz 56472d10a94SMax Reitz do { 56572d10a94SMax Reitz /* Advance iterator */ 56672d10a94SMax Reitz ret = hbitmap_iter_next(&iter->hbi, true); 56772d10a94SMax Reitz size += granularity; 56872d10a94SMax Reitz } while (ret + granularity <= gran_max_offset && 56972d10a94SMax Reitz hbitmap_iter_next(&iter->hbi, false) == ret + granularity && 57072d10a94SMax Reitz size <= INT_MAX - granularity); 57172d10a94SMax Reitz 57272d10a94SMax Reitz *bytes = MIN(size, max_offset - *offset); 57372d10a94SMax Reitz return true; 57472d10a94SMax Reitz } 57572d10a94SMax Reitz 576b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 577b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, 578e0d7f73eSEric Blake int64_t offset, int64_t bytes) 579ebab2259SFam Zheng { 580ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 581d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 582ca759622SEric Blake hbitmap_set(bitmap->bitmap, offset, bytes); 583ebab2259SFam Zheng } 584ebab2259SFam Zheng 585b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap, 586e0d7f73eSEric Blake int64_t offset, int64_t bytes) 587b64bd51eSPaolo Bonzini { 588b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 589e0d7f73eSEric Blake bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes); 590b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 591b64bd51eSPaolo Bonzini } 592b64bd51eSPaolo Bonzini 593b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 594b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, 595e0d7f73eSEric Blake int64_t offset, int64_t bytes) 596ebab2259SFam Zheng { 597ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 598d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 599ca759622SEric Blake hbitmap_reset(bitmap->bitmap, offset, bytes); 600ebab2259SFam Zheng } 601ebab2259SFam Zheng 602b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap, 603e0d7f73eSEric Blake int64_t offset, int64_t bytes) 604b64bd51eSPaolo Bonzini { 605b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 606e0d7f73eSEric Blake bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes); 607b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 608b64bd51eSPaolo Bonzini } 609b64bd51eSPaolo Bonzini 610ebab2259SFam Zheng void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out) 611ebab2259SFam Zheng { 612d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 613b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 614ebab2259SFam Zheng if (!out) { 615ebab2259SFam Zheng hbitmap_reset_all(bitmap->bitmap); 616ebab2259SFam Zheng } else { 617ebab2259SFam Zheng HBitmap *backup = bitmap->bitmap; 618ca759622SEric Blake bitmap->bitmap = hbitmap_alloc(bitmap->size, 619ebab2259SFam Zheng hbitmap_granularity(backup)); 620ebab2259SFam Zheng *out = backup; 621ebab2259SFam Zheng } 622b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 623ebab2259SFam Zheng } 624ebab2259SFam Zheng 62556bd6624SVladimir Sementsov-Ogievskiy void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup) 626ebab2259SFam Zheng { 627ebab2259SFam Zheng HBitmap *tmp = bitmap->bitmap; 628d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 62956bd6624SVladimir Sementsov-Ogievskiy bitmap->bitmap = backup; 630ebab2259SFam Zheng hbitmap_free(tmp); 631ebab2259SFam Zheng } 632ebab2259SFam Zheng 633882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap, 63486f6ae67SEric Blake uint64_t offset, uint64_t bytes) 635882c36f5SVladimir Sementsov-Ogievskiy { 636ca759622SEric Blake return hbitmap_serialization_size(bitmap->bitmap, offset, bytes); 637882c36f5SVladimir Sementsov-Ogievskiy } 638882c36f5SVladimir Sementsov-Ogievskiy 639882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap) 640882c36f5SVladimir Sementsov-Ogievskiy { 641ca759622SEric Blake return hbitmap_serialization_align(bitmap->bitmap); 642882c36f5SVladimir Sementsov-Ogievskiy } 643882c36f5SVladimir Sementsov-Ogievskiy 644882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap, 64586f6ae67SEric Blake uint8_t *buf, uint64_t offset, 64686f6ae67SEric Blake uint64_t bytes) 647882c36f5SVladimir Sementsov-Ogievskiy { 648ca759622SEric Blake hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes); 649882c36f5SVladimir Sementsov-Ogievskiy } 650882c36f5SVladimir Sementsov-Ogievskiy 651882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap, 65286f6ae67SEric Blake uint8_t *buf, uint64_t offset, 65386f6ae67SEric Blake uint64_t bytes, bool finish) 654882c36f5SVladimir Sementsov-Ogievskiy { 655ca759622SEric Blake hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish); 656882c36f5SVladimir Sementsov-Ogievskiy } 657882c36f5SVladimir Sementsov-Ogievskiy 658882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap, 65986f6ae67SEric Blake uint64_t offset, uint64_t bytes, 660882c36f5SVladimir Sementsov-Ogievskiy bool finish) 661882c36f5SVladimir Sementsov-Ogievskiy { 662ca759622SEric Blake hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish); 663882c36f5SVladimir Sementsov-Ogievskiy } 664882c36f5SVladimir Sementsov-Ogievskiy 6656bdc8b71SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, 66686f6ae67SEric Blake uint64_t offset, uint64_t bytes, 6676bdc8b71SVladimir Sementsov-Ogievskiy bool finish) 6686bdc8b71SVladimir Sementsov-Ogievskiy { 669ca759622SEric Blake hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish); 6706bdc8b71SVladimir Sementsov-Ogievskiy } 6716bdc8b71SVladimir Sementsov-Ogievskiy 672882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap) 673882c36f5SVladimir Sementsov-Ogievskiy { 674882c36f5SVladimir Sementsov-Ogievskiy hbitmap_deserialize_finish(bitmap->bitmap); 675882c36f5SVladimir Sementsov-Ogievskiy } 676882c36f5SVladimir Sementsov-Ogievskiy 6770fdf1a4fSEric Blake void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes) 678ebab2259SFam Zheng { 679ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 6802119882cSPaolo Bonzini 6812119882cSPaolo Bonzini if (QLIST_EMPTY(&bs->dirty_bitmaps)) { 6822119882cSPaolo Bonzini return; 6832119882cSPaolo Bonzini } 6842119882cSPaolo Bonzini 6852119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 686ebab2259SFam Zheng QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { 687ebab2259SFam Zheng if (!bdrv_dirty_bitmap_enabled(bitmap)) { 688ebab2259SFam Zheng continue; 689ebab2259SFam Zheng } 690d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 691ca759622SEric Blake hbitmap_set(bitmap->bitmap, offset, bytes); 692ebab2259SFam Zheng } 6932119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 694ebab2259SFam Zheng } 695ebab2259SFam Zheng 696ebab2259SFam Zheng /** 697dc162c8eSFam Zheng * Advance a BdrvDirtyBitmapIter to an arbitrary offset. 698ebab2259SFam Zheng */ 699715a74d8SEric Blake void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset) 700ebab2259SFam Zheng { 701ca759622SEric Blake hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset); 702ebab2259SFam Zheng } 703ebab2259SFam Zheng 704ebab2259SFam Zheng int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap) 705ebab2259SFam Zheng { 706ca759622SEric Blake return hbitmap_count(bitmap->bitmap); 707ebab2259SFam Zheng } 7086d3f4049SFam Zheng 7096d3f4049SFam Zheng int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap) 7106d3f4049SFam Zheng { 7116d3f4049SFam Zheng return hbitmap_count(bitmap->meta); 7126d3f4049SFam Zheng } 713d6883bc9SVladimir Sementsov-Ogievskiy 714d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap) 715d6883bc9SVladimir Sementsov-Ogievskiy { 716d6883bc9SVladimir Sementsov-Ogievskiy return bitmap->readonly; 717d6883bc9SVladimir Sementsov-Ogievskiy } 718d6883bc9SVladimir Sementsov-Ogievskiy 719d6883bc9SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 720d6883bc9SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value) 721d6883bc9SVladimir Sementsov-Ogievskiy { 722d6883bc9SVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 723d6883bc9SVladimir Sementsov-Ogievskiy bitmap->readonly = value; 724d6883bc9SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 725d6883bc9SVladimir Sementsov-Ogievskiy } 726d6883bc9SVladimir Sementsov-Ogievskiy 727d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_has_readonly_bitmaps(BlockDriverState *bs) 728d6883bc9SVladimir Sementsov-Ogievskiy { 729d6883bc9SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bm; 730d6883bc9SVladimir Sementsov-Ogievskiy QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 731d6883bc9SVladimir Sementsov-Ogievskiy if (bm->readonly) { 732d6883bc9SVladimir Sementsov-Ogievskiy return true; 733d6883bc9SVladimir Sementsov-Ogievskiy } 734d6883bc9SVladimir Sementsov-Ogievskiy } 735d6883bc9SVladimir Sementsov-Ogievskiy 736d6883bc9SVladimir Sementsov-Ogievskiy return false; 737d6883bc9SVladimir Sementsov-Ogievskiy } 738a0319aacSVladimir Sementsov-Ogievskiy 739a0319aacSVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 740a88b179fSVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent) 741a88b179fSVladimir Sementsov-Ogievskiy { 742a88b179fSVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 743a88b179fSVladimir Sementsov-Ogievskiy bitmap->persistent = persistent; 744a88b179fSVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 745a88b179fSVladimir Sementsov-Ogievskiy } 746a88b179fSVladimir Sementsov-Ogievskiy 7479c98f145SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 7489c98f145SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration) 7499c98f145SVladimir Sementsov-Ogievskiy { 7509c98f145SVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 7519c98f145SVladimir Sementsov-Ogievskiy bitmap->migration = migration; 7529c98f145SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 7539c98f145SVladimir Sementsov-Ogievskiy } 7549c98f145SVladimir Sementsov-Ogievskiy 755a88b179fSVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap) 756a88b179fSVladimir Sementsov-Ogievskiy { 7579c98f145SVladimir Sementsov-Ogievskiy return bitmap->persistent && !bitmap->migration; 758a88b179fSVladimir Sementsov-Ogievskiy } 759a88b179fSVladimir Sementsov-Ogievskiy 760a88b179fSVladimir Sementsov-Ogievskiy bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) 761a88b179fSVladimir Sementsov-Ogievskiy { 762a88b179fSVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bm; 763a88b179fSVladimir Sementsov-Ogievskiy QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 7649c98f145SVladimir Sementsov-Ogievskiy if (bm->persistent && !bm->readonly && !bm->migration) { 765a88b179fSVladimir Sementsov-Ogievskiy return true; 766a88b179fSVladimir Sementsov-Ogievskiy } 767a88b179fSVladimir Sementsov-Ogievskiy } 768a88b179fSVladimir Sementsov-Ogievskiy 769a88b179fSVladimir Sementsov-Ogievskiy return false; 770a88b179fSVladimir Sementsov-Ogievskiy } 7713dd10a06SVladimir Sementsov-Ogievskiy 7723dd10a06SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, 7733dd10a06SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bitmap) 7743dd10a06SVladimir Sementsov-Ogievskiy { 7753dd10a06SVladimir Sementsov-Ogievskiy return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : 7763dd10a06SVladimir Sementsov-Ogievskiy QLIST_NEXT(bitmap, list); 7773dd10a06SVladimir Sementsov-Ogievskiy } 778a3b52535SVladimir Sementsov-Ogievskiy 779a3b52535SVladimir Sementsov-Ogievskiy char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp) 780a3b52535SVladimir Sementsov-Ogievskiy { 781a3b52535SVladimir Sementsov-Ogievskiy return hbitmap_sha256(bitmap->bitmap, errp); 782a3b52535SVladimir Sementsov-Ogievskiy } 78356207df5SVladimir Sementsov-Ogievskiy 784*76d570dcSVladimir Sementsov-Ogievskiy int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset, 785*76d570dcSVladimir Sementsov-Ogievskiy uint64_t bytes) 78656207df5SVladimir Sementsov-Ogievskiy { 787*76d570dcSVladimir Sementsov-Ogievskiy return hbitmap_next_zero(bitmap->bitmap, offset, bytes); 78856207df5SVladimir Sementsov-Ogievskiy } 789b598e531SVladimir Sementsov-Ogievskiy 790b598e531SVladimir Sementsov-Ogievskiy void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, 791fa000f2fSVladimir Sementsov-Ogievskiy HBitmap **backup, Error **errp) 792b598e531SVladimir Sementsov-Ogievskiy { 793fa000f2fSVladimir Sementsov-Ogievskiy bool ret; 794fa000f2fSVladimir Sementsov-Ogievskiy 795b598e531SVladimir Sementsov-Ogievskiy /* only bitmaps from one bds are supported */ 796b598e531SVladimir Sementsov-Ogievskiy assert(dest->mutex == src->mutex); 797b598e531SVladimir Sementsov-Ogievskiy 798b598e531SVladimir Sementsov-Ogievskiy qemu_mutex_lock(dest->mutex); 799b598e531SVladimir Sementsov-Ogievskiy 800283d7a04SJohn Snow if (bdrv_dirty_bitmap_user_locked(dest)) { 801283d7a04SJohn Snow error_setg(errp, "Bitmap '%s' is currently in use by another" 802283d7a04SJohn Snow " operation and cannot be modified", dest->name); 80306bf5006SVladimir Sementsov-Ogievskiy goto out; 80406bf5006SVladimir Sementsov-Ogievskiy } 80506bf5006SVladimir Sementsov-Ogievskiy 80606bf5006SVladimir Sementsov-Ogievskiy if (bdrv_dirty_bitmap_readonly(dest)) { 80706bf5006SVladimir Sementsov-Ogievskiy error_setg(errp, "Bitmap '%s' is readonly and cannot be modified", 80806bf5006SVladimir Sementsov-Ogievskiy dest->name); 80906bf5006SVladimir Sementsov-Ogievskiy goto out; 81006bf5006SVladimir Sementsov-Ogievskiy } 811b598e531SVladimir Sementsov-Ogievskiy 812fa000f2fSVladimir Sementsov-Ogievskiy if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) { 813b598e531SVladimir Sementsov-Ogievskiy error_setg(errp, "Bitmaps are incompatible and can't be merged"); 81406bf5006SVladimir Sementsov-Ogievskiy goto out; 815b598e531SVladimir Sementsov-Ogievskiy } 816b598e531SVladimir Sementsov-Ogievskiy 817fa000f2fSVladimir Sementsov-Ogievskiy if (backup) { 818fa000f2fSVladimir Sementsov-Ogievskiy *backup = dest->bitmap; 819fa000f2fSVladimir Sementsov-Ogievskiy dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup)); 820fa000f2fSVladimir Sementsov-Ogievskiy ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap); 821fa000f2fSVladimir Sementsov-Ogievskiy } else { 822fa000f2fSVladimir Sementsov-Ogievskiy ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap); 823fa000f2fSVladimir Sementsov-Ogievskiy } 824fa000f2fSVladimir Sementsov-Ogievskiy assert(ret); 825fa000f2fSVladimir Sementsov-Ogievskiy 82606bf5006SVladimir Sementsov-Ogievskiy out: 827b598e531SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(dest->mutex); 828b598e531SVladimir Sementsov-Ogievskiy } 829