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    bool qmp_locked;            /* Bitmap is locked, it can't be modified
  44                                   through QMP */
  45    BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
  46    char *name;                 /* Optional non-empty unique ID */
  47    int64_t size;               /* Size of the bitmap, in bytes */
  48    bool disabled;              /* Bitmap is disabled. It ignores all writes to
  49                                   the device */
  50    int active_iterators;       /* How many iterators are active */
  51    bool readonly;              /* Bitmap is read-only. This field also
  52                                   prevents the respective image from being
  53                                   modified (i.e. blocks writes and discards).
  54                                   Such operations must fail and both the image
  55                                   and this bitmap must remain unchanged while
  56                                   this flag is set. */
  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}
 108
 109/* Called with BQL taken.  */
 110BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
 111                                          uint32_t granularity,
 112                                          const char *name,
 113                                          Error **errp)
 114{
 115    int64_t bitmap_size;
 116    BdrvDirtyBitmap *bitmap;
 117
 118    assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
 119
 120    if (name && bdrv_find_dirty_bitmap(bs, name)) {
 121        error_setg(errp, "Bitmap already exists: %s", name);
 122        return NULL;
 123    }
 124    bitmap_size = bdrv_getlength(bs);
 125    if (bitmap_size < 0) {
 126        error_setg_errno(errp, -bitmap_size, "could not get length of device");
 127        errno = -bitmap_size;
 128        return NULL;
 129    }
 130    bitmap = g_new0(BdrvDirtyBitmap, 1);
 131    bitmap->mutex = &bs->dirty_bitmap_mutex;
 132    bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
 133    bitmap->size = bitmap_size;
 134    bitmap->name = g_strdup(name);
 135    bitmap->disabled = false;
 136    bdrv_dirty_bitmaps_lock(bs);
 137    QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
 138    bdrv_dirty_bitmaps_unlock(bs);
 139    return bitmap;
 140}
 141
 142/* bdrv_create_meta_dirty_bitmap
 143 *
 144 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
 145 * when a dirty status bit in @bitmap is changed (either from reset to set or
 146 * the other way around), its respective meta dirty bitmap bit will be marked
 147 * dirty as well.
 148 *
 149 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
 150 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
 151 * track.
 152 */
 153void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 154                                   int chunk_size)
 155{
 156    assert(!bitmap->meta);
 157    qemu_mutex_lock(bitmap->mutex);
 158    bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
 159                                       chunk_size * BITS_PER_BYTE);
 160    qemu_mutex_unlock(bitmap->mutex);
 161}
 162
 163void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
 164{
 165    assert(bitmap->meta);
 166    qemu_mutex_lock(bitmap->mutex);
 167    hbitmap_free_meta(bitmap->bitmap);
 168    bitmap->meta = NULL;
 169    qemu_mutex_unlock(bitmap->mutex);
 170}
 171
 172int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
 173{
 174    return bitmap->size;
 175}
 176
 177const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
 178{
 179    return bitmap->name;
 180}
 181
 182/* Called with BQL taken.  */
 183bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
 184{
 185    return bitmap->successor;
 186}
 187
 188void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked)
 189{
 190    qemu_mutex_lock(bitmap->mutex);
 191    bitmap->qmp_locked = qmp_locked;
 192    qemu_mutex_unlock(bitmap->mutex);
 193}
 194
 195bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap)
 196{
 197    return bitmap->qmp_locked;
 198}
 199
 200/* Called with BQL taken.  */
 201bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
 202{
 203    return !(bitmap->disabled || bitmap->successor);
 204}
 205
 206/* Called with BQL taken.  */
 207DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
 208{
 209    if (bdrv_dirty_bitmap_frozen(bitmap)) {
 210        return DIRTY_BITMAP_STATUS_FROZEN;
 211    } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) {
 212        return DIRTY_BITMAP_STATUS_LOCKED;
 213    } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
 214        return DIRTY_BITMAP_STATUS_DISABLED;
 215    } else {
 216        return DIRTY_BITMAP_STATUS_ACTIVE;
 217    }
 218}
 219
 220/**
 221 * Create a successor bitmap destined to replace this bitmap after an operation.
 222 * Requires that the bitmap is not frozen and has no successor.
 223 * Called with BQL taken.
 224 */
 225int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
 226                                       BdrvDirtyBitmap *bitmap, Error **errp)
 227{
 228    uint64_t granularity;
 229    BdrvDirtyBitmap *child;
 230
 231    if (bdrv_dirty_bitmap_frozen(bitmap)) {
 232        error_setg(errp, "Cannot create a successor for a bitmap that is "
 233                   "currently frozen");
 234        return -1;
 235    }
 236    assert(!bitmap->successor);
 237
 238    /* Create an anonymous successor */
 239    granularity = bdrv_dirty_bitmap_granularity(bitmap);
 240    child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
 241    if (!child) {
 242        return -1;
 243    }
 244
 245    /* Successor will be on or off based on our current state. */
 246    child->disabled = bitmap->disabled;
 247
 248    /* Install the successor and freeze the parent */
 249    bitmap->successor = child;
 250    return 0;
 251}
 252
 253/* Called with BQL taken. */
 254void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
 255{
 256    qemu_mutex_lock(bitmap->mutex);
 257    bdrv_enable_dirty_bitmap(bitmap->successor);
 258    qemu_mutex_unlock(bitmap->mutex);
 259}
 260
 261/* Called within bdrv_dirty_bitmap_lock..unlock */
 262static void bdrv_do_release_matching_dirty_bitmap_locked(
 263    BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
 264    bool (*cond)(BdrvDirtyBitmap *bitmap))
 265{
 266    BdrvDirtyBitmap *bm, *next;
 267
 268    QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
 269        if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
 270            assert(!bm->active_iterators);
 271            assert(!bdrv_dirty_bitmap_frozen(bm));
 272            assert(!bm->meta);
 273            QLIST_REMOVE(bm, list);
 274            hbitmap_free(bm->bitmap);
 275            g_free(bm->name);
 276            g_free(bm);
 277
 278            if (bitmap) {
 279                return;
 280            }
 281        }
 282    }
 283
 284    if (bitmap) {
 285        abort();
 286    }
 287}
 288
 289/* Called with BQL taken.  */
 290static void bdrv_do_release_matching_dirty_bitmap(
 291    BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
 292    bool (*cond)(BdrvDirtyBitmap *bitmap))
 293{
 294    bdrv_dirty_bitmaps_lock(bs);
 295    bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, cond);
 296    bdrv_dirty_bitmaps_unlock(bs);
 297}
 298
 299/* Called within bdrv_dirty_bitmap_lock..unlock */
 300static void bdrv_release_dirty_bitmap_locked(BlockDriverState *bs,
 301                                             BdrvDirtyBitmap *bitmap)
 302{
 303    bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, NULL);
 304}
 305
 306/**
 307 * For a bitmap with a successor, yield our name to the successor,
 308 * delete the old bitmap, and return a handle to the new bitmap.
 309 * Called with BQL taken.
 310 */
 311BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
 312                                            BdrvDirtyBitmap *bitmap,
 313                                            Error **errp)
 314{
 315    char *name;
 316    BdrvDirtyBitmap *successor = bitmap->successor;
 317
 318    if (successor == NULL) {
 319        error_setg(errp, "Cannot relinquish control if "
 320                   "there's no successor present");
 321        return NULL;
 322    }
 323
 324    name = bitmap->name;
 325    bitmap->name = NULL;
 326    successor->name = name;
 327    bitmap->successor = NULL;
 328    successor->persistent = bitmap->persistent;
 329    bitmap->persistent = false;
 330    bdrv_release_dirty_bitmap(bs, bitmap);
 331
 332    return successor;
 333}
 334
 335/**
 336 * In cases of failure where we can no longer safely delete the parent,
 337 * we may wish to re-join the parent and child/successor.
 338 * The merged parent will be un-frozen, but not explicitly re-enabled.
 339 * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
 340 */
 341BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
 342                                                  BdrvDirtyBitmap *parent,
 343                                                  Error **errp)
 344{
 345    BdrvDirtyBitmap *successor = parent->successor;
 346
 347    if (!successor) {
 348        error_setg(errp, "Cannot reclaim a successor when none is present");
 349        return NULL;
 350    }
 351
 352    if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
 353        error_setg(errp, "Merging of parent and successor bitmap failed");
 354        return NULL;
 355    }
 356    bdrv_release_dirty_bitmap_locked(bs, successor);
 357    parent->successor = NULL;
 358
 359    return parent;
 360}
 361
 362/* Called with BQL taken. */
 363BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
 364                                           BdrvDirtyBitmap *parent,
 365                                           Error **errp)
 366{
 367    BdrvDirtyBitmap *ret;
 368
 369    qemu_mutex_lock(parent->mutex);
 370    ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp);
 371    qemu_mutex_unlock(parent->mutex);
 372
 373    return ret;
 374}
 375
 376/**
 377 * Truncates _all_ bitmaps attached to a BDS.
 378 * Called with BQL taken.
 379 */
 380void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
 381{
 382    BdrvDirtyBitmap *bitmap;
 383
 384    bdrv_dirty_bitmaps_lock(bs);
 385    QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
 386        assert(!bdrv_dirty_bitmap_frozen(bitmap));
 387        assert(!bitmap->active_iterators);
 388        hbitmap_truncate(bitmap->bitmap, bytes);
 389        bitmap->size = bytes;
 390    }
 391    bdrv_dirty_bitmaps_unlock(bs);
 392}
 393
 394static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
 395{
 396    return !!bdrv_dirty_bitmap_name(bitmap);
 397}
 398
 399/* Called with BQL taken.  */
 400void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
 401{
 402    bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
 403}
 404
 405/**
 406 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
 407 * There must not be any frozen bitmaps attached.
 408 * This function does not remove persistent bitmaps from the storage.
 409 * Called with BQL taken.
 410 */
 411void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
 412{
 413    bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
 414}
 415
 416/**
 417 * Release all persistent dirty bitmaps attached to a BDS (for use in
 418 * bdrv_inactivate_recurse()).
 419 * There must not be any frozen bitmaps attached.
 420 * This function does not remove persistent bitmaps from the storage.
 421 */
 422void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
 423{
 424    bdrv_do_release_matching_dirty_bitmap(bs, NULL,
 425                                          bdrv_dirty_bitmap_get_persistance);
 426}
 427
 428/**
 429 * Remove persistent dirty bitmap from the storage if it exists.
 430 * Absence of bitmap is not an error, because we have the following scenario:
 431 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
 432 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
 433 * not fail.
 434 * This function doesn't release corresponding BdrvDirtyBitmap.
 435 */
 436void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
 437                                         const char *name,
 438                                         Error **errp)
 439{
 440    if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
 441        bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
 442    }
 443}
 444
 445/* Called with BQL taken.  */
 446void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
 447{
 448    assert(!bdrv_dirty_bitmap_frozen(bitmap));
 449    bitmap->disabled = true;
 450}
 451
 452/* Called with BQL taken.  */
 453void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
 454{
 455    assert(!bdrv_dirty_bitmap_frozen(bitmap));
 456    bitmap->disabled = false;
 457}
 458
 459BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
 460{
 461    BdrvDirtyBitmap *bm;
 462    BlockDirtyInfoList *list = NULL;
 463    BlockDirtyInfoList **plist = &list;
 464
 465    bdrv_dirty_bitmaps_lock(bs);
 466    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 467        BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
 468        BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
 469        info->count = bdrv_get_dirty_count(bm);
 470        info->granularity = bdrv_dirty_bitmap_granularity(bm);
 471        info->has_name = !!bm->name;
 472        info->name = g_strdup(bm->name);
 473        info->status = bdrv_dirty_bitmap_status(bm);
 474        entry->value = info;
 475        *plist = entry;
 476        plist = &entry->next;
 477    }
 478    bdrv_dirty_bitmaps_unlock(bs);
 479
 480    return list;
 481}
 482
 483/* Called within bdrv_dirty_bitmap_lock..unlock */
 484bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
 485                           int64_t offset)
 486{
 487    if (bitmap) {
 488        return hbitmap_get(bitmap->bitmap, offset);
 489    } else {
 490        return false;
 491    }
 492}
 493
 494/**
 495 * Chooses a default granularity based on the existing cluster size,
 496 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
 497 * is no cluster size information available.
 498 */
 499uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
 500{
 501    BlockDriverInfo bdi;
 502    uint32_t granularity;
 503
 504    if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
 505        granularity = MAX(4096, bdi.cluster_size);
 506        granularity = MIN(65536, granularity);
 507    } else {
 508        granularity = 65536;
 509    }
 510
 511    return granularity;
 512}
 513
 514uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
 515{
 516    return 1U << hbitmap_granularity(bitmap->bitmap);
 517}
 518
 519BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
 520{
 521    BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
 522    hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
 523    iter->bitmap = bitmap;
 524    bitmap->active_iterators++;
 525    return iter;
 526}
 527
 528BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
 529{
 530    BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
 531    hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
 532    iter->bitmap = bitmap;
 533    bitmap->active_iterators++;
 534    return iter;
 535}
 536
 537void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
 538{
 539    if (!iter) {
 540        return;
 541    }
 542    assert(iter->bitmap->active_iterators > 0);
 543    iter->bitmap->active_iterators--;
 544    g_free(iter);
 545}
 546
 547int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
 548{
 549    return hbitmap_iter_next(&iter->hbi);
 550}
 551
 552/* Called within bdrv_dirty_bitmap_lock..unlock */
 553void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 554                                  int64_t offset, int64_t bytes)
 555{
 556    assert(bdrv_dirty_bitmap_enabled(bitmap));
 557    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 558    hbitmap_set(bitmap->bitmap, offset, bytes);
 559}
 560
 561void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 562                           int64_t offset, int64_t bytes)
 563{
 564    bdrv_dirty_bitmap_lock(bitmap);
 565    bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
 566    bdrv_dirty_bitmap_unlock(bitmap);
 567}
 568
 569/* Called within bdrv_dirty_bitmap_lock..unlock */
 570void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 571                                    int64_t offset, int64_t bytes)
 572{
 573    assert(bdrv_dirty_bitmap_enabled(bitmap));
 574    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 575    hbitmap_reset(bitmap->bitmap, offset, bytes);
 576}
 577
 578void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 579                             int64_t offset, int64_t bytes)
 580{
 581    bdrv_dirty_bitmap_lock(bitmap);
 582    bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
 583    bdrv_dirty_bitmap_unlock(bitmap);
 584}
 585
 586void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
 587{
 588    assert(bdrv_dirty_bitmap_enabled(bitmap));
 589    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 590    bdrv_dirty_bitmap_lock(bitmap);
 591    if (!out) {
 592        hbitmap_reset_all(bitmap->bitmap);
 593    } else {
 594        HBitmap *backup = bitmap->bitmap;
 595        bitmap->bitmap = hbitmap_alloc(bitmap->size,
 596                                       hbitmap_granularity(backup));
 597        *out = backup;
 598    }
 599    bdrv_dirty_bitmap_unlock(bitmap);
 600}
 601
 602void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
 603{
 604    HBitmap *tmp = bitmap->bitmap;
 605    assert(bdrv_dirty_bitmap_enabled(bitmap));
 606    assert(!bdrv_dirty_bitmap_readonly(bitmap));
 607    bitmap->bitmap = in;
 608    hbitmap_free(tmp);
 609}
 610
 611uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
 612                                              uint64_t offset, uint64_t bytes)
 613{
 614    return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
 615}
 616
 617uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
 618{
 619    return hbitmap_serialization_align(bitmap->bitmap);
 620}
 621
 622void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
 623                                      uint8_t *buf, uint64_t offset,
 624                                      uint64_t bytes)
 625{
 626    hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
 627}
 628
 629void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
 630                                        uint8_t *buf, uint64_t offset,
 631                                        uint64_t bytes, bool finish)
 632{
 633    hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
 634}
 635
 636void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
 637                                          uint64_t offset, uint64_t bytes,
 638                                          bool finish)
 639{
 640    hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
 641}
 642
 643void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
 644                                        uint64_t offset, uint64_t bytes,
 645                                        bool finish)
 646{
 647    hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
 648}
 649
 650void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
 651{
 652    hbitmap_deserialize_finish(bitmap->bitmap);
 653}
 654
 655void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
 656{
 657    BdrvDirtyBitmap *bitmap;
 658
 659    if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
 660        return;
 661    }
 662
 663    bdrv_dirty_bitmaps_lock(bs);
 664    QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
 665        if (!bdrv_dirty_bitmap_enabled(bitmap)) {
 666            continue;
 667        }
 668        assert(!bdrv_dirty_bitmap_readonly(bitmap));
 669        hbitmap_set(bitmap->bitmap, offset, bytes);
 670    }
 671    bdrv_dirty_bitmaps_unlock(bs);
 672}
 673
 674/**
 675 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
 676 */
 677void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
 678{
 679    hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
 680}
 681
 682int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
 683{
 684    return hbitmap_count(bitmap->bitmap);
 685}
 686
 687int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
 688{
 689    return hbitmap_count(bitmap->meta);
 690}
 691
 692bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
 693{
 694    return bitmap->readonly;
 695}
 696
 697/* Called with BQL taken. */
 698void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
 699{
 700    qemu_mutex_lock(bitmap->mutex);
 701    bitmap->readonly = value;
 702    qemu_mutex_unlock(bitmap->mutex);
 703}
 704
 705bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
 706{
 707    BdrvDirtyBitmap *bm;
 708    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 709        if (bm->readonly) {
 710            return true;
 711        }
 712    }
 713
 714    return false;
 715}
 716
 717/* Called with BQL taken. */
 718void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
 719{
 720    qemu_mutex_lock(bitmap->mutex);
 721    bitmap->persistent = persistent;
 722    qemu_mutex_unlock(bitmap->mutex);
 723}
 724
 725bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
 726{
 727    return bitmap->persistent;
 728}
 729
 730bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
 731{
 732    BdrvDirtyBitmap *bm;
 733    QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 734        if (bm->persistent && !bm->readonly) {
 735            return true;
 736        }
 737    }
 738
 739    return false;
 740}
 741
 742BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
 743                                        BdrvDirtyBitmap *bitmap)
 744{
 745    return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
 746                            QLIST_NEXT(bitmap, list);
 747}
 748
 749char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
 750{
 751    return hbitmap_sha256(bitmap->bitmap, errp);
 752}
 753
 754int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
 755{
 756    return hbitmap_next_zero(bitmap->bitmap, offset);
 757}
 758