qemu/block/dirty-bitmap.c
<<
>>
Prefs
   1/*
   2 * Block Dirty Bitmap
   3 *
   4 * Copyright (c) 2016-2017 Red Hat. Inc
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24#include "qemu/osdep.h"
  25#include "qapi/error.h"
  26#include "qemu-common.h"
  27#include "trace.h"
  28#include "block/block_int.h"
  29#include "block/blockjob.h"
  30
  31/**
  32 * A BdrvDirtyBitmap can be in three possible states:
  33 * (1) successor is NULL and disabled is false: full r/w mode
  34 * (2) successor is NULL and disabled is true: read only mode ("disabled")
  35 * (3) successor is set: frozen mode.
  36 *     A frozen bitmap cannot be renamed, deleted, anonymized, cleared, set,
  37 *     or enabled. A frozen bitmap can only abdicate() or reclaim().
  38 */
  39struct BdrvDirtyBitmap {
  40    QemuMutex *mutex;
  41    HBitmap *bitmap;            /* Dirty bitmap implementation */
  42    HBitmap *meta;              /* Meta dirty bitmap */
  43    BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
  44    char *name;                 /* Optional non-empty unique ID */
  45    int64_t size;               /* Size of the bitmap, in bytes */
  46    bool disabled;              /* Bitmap is disabled. It ignores all writes to
  47                                   the device */
  48    int active_iterators;       /* How many iterators are active */
  49    bool readonly;              /* Bitmap is read-only. This field also
  50                                   prevents the respective image from being
  51                                   modified (i.e. blocks writes and discards).
  52                                   Such operations must fail and both the image
  53                                   and this bitmap must remain unchanged while
  54                                   this flag is set. */
  55    bool autoload;              /* For persistent bitmaps: bitmap must be
  56                                   autoloaded on image opening */
  57    bool persistent;            /* bitmap must be saved to owner disk image */
  58    QLIST_ENTRY(BdrvDirtyBitmap) list;
  59};
  60
  61struct BdrvDirtyBitmapIter {
  62    HBitmapIter hbi;
  63    BdrvDirtyBitmap *bitmap;
  64};
  65
  66static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
  67{
  68    qemu_mutex_lock(&bs->dirty_bitmap_mutex);
  69}
  70
  71static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
  72{
  73    qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
  74}
  75
  76void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
  77{
  78    qemu_mutex_lock(bitmap->mutex);
  79}
  80
  81void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
  82{
  83    qemu_mutex_unlock(bitmap->mutex);
  84}
  85
  86/* Called with BQL or dirty_bitmap lock taken.  */
  87BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
  88{
  89    BdrvDirtyBitmap *bm;
  90
  91    assert(name);
  92    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
  93        if (bm->name && !strcmp(name, bm->name)) {
  94            return bm;
  95        }
  96    }
  97    return NULL;
  98}
  99
 100/* Called with BQL taken.  */
 101void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
 102{
 103    assert(!bdrv_dirty_bitmap_frozen(bitmap));
 104    g_free(bitmap->name);
 105    bitmap->name = NULL;
 106    bitmap->persistent = false;
 107    bitmap->autoload = false;
 108}
 109
 110/* Called with BQL taken.  */
 111BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
 112                                          uint32_t granularity,
 113                                          const char *name,
 114                                          Error **errp)
 115{
 116    int64_t bitmap_size;
 117    BdrvDirtyBitmap *bitmap;
 118
 119    assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
 120
 121    if (name && bdrv_find_dirty_bitmap(bs, name)) {
 122        error_setg(errp, "Bitmap already exists: %s", name);
 123        return NULL;
 124    }
 125    bitmap_size = bdrv_getlength(bs);
 126    if (bitmap_size < 0) {
 127        error_setg_errno(errp, -bitmap_size, "could not get length of device");
 128        errno = -bitmap_size;
 129        return NULL;
 130    }
 131    bitmap = g_new0(BdrvDirtyBitmap, 1);
 132    bitmap->mutex = &bs->dirty_bitmap_mutex;
 133    bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
 134    bitmap->size = bitmap_size;
 135    bitmap->name = g_strdup(name);
 136    bitmap->disabled = false;
 137    bdrv_dirty_bitmaps_lock(bs);
 138    QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
 139    bdrv_dirty_bitmaps_unlock(bs);
 140    return bitmap;
 141}
 142
 143/* bdrv_create_meta_dirty_bitmap
 144 *
 145 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
 146 * when a dirty status bit in @bitmap is changed (either from reset to set or
 147 * the other way around), its respective meta dirty bitmap bit will be marked
 148 * dirty as well.
 149 *
 150 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
 151 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
 152 * track.
 153 */
 154void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 155                                   int chunk_size)
 156{
 157    assert(!bitmap->meta);
 158    qemu_mutex_lock(bitmap->mutex);
 159    bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
 160                                       chunk_size * BITS_PER_BYTE);
 161    qemu_mutex_unlock(bitmap->mutex);
 162}
 163
 164void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
 165{
 166    assert(bitmap->meta);
 167    qemu_mutex_lock(bitmap->mutex);
 168    hbitmap_free_meta(bitmap->bitmap);
 169    bitmap->meta = NULL;
 170    qemu_mutex_unlock(bitmap->mutex);
 171}
 172
 173int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
 174{
 175    return bitmap->size;
 176}
 177
 178const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
 179{
 180    return bitmap->name;
 181}
 182
 183/* Called with BQL taken.  */
 184bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
 185{
 186    return bitmap->successor;
 187}
 188
 189/* Called with BQL taken.  */
 190bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
 191{
 192    return !(bitmap->disabled || bitmap->successor);
 193}
 194
 195/* Called with BQL taken.  */
 196DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
 197{
 198    if (bdrv_dirty_bitmap_frozen(bitmap)) {
 199        return DIRTY_BITMAP_STATUS_FROZEN;
 200    } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
 201        return DIRTY_BITMAP_STATUS_DISABLED;
 202    } else {
 203        return DIRTY_BITMAP_STATUS_ACTIVE;
 204    }
 205}
 206
 207/**
 208 * Create a successor bitmap destined to replace this bitmap after an operation.
 209 * Requires that the bitmap is not frozen and has no successor.
 210 * Called with BQL taken.
 211 */
 212int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
 213                                       BdrvDirtyBitmap *bitmap, Error **errp)
 214{
 215    uint64_t granularity;
 216    BdrvDirtyBitmap *child;
 217
 218    if (bdrv_dirty_bitmap_frozen(bitmap)) {
 219        error_setg(errp, "Cannot create a successor for a bitmap that is "
 220                   "currently frozen");
 221        return -1;
 222    }
 223    assert(!bitmap->successor);
 224
 225    /* Create an anonymous successor */
 226    granularity = bdrv_dirty_bitmap_granularity(bitmap);
 227    child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
 228    if (!child) {
 229        return -1;
 230    }
 231
 232    /* Successor will be on or off based on our current state. */
 233    child->disabled = bitmap->disabled;
 234
 235    /* Install the successor and freeze the parent */
 236    bitmap->successor = child;
 237    return 0;
 238}
 239
 240/**
 241 * For a bitmap with a successor, yield our name to the successor,
 242 * delete the old bitmap, and return a handle to the new bitmap.
 243 * Called with BQL taken.
 244 */
 245BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
 246                                            BdrvDirtyBitmap *bitmap,
 247                                            Error **errp)
 248{
 249    char *name;
 250    BdrvDirtyBitmap *successor = bitmap->successor;
 251
 252    if (successor == NULL) {
 253        error_setg(errp, "Cannot relinquish control if "
 254                   "there's no successor present");
 255        return NULL;
 256    }
 257
 258    name = bitmap->name;
 259    bitmap->name = NULL;
 260    successor->name = name;
 261    bitmap->successor = NULL;
 262    successor->persistent = bitmap->persistent;
 263    bitmap->persistent = false;
 264    successor->autoload = bitmap->autoload;
 265    bitmap->autoload = false;
 266    bdrv_release_dirty_bitmap(bs, bitmap);
 267
 268    return successor;
 269}
 270
 271/**
 272 * In cases of failure where we can no longer safely delete the parent,
 273 * we may wish to re-join the parent and child/successor.
 274 * The merged parent will be un-frozen, but not explicitly re-enabled.
 275 * Called with BQL taken.
 276 */
 277BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
 278                                           BdrvDirtyBitmap *parent,
 279                                           Error **errp)
 280{
 281    BdrvDirtyBitmap *successor = parent->successor;
 282
 283    if (!successor) {
 284        error_setg(errp, "Cannot reclaim a successor when none is present");
 285        return NULL;
 286    }
 287
 288    if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
 289        error_setg(errp, "Merging of parent and successor bitmap failed");
 290        return NULL;
 291    }
 292    bdrv_release_dirty_bitmap(bs, successor);
 293    parent->successor = NULL;
 294
 295    return parent;
 296}
 297
 298/**
 299 * Truncates _all_ bitmaps attached to a BDS.
 300 * Called with BQL taken.
 301 */
 302void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
 303{
 304    BdrvDirtyBitmap *bitmap;
 305
 306    bdrv_dirty_bitmaps_lock(bs);
 307    QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
 308        assert(!bdrv_dirty_bitmap_frozen(bitmap));
 309        assert(!bitmap->active_iterators);
 310        hbitmap_truncate(bitmap->bitmap, bytes);
 311        bitmap->size = bytes;
 312    }
 313    bdrv_dirty_bitmaps_unlock(bs);
 314}
 315
 316static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
 317{
 318    return !!bdrv_dirty_bitmap_name(bitmap);
 319}
 320
 321/* Called with BQL taken.  */
 322static void bdrv_do_release_matching_dirty_bitmap(
 323    BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
 324    bool (*cond)(BdrvDirtyBitmap *bitmap))
 325{
 326    BdrvDirtyBitmap *bm, *next;
 327    bdrv_dirty_bitmaps_lock(bs);
 328    QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
 329        if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
 330            assert(!bm->active_iterators);
 331            assert(!bdrv_dirty_bitmap_frozen(bm));
 332            assert(!bm->meta);
 333            QLIST_REMOVE(bm, list);
 334            hbitmap_free(bm->bitmap);
 335            g_free(bm->name);
 336            g_free(bm);
 337
 338            if (bitmap) {
 339                goto out;
 340            }
 341        }
 342    }
 343    if (bitmap) {
 344        abort();
 345    }
 346
 347out:
 348    bdrv_dirty_bitmaps_unlock(bs);
 349}
 350
 351/* Called with BQL taken.  */
 352void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
 353{
 354    bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
 355}
 356
 357/**
 358 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
 359 * There must not be any frozen bitmaps attached.
 360 * This function does not remove persistent bitmaps from the storage.
 361 * Called with BQL taken.
 362 */
 363void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
 364{
 365    bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
 366}
 367
 368/**
 369 * Release all persistent dirty bitmaps attached to a BDS (for use in
 370 * bdrv_inactivate_recurse()).
 371 * There must not be any frozen bitmaps attached.
 372 * This function does not remove persistent bitmaps from the storage.
 373 */
 374void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
 375{
 376    bdrv_do_release_matching_dirty_bitmap(bs, NULL,
 377                                          bdrv_dirty_bitmap_get_persistance);
 378}
 379
 380/**
 381 * Remove persistent dirty bitmap from the storage if it exists.
 382 * Absence of bitmap is not an error, because we have the following scenario:
 383 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
 384 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
 385 * not fail.
 386 * This function doesn't release corresponding BdrvDirtyBitmap.
 387 */
 388void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
 389                                         const char *name,
 390                                         Error **errp)
 391{
 392    if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
 393        bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
 394    }
 395}
 396
 397/* Called with BQL taken.  */
 398void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
 399{
 400    assert(!bdrv_dirty_bitmap_frozen(bitmap));
 401    bitmap->disabled = true;
 402}
 403
 404/* Called with BQL taken.  */
 405void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
 406{
 407    assert(!bdrv_dirty_bitmap_frozen(bitmap));
 408    bitmap->disabled = false;
 409}
 410
 411BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
 412{
 413    BdrvDirtyBitmap *bm;
 414    BlockDirtyInfoList *list = NULL;
 415    BlockDirtyInfoList **plist = &list;
 416
 417    bdrv_dirty_bitmaps_lock(bs);
 418    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 419        BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
 420        BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
 421        info->count = bdrv_get_dirty_count(bm);
 422        info->granularity = bdrv_dirty_bitmap_granularity(bm);
 423        info->has_name = !!bm->name;
 424        info->name = g_strdup(bm->name);
 425        info->status = bdrv_dirty_bitmap_status(bm);
 426        entry->value = info;
 427        *plist = entry;
 428        plist = &entry->next;
 429    }
 430    bdrv_dirty_bitmaps_unlock(bs);
 431
 432    return list;
 433}
 434
 435/* Called within bdrv_dirty_bitmap_lock..unlock */
 436bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
 437                           int64_t offset)
 438{
 439    if (bitmap) {
 440        return hbitmap_get(bitmap->bitmap, offset);
 441    } else {
 442        return false;
 443    }
 444}
 445
 446/**
 447 * Chooses a default granularity based on the existing cluster size,
 448 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
 449 * is no cluster size information available.
 450 */
 451uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
 452{
 453    BlockDriverInfo bdi;
 454    uint32_t granularity;
 455
 456    if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
 457        granularity = MAX(4096, bdi.cluster_size);
 458        granularity = MIN(65536, granularity);
 459    } else {
 460        granularity = 65536;
 461    }
 462
 463    return granularity;
 464}
 465
 466uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
 467{
 468    return 1U << hbitmap_granularity(bitmap->bitmap);
 469}
 470
 471BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
 472{
 473    BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
 474    hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
 475    iter->bitmap = bitmap;
 476    bitmap->active_iterators++;
 477    return iter;
 478}
 479
 480BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
 481{
 482    BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
 483    hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
 484    iter->bitmap = bitmap;
 485    bitmap->active_iterators++;
 486    return iter;
 487}
 488
 489void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
 490{
 491    if (!iter) {
 492        return;
 493    }
 494    assert(iter->bitmap->active_iterators > 0);
 495    iter->bitmap->active_iterators--;
 496    g_free(iter);
 497}
 498
 499int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
 500{
 501    return hbitmap_iter_next(&iter->hbi);
 502}
 503
 504/* Called within bdrv_dirty_bitmap_lock..unlock */
 505void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 506                                  int64_t offset, int64_t bytes)
 507{
 508    assert(bdrv_dirty_bitmap_enabled(bitmap));
 509    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 510    hbitmap_set(bitmap->bitmap, offset, bytes);
 511}
 512
 513void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 514                           int64_t offset, int64_t bytes)
 515{
 516    bdrv_dirty_bitmap_lock(bitmap);
 517    bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
 518    bdrv_dirty_bitmap_unlock(bitmap);
 519}
 520
 521/* Called within bdrv_dirty_bitmap_lock..unlock */
 522void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 523                                    int64_t offset, int64_t bytes)
 524{
 525    assert(bdrv_dirty_bitmap_enabled(bitmap));
 526    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 527    hbitmap_reset(bitmap->bitmap, offset, bytes);
 528}
 529
 530void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 531                             int64_t offset, int64_t bytes)
 532{
 533    bdrv_dirty_bitmap_lock(bitmap);
 534    bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
 535    bdrv_dirty_bitmap_unlock(bitmap);
 536}
 537
 538void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
 539{
 540    assert(bdrv_dirty_bitmap_enabled(bitmap));
 541    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 542    bdrv_dirty_bitmap_lock(bitmap);
 543    if (!out) {
 544        hbitmap_reset_all(bitmap->bitmap);
 545    } else {
 546        HBitmap *backup = bitmap->bitmap;
 547        bitmap->bitmap = hbitmap_alloc(bitmap->size,
 548                                       hbitmap_granularity(backup));
 549        *out = backup;
 550    }
 551    bdrv_dirty_bitmap_unlock(bitmap);
 552}
 553
 554void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
 555{
 556    HBitmap *tmp = bitmap->bitmap;
 557    assert(bdrv_dirty_bitmap_enabled(bitmap));
 558    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 559    bitmap->bitmap = in;
 560    hbitmap_free(tmp);
 561}
 562
 563uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
 564                                              uint64_t offset, uint64_t bytes)
 565{
 566    return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
 567}
 568
 569uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
 570{
 571    return hbitmap_serialization_align(bitmap->bitmap);
 572}
 573
 574void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
 575                                      uint8_t *buf, uint64_t offset,
 576                                      uint64_t bytes)
 577{
 578    hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
 579}
 580
 581void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
 582                                        uint8_t *buf, uint64_t offset,
 583                                        uint64_t bytes, bool finish)
 584{
 585    hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
 586}
 587
 588void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
 589                                          uint64_t offset, uint64_t bytes,
 590                                          bool finish)
 591{
 592    hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
 593}
 594
 595void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
 596                                        uint64_t offset, uint64_t bytes,
 597                                        bool finish)
 598{
 599    hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
 600}
 601
 602void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
 603{
 604    hbitmap_deserialize_finish(bitmap->bitmap);
 605}
 606
 607void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
 608{
 609    BdrvDirtyBitmap *bitmap;
 610
 611    if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
 612        return;
 613    }
 614
 615    bdrv_dirty_bitmaps_lock(bs);
 616    QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
 617        if (!bdrv_dirty_bitmap_enabled(bitmap)) {
 618            continue;
 619        }
 620        assert(!bdrv_dirty_bitmap_readonly(bitmap));
 621        hbitmap_set(bitmap->bitmap, offset, bytes);
 622    }
 623    bdrv_dirty_bitmaps_unlock(bs);
 624}
 625
 626/**
 627 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
 628 */
 629void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
 630{
 631    hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
 632}
 633
 634int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
 635{
 636    return hbitmap_count(bitmap->bitmap);
 637}
 638
 639int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
 640{
 641    return hbitmap_count(bitmap->meta);
 642}
 643
 644bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
 645{
 646    return bitmap->readonly;
 647}
 648
 649/* Called with BQL taken. */
 650void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
 651{
 652    qemu_mutex_lock(bitmap->mutex);
 653    bitmap->readonly = value;
 654    qemu_mutex_unlock(bitmap->mutex);
 655}
 656
 657bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
 658{
 659    BdrvDirtyBitmap *bm;
 660    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 661        if (bm->readonly) {
 662            return true;
 663        }
 664    }
 665
 666    return false;
 667}
 668
 669/* Called with BQL taken. */
 670void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload)
 671{
 672    qemu_mutex_lock(bitmap->mutex);
 673    bitmap->autoload = autoload;
 674    qemu_mutex_unlock(bitmap->mutex);
 675}
 676
 677bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
 678{
 679    return bitmap->autoload;
 680}
 681
 682/* Called with BQL taken. */
 683void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
 684{
 685    qemu_mutex_lock(bitmap->mutex);
 686    bitmap->persistent = persistent;
 687    qemu_mutex_unlock(bitmap->mutex);
 688}
 689
 690bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
 691{
 692    return bitmap->persistent;
 693}
 694
 695bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
 696{
 697    BdrvDirtyBitmap *bm;
 698    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 699        if (bm->persistent && !bm->readonly) {
 700            return true;
 701        }
 702    }
 703
 704    return false;
 705}
 706
 707BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
 708                                        BdrvDirtyBitmap *bitmap)
 709{
 710    return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
 711                            QLIST_NEXT(bitmap, list);
 712}
 713
 714char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
 715{
 716    return hbitmap_sha256(bitmap->bitmap, errp);
 717}
 718