1ebab2259SFam Zheng /* 2ebab2259SFam Zheng * Block Dirty Bitmap 3ebab2259SFam Zheng * 4ebab2259SFam Zheng * Copyright (c) 2016 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; 41ebab2259SFam Zheng HBitmap *bitmap; /* Dirty sector bitmap implementation */ 42fb933437SFam Zheng HBitmap *meta; /* Meta dirty bitmap */ 43ebab2259SFam Zheng BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */ 44ebab2259SFam Zheng char *name; /* Optional non-empty unique ID */ 45ebab2259SFam Zheng int64_t size; /* Size of the bitmap (Number of sectors) */ 468bfc932eSVladimir Sementsov-Ogievskiy bool disabled; /* Bitmap is disabled. It ignores all writes to 478bfc932eSVladimir Sementsov-Ogievskiy the device */ 48dc162c8eSFam Zheng int active_iterators; /* How many iterators are active */ 49*d6883bc9SVladimir Sementsov-Ogievskiy bool readonly; /* Bitmap is read-only. This field also 50*d6883bc9SVladimir Sementsov-Ogievskiy prevents the respective image from being 51*d6883bc9SVladimir Sementsov-Ogievskiy modified (i.e. blocks writes and discards). 52*d6883bc9SVladimir Sementsov-Ogievskiy Such operations must fail and both the image 53*d6883bc9SVladimir Sementsov-Ogievskiy and this bitmap must remain unchanged while 54*d6883bc9SVladimir Sementsov-Ogievskiy this flag is set. */ 55ebab2259SFam Zheng QLIST_ENTRY(BdrvDirtyBitmap) list; 56ebab2259SFam Zheng }; 57ebab2259SFam Zheng 58dc162c8eSFam Zheng struct BdrvDirtyBitmapIter { 59dc162c8eSFam Zheng HBitmapIter hbi; 60dc162c8eSFam Zheng BdrvDirtyBitmap *bitmap; 61dc162c8eSFam Zheng }; 62dc162c8eSFam Zheng 632119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs) 642119882cSPaolo Bonzini { 652119882cSPaolo Bonzini qemu_mutex_lock(&bs->dirty_bitmap_mutex); 662119882cSPaolo Bonzini } 672119882cSPaolo Bonzini 682119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs) 692119882cSPaolo Bonzini { 702119882cSPaolo Bonzini qemu_mutex_unlock(&bs->dirty_bitmap_mutex); 712119882cSPaolo Bonzini } 722119882cSPaolo Bonzini 73b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap) 74b64bd51eSPaolo Bonzini { 75b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 76b64bd51eSPaolo Bonzini } 77b64bd51eSPaolo Bonzini 78b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap) 79b64bd51eSPaolo Bonzini { 80b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 81b64bd51eSPaolo Bonzini } 82b64bd51eSPaolo Bonzini 832119882cSPaolo Bonzini /* Called with BQL or dirty_bitmap lock taken. */ 84ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name) 85ebab2259SFam Zheng { 86ebab2259SFam Zheng BdrvDirtyBitmap *bm; 87ebab2259SFam Zheng 88ebab2259SFam Zheng assert(name); 89ebab2259SFam Zheng QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 90ebab2259SFam Zheng if (bm->name && !strcmp(name, bm->name)) { 91ebab2259SFam Zheng return bm; 92ebab2259SFam Zheng } 93ebab2259SFam Zheng } 94ebab2259SFam Zheng return NULL; 95ebab2259SFam Zheng } 96ebab2259SFam Zheng 972119882cSPaolo Bonzini /* Called with BQL taken. */ 98ebab2259SFam Zheng void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap) 99ebab2259SFam Zheng { 100ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 101ebab2259SFam Zheng g_free(bitmap->name); 102ebab2259SFam Zheng bitmap->name = NULL; 103ebab2259SFam Zheng } 104ebab2259SFam Zheng 1052119882cSPaolo Bonzini /* Called with BQL taken. */ 106ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, 107ebab2259SFam Zheng uint32_t granularity, 108ebab2259SFam Zheng const char *name, 109ebab2259SFam Zheng Error **errp) 110ebab2259SFam Zheng { 111ebab2259SFam Zheng int64_t bitmap_size; 112ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 113ebab2259SFam Zheng uint32_t sector_granularity; 114ebab2259SFam Zheng 115ebab2259SFam Zheng assert((granularity & (granularity - 1)) == 0); 116ebab2259SFam Zheng 117ebab2259SFam Zheng if (name && bdrv_find_dirty_bitmap(bs, name)) { 118ebab2259SFam Zheng error_setg(errp, "Bitmap already exists: %s", name); 119ebab2259SFam Zheng return NULL; 120ebab2259SFam Zheng } 121ebab2259SFam Zheng sector_granularity = granularity >> BDRV_SECTOR_BITS; 122ebab2259SFam Zheng assert(sector_granularity); 123ebab2259SFam Zheng bitmap_size = bdrv_nb_sectors(bs); 124ebab2259SFam Zheng if (bitmap_size < 0) { 125ebab2259SFam Zheng error_setg_errno(errp, -bitmap_size, "could not get length of device"); 126ebab2259SFam Zheng errno = -bitmap_size; 127ebab2259SFam Zheng return NULL; 128ebab2259SFam Zheng } 129ebab2259SFam Zheng bitmap = g_new0(BdrvDirtyBitmap, 1); 130b64bd51eSPaolo Bonzini bitmap->mutex = &bs->dirty_bitmap_mutex; 131ebab2259SFam Zheng bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity)); 132ebab2259SFam Zheng bitmap->size = bitmap_size; 133ebab2259SFam Zheng bitmap->name = g_strdup(name); 134ebab2259SFam Zheng bitmap->disabled = false; 1352119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 136ebab2259SFam Zheng QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list); 1372119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 138ebab2259SFam Zheng return bitmap; 139ebab2259SFam Zheng } 140ebab2259SFam Zheng 141fb933437SFam Zheng /* bdrv_create_meta_dirty_bitmap 142fb933437SFam Zheng * 143fb933437SFam Zheng * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e. 144fb933437SFam Zheng * when a dirty status bit in @bitmap is changed (either from reset to set or 145fb933437SFam Zheng * the other way around), its respective meta dirty bitmap bit will be marked 146fb933437SFam Zheng * dirty as well. 147fb933437SFam Zheng * 148fb933437SFam Zheng * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap. 149fb933437SFam Zheng * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap 150fb933437SFam Zheng * track. 151fb933437SFam Zheng */ 152fb933437SFam Zheng void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap, 153fb933437SFam Zheng int chunk_size) 154fb933437SFam Zheng { 155fb933437SFam Zheng assert(!bitmap->meta); 156b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 157fb933437SFam Zheng bitmap->meta = hbitmap_create_meta(bitmap->bitmap, 158fb933437SFam Zheng chunk_size * BITS_PER_BYTE); 159b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 160fb933437SFam Zheng } 161fb933437SFam Zheng 162fb933437SFam Zheng void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap) 163fb933437SFam Zheng { 164fb933437SFam Zheng assert(bitmap->meta); 165b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 166fb933437SFam Zheng hbitmap_free_meta(bitmap->bitmap); 167fb933437SFam Zheng bitmap->meta = NULL; 168b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 169fb933437SFam Zheng } 170fb933437SFam Zheng 171b64bd51eSPaolo Bonzini int bdrv_dirty_bitmap_get_meta_locked(BlockDriverState *bs, 172fb933437SFam Zheng BdrvDirtyBitmap *bitmap, int64_t sector, 173fb933437SFam Zheng int nb_sectors) 174fb933437SFam Zheng { 175fb933437SFam Zheng uint64_t i; 176fb933437SFam Zheng int sectors_per_bit = 1 << hbitmap_granularity(bitmap->meta); 177fb933437SFam Zheng 178fb933437SFam Zheng /* To optimize: we can make hbitmap to internally check the range in a 179fb933437SFam Zheng * coarse level, or at least do it word by word. */ 180fb933437SFam Zheng for (i = sector; i < sector + nb_sectors; i += sectors_per_bit) { 181fb933437SFam Zheng if (hbitmap_get(bitmap->meta, i)) { 182fb933437SFam Zheng return true; 183fb933437SFam Zheng } 184fb933437SFam Zheng } 185fb933437SFam Zheng return false; 186fb933437SFam Zheng } 187fb933437SFam Zheng 188b64bd51eSPaolo Bonzini int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs, 189b64bd51eSPaolo Bonzini BdrvDirtyBitmap *bitmap, int64_t sector, 190b64bd51eSPaolo Bonzini int nb_sectors) 191b64bd51eSPaolo Bonzini { 192b64bd51eSPaolo Bonzini bool dirty; 193b64bd51eSPaolo Bonzini 194b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 195b64bd51eSPaolo Bonzini dirty = bdrv_dirty_bitmap_get_meta_locked(bs, bitmap, sector, nb_sectors); 196b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 197b64bd51eSPaolo Bonzini 198b64bd51eSPaolo Bonzini return dirty; 199b64bd51eSPaolo Bonzini } 200b64bd51eSPaolo Bonzini 201fb933437SFam Zheng void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs, 202fb933437SFam Zheng BdrvDirtyBitmap *bitmap, int64_t sector, 203fb933437SFam Zheng int nb_sectors) 204fb933437SFam Zheng { 205b64bd51eSPaolo Bonzini qemu_mutex_lock(bitmap->mutex); 206fb933437SFam Zheng hbitmap_reset(bitmap->meta, sector, nb_sectors); 207b64bd51eSPaolo Bonzini qemu_mutex_unlock(bitmap->mutex); 208fb933437SFam Zheng } 209fb933437SFam Zheng 21015891facSFam Zheng int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap) 21115891facSFam Zheng { 21215891facSFam Zheng return bitmap->size; 21315891facSFam Zheng } 21415891facSFam Zheng 21515891facSFam Zheng const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap) 21615891facSFam Zheng { 21715891facSFam Zheng return bitmap->name; 21815891facSFam Zheng } 21915891facSFam Zheng 2202119882cSPaolo Bonzini /* Called with BQL taken. */ 221ebab2259SFam Zheng bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap) 222ebab2259SFam Zheng { 223ebab2259SFam Zheng return bitmap->successor; 224ebab2259SFam Zheng } 225ebab2259SFam Zheng 2262119882cSPaolo Bonzini /* Called with BQL taken. */ 227ebab2259SFam Zheng bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap) 228ebab2259SFam Zheng { 229ebab2259SFam Zheng return !(bitmap->disabled || bitmap->successor); 230ebab2259SFam Zheng } 231ebab2259SFam Zheng 2322119882cSPaolo Bonzini /* Called with BQL taken. */ 233ebab2259SFam Zheng DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap) 234ebab2259SFam Zheng { 235ebab2259SFam Zheng if (bdrv_dirty_bitmap_frozen(bitmap)) { 236ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_FROZEN; 237ebab2259SFam Zheng } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { 238ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_DISABLED; 239ebab2259SFam Zheng } else { 240ebab2259SFam Zheng return DIRTY_BITMAP_STATUS_ACTIVE; 241ebab2259SFam Zheng } 242ebab2259SFam Zheng } 243ebab2259SFam Zheng 244ebab2259SFam Zheng /** 245ebab2259SFam Zheng * Create a successor bitmap destined to replace this bitmap after an operation. 246ebab2259SFam Zheng * Requires that the bitmap is not frozen and has no successor. 2472119882cSPaolo Bonzini * Called with BQL taken. 248ebab2259SFam Zheng */ 249ebab2259SFam Zheng int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs, 250ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, Error **errp) 251ebab2259SFam Zheng { 252ebab2259SFam Zheng uint64_t granularity; 253ebab2259SFam Zheng BdrvDirtyBitmap *child; 254ebab2259SFam Zheng 255ebab2259SFam Zheng if (bdrv_dirty_bitmap_frozen(bitmap)) { 256ebab2259SFam Zheng error_setg(errp, "Cannot create a successor for a bitmap that is " 257ebab2259SFam Zheng "currently frozen"); 258ebab2259SFam Zheng return -1; 259ebab2259SFam Zheng } 260ebab2259SFam Zheng assert(!bitmap->successor); 261ebab2259SFam Zheng 262ebab2259SFam Zheng /* Create an anonymous successor */ 263ebab2259SFam Zheng granularity = bdrv_dirty_bitmap_granularity(bitmap); 264ebab2259SFam Zheng child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); 265ebab2259SFam Zheng if (!child) { 266ebab2259SFam Zheng return -1; 267ebab2259SFam Zheng } 268ebab2259SFam Zheng 269ebab2259SFam Zheng /* Successor will be on or off based on our current state. */ 270ebab2259SFam Zheng child->disabled = bitmap->disabled; 271ebab2259SFam Zheng 272ebab2259SFam Zheng /* Install the successor and freeze the parent */ 273ebab2259SFam Zheng bitmap->successor = child; 274ebab2259SFam Zheng return 0; 275ebab2259SFam Zheng } 276ebab2259SFam Zheng 277ebab2259SFam Zheng /** 278ebab2259SFam Zheng * For a bitmap with a successor, yield our name to the successor, 279ebab2259SFam Zheng * delete the old bitmap, and return a handle to the new bitmap. 2802119882cSPaolo Bonzini * Called with BQL taken. 281ebab2259SFam Zheng */ 282ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs, 283ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, 284ebab2259SFam Zheng Error **errp) 285ebab2259SFam Zheng { 286ebab2259SFam Zheng char *name; 287ebab2259SFam Zheng BdrvDirtyBitmap *successor = bitmap->successor; 288ebab2259SFam Zheng 289ebab2259SFam Zheng if (successor == NULL) { 290ebab2259SFam Zheng error_setg(errp, "Cannot relinquish control if " 291ebab2259SFam Zheng "there's no successor present"); 292ebab2259SFam Zheng return NULL; 293ebab2259SFam Zheng } 294ebab2259SFam Zheng 295ebab2259SFam Zheng name = bitmap->name; 296ebab2259SFam Zheng bitmap->name = NULL; 297ebab2259SFam Zheng successor->name = name; 298ebab2259SFam Zheng bitmap->successor = NULL; 299ebab2259SFam Zheng bdrv_release_dirty_bitmap(bs, bitmap); 300ebab2259SFam Zheng 301ebab2259SFam Zheng return successor; 302ebab2259SFam Zheng } 303ebab2259SFam Zheng 304ebab2259SFam Zheng /** 305ebab2259SFam Zheng * In cases of failure where we can no longer safely delete the parent, 306ebab2259SFam Zheng * we may wish to re-join the parent and child/successor. 307ebab2259SFam Zheng * The merged parent will be un-frozen, but not explicitly re-enabled. 3082119882cSPaolo Bonzini * Called with BQL taken. 309ebab2259SFam Zheng */ 310ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, 311ebab2259SFam Zheng BdrvDirtyBitmap *parent, 312ebab2259SFam Zheng Error **errp) 313ebab2259SFam Zheng { 314ebab2259SFam Zheng BdrvDirtyBitmap *successor = parent->successor; 315ebab2259SFam Zheng 316ebab2259SFam Zheng if (!successor) { 317ebab2259SFam Zheng error_setg(errp, "Cannot reclaim a successor when none is present"); 318ebab2259SFam Zheng return NULL; 319ebab2259SFam Zheng } 320ebab2259SFam Zheng 321ebab2259SFam Zheng if (!hbitmap_merge(parent->bitmap, successor->bitmap)) { 322ebab2259SFam Zheng error_setg(errp, "Merging of parent and successor bitmap failed"); 323ebab2259SFam Zheng return NULL; 324ebab2259SFam Zheng } 325ebab2259SFam Zheng bdrv_release_dirty_bitmap(bs, successor); 326ebab2259SFam Zheng parent->successor = NULL; 327ebab2259SFam Zheng 328ebab2259SFam Zheng return parent; 329ebab2259SFam Zheng } 330ebab2259SFam Zheng 331ebab2259SFam Zheng /** 332ebab2259SFam Zheng * Truncates _all_ bitmaps attached to a BDS. 3332119882cSPaolo Bonzini * Called with BQL taken. 334ebab2259SFam Zheng */ 335ebab2259SFam Zheng void bdrv_dirty_bitmap_truncate(BlockDriverState *bs) 336ebab2259SFam Zheng { 337ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 338ebab2259SFam Zheng uint64_t size = bdrv_nb_sectors(bs); 339ebab2259SFam Zheng 3402119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 341ebab2259SFam Zheng QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { 342ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 343dc162c8eSFam Zheng assert(!bitmap->active_iterators); 344ebab2259SFam Zheng hbitmap_truncate(bitmap->bitmap, size); 345ebab2259SFam Zheng bitmap->size = size; 346ebab2259SFam Zheng } 3472119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 348ebab2259SFam Zheng } 349ebab2259SFam Zheng 3502119882cSPaolo Bonzini /* Called with BQL taken. */ 351ebab2259SFam Zheng static void bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs, 352ebab2259SFam Zheng BdrvDirtyBitmap *bitmap, 353ebab2259SFam Zheng bool only_named) 354ebab2259SFam Zheng { 355ebab2259SFam Zheng BdrvDirtyBitmap *bm, *next; 3562119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 357ebab2259SFam Zheng QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { 358ebab2259SFam Zheng if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) { 359dc162c8eSFam Zheng assert(!bm->active_iterators); 360ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bm)); 361fb933437SFam Zheng assert(!bm->meta); 362ebab2259SFam Zheng QLIST_REMOVE(bm, list); 363ebab2259SFam Zheng hbitmap_free(bm->bitmap); 364ebab2259SFam Zheng g_free(bm->name); 365ebab2259SFam Zheng g_free(bm); 366ebab2259SFam Zheng 367ebab2259SFam Zheng if (bitmap) { 3682119882cSPaolo Bonzini goto out; 369ebab2259SFam Zheng } 370ebab2259SFam Zheng } 371ebab2259SFam Zheng } 3727105007aSFam Zheng if (bitmap) { 3737105007aSFam Zheng abort(); 3747105007aSFam Zheng } 3752119882cSPaolo Bonzini 3762119882cSPaolo Bonzini out: 3772119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 378ebab2259SFam Zheng } 379ebab2259SFam Zheng 3802119882cSPaolo Bonzini /* Called with BQL taken. */ 381ebab2259SFam Zheng void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) 382ebab2259SFam Zheng { 383ebab2259SFam Zheng bdrv_do_release_matching_dirty_bitmap(bs, bitmap, false); 384ebab2259SFam Zheng } 385ebab2259SFam Zheng 386ebab2259SFam Zheng /** 387ebab2259SFam Zheng * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()). 388ebab2259SFam Zheng * There must not be any frozen bitmaps attached. 3892119882cSPaolo Bonzini * Called with BQL taken. 390ebab2259SFam Zheng */ 391ebab2259SFam Zheng void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs) 392ebab2259SFam Zheng { 393ebab2259SFam Zheng bdrv_do_release_matching_dirty_bitmap(bs, NULL, true); 394ebab2259SFam Zheng } 395ebab2259SFam Zheng 3962119882cSPaolo Bonzini /* Called with BQL taken. */ 397ebab2259SFam Zheng void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap) 398ebab2259SFam Zheng { 399ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 400ebab2259SFam Zheng bitmap->disabled = true; 401ebab2259SFam Zheng } 402ebab2259SFam Zheng 4032119882cSPaolo Bonzini /* Called with BQL taken. */ 404ebab2259SFam Zheng void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap) 405ebab2259SFam Zheng { 406ebab2259SFam Zheng assert(!bdrv_dirty_bitmap_frozen(bitmap)); 407ebab2259SFam Zheng bitmap->disabled = false; 408ebab2259SFam Zheng } 409ebab2259SFam Zheng 410ebab2259SFam Zheng BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) 411ebab2259SFam Zheng { 412ebab2259SFam Zheng BdrvDirtyBitmap *bm; 413ebab2259SFam Zheng BlockDirtyInfoList *list = NULL; 414ebab2259SFam Zheng BlockDirtyInfoList **plist = &list; 415ebab2259SFam Zheng 4162119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 417ebab2259SFam Zheng QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 418ebab2259SFam Zheng BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1); 419ebab2259SFam Zheng BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1); 420ebab2259SFam Zheng info->count = bdrv_get_dirty_count(bm); 421ebab2259SFam Zheng info->granularity = bdrv_dirty_bitmap_granularity(bm); 422ebab2259SFam Zheng info->has_name = !!bm->name; 423ebab2259SFam Zheng info->name = g_strdup(bm->name); 424ebab2259SFam Zheng info->status = bdrv_dirty_bitmap_status(bm); 425ebab2259SFam Zheng entry->value = info; 426ebab2259SFam Zheng *plist = entry; 427ebab2259SFam Zheng plist = &entry->next; 428ebab2259SFam Zheng } 4292119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 430ebab2259SFam Zheng 431ebab2259SFam Zheng return list; 432ebab2259SFam Zheng } 433ebab2259SFam Zheng 434b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 435b64bd51eSPaolo Bonzini int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, 436ebab2259SFam Zheng int64_t sector) 437ebab2259SFam Zheng { 438ebab2259SFam Zheng if (bitmap) { 439ebab2259SFam Zheng return hbitmap_get(bitmap->bitmap, sector); 440ebab2259SFam Zheng } else { 441ebab2259SFam Zheng return 0; 442ebab2259SFam Zheng } 443ebab2259SFam Zheng } 444ebab2259SFam Zheng 445ebab2259SFam Zheng /** 446ebab2259SFam Zheng * Chooses a default granularity based on the existing cluster size, 447ebab2259SFam Zheng * but clamped between [4K, 64K]. Defaults to 64K in the case that there 448ebab2259SFam Zheng * is no cluster size information available. 449ebab2259SFam Zheng */ 450ebab2259SFam Zheng uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs) 451ebab2259SFam Zheng { 452ebab2259SFam Zheng BlockDriverInfo bdi; 453ebab2259SFam Zheng uint32_t granularity; 454ebab2259SFam Zheng 455ebab2259SFam Zheng if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) { 456ebab2259SFam Zheng granularity = MAX(4096, bdi.cluster_size); 457ebab2259SFam Zheng granularity = MIN(65536, granularity); 458ebab2259SFam Zheng } else { 459ebab2259SFam Zheng granularity = 65536; 460ebab2259SFam Zheng } 461ebab2259SFam Zheng 462ebab2259SFam Zheng return granularity; 463ebab2259SFam Zheng } 464ebab2259SFam Zheng 465ba06ff1aSVladimir Sementsov-Ogievskiy uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap) 466ebab2259SFam Zheng { 467ebab2259SFam Zheng return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap); 468ebab2259SFam Zheng } 469ebab2259SFam Zheng 4706d3f4049SFam Zheng uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap) 4716d3f4049SFam Zheng { 4726d3f4049SFam Zheng return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta); 4736d3f4049SFam Zheng } 4746d3f4049SFam Zheng 475dc162c8eSFam Zheng BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap, 476dc162c8eSFam Zheng uint64_t first_sector) 477ebab2259SFam Zheng { 478dc162c8eSFam Zheng BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1); 479dc162c8eSFam Zheng hbitmap_iter_init(&iter->hbi, bitmap->bitmap, first_sector); 480dc162c8eSFam Zheng iter->bitmap = bitmap; 481dc162c8eSFam Zheng bitmap->active_iterators++; 482dc162c8eSFam Zheng return iter; 483dc162c8eSFam Zheng } 484dc162c8eSFam Zheng 4856d3f4049SFam Zheng BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap) 4866d3f4049SFam Zheng { 4876d3f4049SFam Zheng BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1); 4886d3f4049SFam Zheng hbitmap_iter_init(&iter->hbi, bitmap->meta, 0); 4896d3f4049SFam Zheng iter->bitmap = bitmap; 4906d3f4049SFam Zheng bitmap->active_iterators++; 4916d3f4049SFam Zheng return iter; 4926d3f4049SFam Zheng } 4936d3f4049SFam Zheng 494dc162c8eSFam Zheng void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter) 495dc162c8eSFam Zheng { 496dc162c8eSFam Zheng if (!iter) { 497dc162c8eSFam Zheng return; 498dc162c8eSFam Zheng } 499dc162c8eSFam Zheng assert(iter->bitmap->active_iterators > 0); 500dc162c8eSFam Zheng iter->bitmap->active_iterators--; 501dc162c8eSFam Zheng g_free(iter); 502dc162c8eSFam Zheng } 503dc162c8eSFam Zheng 504dc162c8eSFam Zheng int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter) 505dc162c8eSFam Zheng { 506dc162c8eSFam Zheng return hbitmap_iter_next(&iter->hbi); 507ebab2259SFam Zheng } 508ebab2259SFam Zheng 509b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 510b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, 5116d078599SDenis V. Lunev int64_t cur_sector, int64_t nr_sectors) 512ebab2259SFam Zheng { 513ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 514*d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 515ebab2259SFam Zheng hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors); 516ebab2259SFam Zheng } 517ebab2259SFam Zheng 518b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap, 519b64bd51eSPaolo Bonzini int64_t cur_sector, int64_t nr_sectors) 520b64bd51eSPaolo Bonzini { 521b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 522b64bd51eSPaolo Bonzini bdrv_set_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors); 523b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 524b64bd51eSPaolo Bonzini } 525b64bd51eSPaolo Bonzini 526b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */ 527b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, 5286d078599SDenis V. Lunev int64_t cur_sector, int64_t nr_sectors) 529ebab2259SFam Zheng { 530ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 531*d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 532ebab2259SFam Zheng hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors); 533ebab2259SFam Zheng } 534ebab2259SFam Zheng 535b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap, 536b64bd51eSPaolo Bonzini int64_t cur_sector, int64_t nr_sectors) 537b64bd51eSPaolo Bonzini { 538b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 539b64bd51eSPaolo Bonzini bdrv_reset_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors); 540b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 541b64bd51eSPaolo Bonzini } 542b64bd51eSPaolo Bonzini 543ebab2259SFam Zheng void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out) 544ebab2259SFam Zheng { 545ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 546*d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 547b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_lock(bitmap); 548ebab2259SFam Zheng if (!out) { 549ebab2259SFam Zheng hbitmap_reset_all(bitmap->bitmap); 550ebab2259SFam Zheng } else { 551ebab2259SFam Zheng HBitmap *backup = bitmap->bitmap; 552ebab2259SFam Zheng bitmap->bitmap = hbitmap_alloc(bitmap->size, 553ebab2259SFam Zheng hbitmap_granularity(backup)); 554ebab2259SFam Zheng *out = backup; 555ebab2259SFam Zheng } 556b64bd51eSPaolo Bonzini bdrv_dirty_bitmap_unlock(bitmap); 557ebab2259SFam Zheng } 558ebab2259SFam Zheng 559ebab2259SFam Zheng void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in) 560ebab2259SFam Zheng { 561ebab2259SFam Zheng HBitmap *tmp = bitmap->bitmap; 562ebab2259SFam Zheng assert(bdrv_dirty_bitmap_enabled(bitmap)); 563*d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 564ebab2259SFam Zheng bitmap->bitmap = in; 565ebab2259SFam Zheng hbitmap_free(tmp); 566ebab2259SFam Zheng } 567ebab2259SFam Zheng 568882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap, 569882c36f5SVladimir Sementsov-Ogievskiy uint64_t start, uint64_t count) 570882c36f5SVladimir Sementsov-Ogievskiy { 571882c36f5SVladimir Sementsov-Ogievskiy return hbitmap_serialization_size(bitmap->bitmap, start, count); 572882c36f5SVladimir Sementsov-Ogievskiy } 573882c36f5SVladimir Sementsov-Ogievskiy 574882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap) 575882c36f5SVladimir Sementsov-Ogievskiy { 576882c36f5SVladimir Sementsov-Ogievskiy return hbitmap_serialization_granularity(bitmap->bitmap); 577882c36f5SVladimir Sementsov-Ogievskiy } 578882c36f5SVladimir Sementsov-Ogievskiy 579882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap, 580882c36f5SVladimir Sementsov-Ogievskiy uint8_t *buf, uint64_t start, 581882c36f5SVladimir Sementsov-Ogievskiy uint64_t count) 582882c36f5SVladimir Sementsov-Ogievskiy { 583882c36f5SVladimir Sementsov-Ogievskiy hbitmap_serialize_part(bitmap->bitmap, buf, start, count); 584882c36f5SVladimir Sementsov-Ogievskiy } 585882c36f5SVladimir Sementsov-Ogievskiy 586882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap, 587882c36f5SVladimir Sementsov-Ogievskiy uint8_t *buf, uint64_t start, 588882c36f5SVladimir Sementsov-Ogievskiy uint64_t count, bool finish) 589882c36f5SVladimir Sementsov-Ogievskiy { 590882c36f5SVladimir Sementsov-Ogievskiy hbitmap_deserialize_part(bitmap->bitmap, buf, start, count, finish); 591882c36f5SVladimir Sementsov-Ogievskiy } 592882c36f5SVladimir Sementsov-Ogievskiy 593882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap, 594882c36f5SVladimir Sementsov-Ogievskiy uint64_t start, uint64_t count, 595882c36f5SVladimir Sementsov-Ogievskiy bool finish) 596882c36f5SVladimir Sementsov-Ogievskiy { 597882c36f5SVladimir Sementsov-Ogievskiy hbitmap_deserialize_zeroes(bitmap->bitmap, start, count, finish); 598882c36f5SVladimir Sementsov-Ogievskiy } 599882c36f5SVladimir Sementsov-Ogievskiy 6006bdc8b71SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, 6016bdc8b71SVladimir Sementsov-Ogievskiy uint64_t start, uint64_t count, 6026bdc8b71SVladimir Sementsov-Ogievskiy bool finish) 6036bdc8b71SVladimir Sementsov-Ogievskiy { 6046bdc8b71SVladimir Sementsov-Ogievskiy hbitmap_deserialize_ones(bitmap->bitmap, start, count, finish); 6056bdc8b71SVladimir Sementsov-Ogievskiy } 6066bdc8b71SVladimir Sementsov-Ogievskiy 607882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap) 608882c36f5SVladimir Sementsov-Ogievskiy { 609882c36f5SVladimir Sementsov-Ogievskiy hbitmap_deserialize_finish(bitmap->bitmap); 610882c36f5SVladimir Sementsov-Ogievskiy } 611882c36f5SVladimir Sementsov-Ogievskiy 612ebab2259SFam Zheng void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, 6136d078599SDenis V. Lunev int64_t nr_sectors) 614ebab2259SFam Zheng { 615ebab2259SFam Zheng BdrvDirtyBitmap *bitmap; 6162119882cSPaolo Bonzini 6172119882cSPaolo Bonzini if (QLIST_EMPTY(&bs->dirty_bitmaps)) { 6182119882cSPaolo Bonzini return; 6192119882cSPaolo Bonzini } 6202119882cSPaolo Bonzini 6212119882cSPaolo Bonzini bdrv_dirty_bitmaps_lock(bs); 622ebab2259SFam Zheng QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { 623ebab2259SFam Zheng if (!bdrv_dirty_bitmap_enabled(bitmap)) { 624ebab2259SFam Zheng continue; 625ebab2259SFam Zheng } 626*d6883bc9SVladimir Sementsov-Ogievskiy assert(!bdrv_dirty_bitmap_readonly(bitmap)); 627ebab2259SFam Zheng hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors); 628ebab2259SFam Zheng } 6292119882cSPaolo Bonzini bdrv_dirty_bitmaps_unlock(bs); 630ebab2259SFam Zheng } 631ebab2259SFam Zheng 632ebab2259SFam Zheng /** 633dc162c8eSFam Zheng * Advance a BdrvDirtyBitmapIter to an arbitrary offset. 634ebab2259SFam Zheng */ 635dc162c8eSFam Zheng void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num) 636ebab2259SFam Zheng { 637dc162c8eSFam Zheng hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num); 638ebab2259SFam Zheng } 639ebab2259SFam Zheng 640ebab2259SFam Zheng int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap) 641ebab2259SFam Zheng { 642ebab2259SFam Zheng return hbitmap_count(bitmap->bitmap); 643ebab2259SFam Zheng } 6446d3f4049SFam Zheng 6456d3f4049SFam Zheng int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap) 6466d3f4049SFam Zheng { 6476d3f4049SFam Zheng return hbitmap_count(bitmap->meta); 6486d3f4049SFam Zheng } 649*d6883bc9SVladimir Sementsov-Ogievskiy 650*d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap) 651*d6883bc9SVladimir Sementsov-Ogievskiy { 652*d6883bc9SVladimir Sementsov-Ogievskiy return bitmap->readonly; 653*d6883bc9SVladimir Sementsov-Ogievskiy } 654*d6883bc9SVladimir Sementsov-Ogievskiy 655*d6883bc9SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */ 656*d6883bc9SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value) 657*d6883bc9SVladimir Sementsov-Ogievskiy { 658*d6883bc9SVladimir Sementsov-Ogievskiy qemu_mutex_lock(bitmap->mutex); 659*d6883bc9SVladimir Sementsov-Ogievskiy bitmap->readonly = value; 660*d6883bc9SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(bitmap->mutex); 661*d6883bc9SVladimir Sementsov-Ogievskiy } 662*d6883bc9SVladimir Sementsov-Ogievskiy 663*d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_has_readonly_bitmaps(BlockDriverState *bs) 664*d6883bc9SVladimir Sementsov-Ogievskiy { 665*d6883bc9SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bm; 666*d6883bc9SVladimir Sementsov-Ogievskiy QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 667*d6883bc9SVladimir Sementsov-Ogievskiy if (bm->readonly) { 668*d6883bc9SVladimir Sementsov-Ogievskiy return true; 669*d6883bc9SVladimir Sementsov-Ogievskiy } 670*d6883bc9SVladimir Sementsov-Ogievskiy } 671*d6883bc9SVladimir Sementsov-Ogievskiy 672*d6883bc9SVladimir Sementsov-Ogievskiy return false; 673*d6883bc9SVladimir Sementsov-Ogievskiy } 674