target/sh4: Consolidate end-of-TB tests
[qemu/ar7.git] / block / dirty-bitmap.c
blob543bddb9b5d0ec014a23eb6b3aa3b89bdb4e1379
1 /*
2 * Block Dirty Bitmap
4 * Copyright (c) 2016 Red Hat. Inc
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
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"
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().
39 struct BdrvDirtyBitmap {
40 QemuMutex *mutex;
41 HBitmap *bitmap; /* Dirty sector 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 (Number of sectors) */
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;
61 struct BdrvDirtyBitmapIter {
62 HBitmapIter hbi;
63 BdrvDirtyBitmap *bitmap;
66 static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
68 qemu_mutex_lock(&bs->dirty_bitmap_mutex);
71 static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
73 qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
76 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
78 qemu_mutex_lock(bitmap->mutex);
81 void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
83 qemu_mutex_unlock(bitmap->mutex);
86 /* Called with BQL or dirty_bitmap lock taken. */
87 BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
89 BdrvDirtyBitmap *bm;
91 assert(name);
92 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
93 if (bm->name && !strcmp(name, bm->name)) {
94 return bm;
97 return NULL;
100 /* Called with BQL taken. */
101 void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
103 assert(!bdrv_dirty_bitmap_frozen(bitmap));
104 g_free(bitmap->name);
105 bitmap->name = NULL;
106 bitmap->persistent = false;
107 bitmap->autoload = false;
110 /* Called with BQL taken. */
111 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
112 uint32_t granularity,
113 const char *name,
114 Error **errp)
116 int64_t bitmap_size;
117 BdrvDirtyBitmap *bitmap;
118 uint32_t sector_granularity;
120 assert((granularity & (granularity - 1)) == 0);
122 if (name && bdrv_find_dirty_bitmap(bs, name)) {
123 error_setg(errp, "Bitmap already exists: %s", name);
124 return NULL;
126 sector_granularity = granularity >> BDRV_SECTOR_BITS;
127 assert(sector_granularity);
128 bitmap_size = bdrv_nb_sectors(bs);
129 if (bitmap_size < 0) {
130 error_setg_errno(errp, -bitmap_size, "could not get length of device");
131 errno = -bitmap_size;
132 return NULL;
134 bitmap = g_new0(BdrvDirtyBitmap, 1);
135 bitmap->mutex = &bs->dirty_bitmap_mutex;
136 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
137 bitmap->size = bitmap_size;
138 bitmap->name = g_strdup(name);
139 bitmap->disabled = false;
140 bdrv_dirty_bitmaps_lock(bs);
141 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
142 bdrv_dirty_bitmaps_unlock(bs);
143 return bitmap;
146 /* bdrv_create_meta_dirty_bitmap
148 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
149 * when a dirty status bit in @bitmap is changed (either from reset to set or
150 * the other way around), its respective meta dirty bitmap bit will be marked
151 * dirty as well.
153 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
154 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
155 * track.
157 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
158 int chunk_size)
160 assert(!bitmap->meta);
161 qemu_mutex_lock(bitmap->mutex);
162 bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
163 chunk_size * BITS_PER_BYTE);
164 qemu_mutex_unlock(bitmap->mutex);
167 void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
169 assert(bitmap->meta);
170 qemu_mutex_lock(bitmap->mutex);
171 hbitmap_free_meta(bitmap->bitmap);
172 bitmap->meta = NULL;
173 qemu_mutex_unlock(bitmap->mutex);
176 int bdrv_dirty_bitmap_get_meta_locked(BlockDriverState *bs,
177 BdrvDirtyBitmap *bitmap, int64_t sector,
178 int nb_sectors)
180 uint64_t i;
181 int sectors_per_bit = 1 << hbitmap_granularity(bitmap->meta);
183 /* To optimize: we can make hbitmap to internally check the range in a
184 * coarse level, or at least do it word by word. */
185 for (i = sector; i < sector + nb_sectors; i += sectors_per_bit) {
186 if (hbitmap_get(bitmap->meta, i)) {
187 return true;
190 return false;
193 int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
194 BdrvDirtyBitmap *bitmap, int64_t sector,
195 int nb_sectors)
197 bool dirty;
199 qemu_mutex_lock(bitmap->mutex);
200 dirty = bdrv_dirty_bitmap_get_meta_locked(bs, bitmap, sector, nb_sectors);
201 qemu_mutex_unlock(bitmap->mutex);
203 return dirty;
206 void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
207 BdrvDirtyBitmap *bitmap, int64_t sector,
208 int nb_sectors)
210 qemu_mutex_lock(bitmap->mutex);
211 hbitmap_reset(bitmap->meta, sector, nb_sectors);
212 qemu_mutex_unlock(bitmap->mutex);
215 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
217 return bitmap->size;
220 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
222 return bitmap->name;
225 /* Called with BQL taken. */
226 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
228 return bitmap->successor;
231 /* Called with BQL taken. */
232 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
234 return !(bitmap->disabled || bitmap->successor);
237 /* Called with BQL taken. */
238 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
240 if (bdrv_dirty_bitmap_frozen(bitmap)) {
241 return DIRTY_BITMAP_STATUS_FROZEN;
242 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
243 return DIRTY_BITMAP_STATUS_DISABLED;
244 } else {
245 return DIRTY_BITMAP_STATUS_ACTIVE;
250 * Create a successor bitmap destined to replace this bitmap after an operation.
251 * Requires that the bitmap is not frozen and has no successor.
252 * Called with BQL taken.
254 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
255 BdrvDirtyBitmap *bitmap, Error **errp)
257 uint64_t granularity;
258 BdrvDirtyBitmap *child;
260 if (bdrv_dirty_bitmap_frozen(bitmap)) {
261 error_setg(errp, "Cannot create a successor for a bitmap that is "
262 "currently frozen");
263 return -1;
265 assert(!bitmap->successor);
267 /* Create an anonymous successor */
268 granularity = bdrv_dirty_bitmap_granularity(bitmap);
269 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
270 if (!child) {
271 return -1;
274 /* Successor will be on or off based on our current state. */
275 child->disabled = bitmap->disabled;
277 /* Install the successor and freeze the parent */
278 bitmap->successor = child;
279 return 0;
283 * For a bitmap with a successor, yield our name to the successor,
284 * delete the old bitmap, and return a handle to the new bitmap.
285 * Called with BQL taken.
287 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
288 BdrvDirtyBitmap *bitmap,
289 Error **errp)
291 char *name;
292 BdrvDirtyBitmap *successor = bitmap->successor;
294 if (successor == NULL) {
295 error_setg(errp, "Cannot relinquish control if "
296 "there's no successor present");
297 return NULL;
300 name = bitmap->name;
301 bitmap->name = NULL;
302 successor->name = name;
303 bitmap->successor = NULL;
304 successor->persistent = bitmap->persistent;
305 bitmap->persistent = false;
306 successor->autoload = bitmap->autoload;
307 bitmap->autoload = false;
308 bdrv_release_dirty_bitmap(bs, bitmap);
310 return successor;
314 * In cases of failure where we can no longer safely delete the parent,
315 * we may wish to re-join the parent and child/successor.
316 * The merged parent will be un-frozen, but not explicitly re-enabled.
317 * Called with BQL taken.
319 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
320 BdrvDirtyBitmap *parent,
321 Error **errp)
323 BdrvDirtyBitmap *successor = parent->successor;
325 if (!successor) {
326 error_setg(errp, "Cannot reclaim a successor when none is present");
327 return NULL;
330 if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
331 error_setg(errp, "Merging of parent and successor bitmap failed");
332 return NULL;
334 bdrv_release_dirty_bitmap(bs, successor);
335 parent->successor = NULL;
337 return parent;
341 * Truncates _all_ bitmaps attached to a BDS.
342 * Called with BQL taken.
344 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
346 BdrvDirtyBitmap *bitmap;
347 uint64_t size = bdrv_nb_sectors(bs);
349 bdrv_dirty_bitmaps_lock(bs);
350 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
351 assert(!bdrv_dirty_bitmap_frozen(bitmap));
352 assert(!bitmap->active_iterators);
353 hbitmap_truncate(bitmap->bitmap, size);
354 bitmap->size = size;
356 bdrv_dirty_bitmaps_unlock(bs);
359 static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
361 return !!bdrv_dirty_bitmap_name(bitmap);
364 /* Called with BQL taken. */
365 static void bdrv_do_release_matching_dirty_bitmap(
366 BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
367 bool (*cond)(BdrvDirtyBitmap *bitmap))
369 BdrvDirtyBitmap *bm, *next;
370 bdrv_dirty_bitmaps_lock(bs);
371 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
372 if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
373 assert(!bm->active_iterators);
374 assert(!bdrv_dirty_bitmap_frozen(bm));
375 assert(!bm->meta);
376 QLIST_REMOVE(bm, list);
377 hbitmap_free(bm->bitmap);
378 g_free(bm->name);
379 g_free(bm);
381 if (bitmap) {
382 goto out;
386 if (bitmap) {
387 abort();
390 out:
391 bdrv_dirty_bitmaps_unlock(bs);
394 /* Called with BQL taken. */
395 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
397 bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
401 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
402 * There must not be any frozen bitmaps attached.
403 * This function does not remove persistent bitmaps from the storage.
404 * Called with BQL taken.
406 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
408 bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
412 * Release all persistent dirty bitmaps attached to a BDS (for use in
413 * bdrv_inactivate_recurse()).
414 * There must not be any frozen bitmaps attached.
415 * This function does not remove persistent bitmaps from the storage.
417 void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
419 bdrv_do_release_matching_dirty_bitmap(bs, NULL,
420 bdrv_dirty_bitmap_get_persistance);
424 * Remove persistent dirty bitmap from the storage if it exists.
425 * Absence of bitmap is not an error, because we have the following scenario:
426 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
427 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
428 * not fail.
429 * This function doesn't release corresponding BdrvDirtyBitmap.
431 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
432 const char *name,
433 Error **errp)
435 if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
436 bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
440 /* Called with BQL taken. */
441 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
443 assert(!bdrv_dirty_bitmap_frozen(bitmap));
444 bitmap->disabled = true;
447 /* Called with BQL taken. */
448 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
450 assert(!bdrv_dirty_bitmap_frozen(bitmap));
451 bitmap->disabled = false;
454 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
456 BdrvDirtyBitmap *bm;
457 BlockDirtyInfoList *list = NULL;
458 BlockDirtyInfoList **plist = &list;
460 bdrv_dirty_bitmaps_lock(bs);
461 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
462 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
463 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
464 info->count = bdrv_get_dirty_count(bm);
465 info->granularity = bdrv_dirty_bitmap_granularity(bm);
466 info->has_name = !!bm->name;
467 info->name = g_strdup(bm->name);
468 info->status = bdrv_dirty_bitmap_status(bm);
469 entry->value = info;
470 *plist = entry;
471 plist = &entry->next;
473 bdrv_dirty_bitmaps_unlock(bs);
475 return list;
478 /* Called within bdrv_dirty_bitmap_lock..unlock */
479 int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
480 int64_t sector)
482 if (bitmap) {
483 return hbitmap_get(bitmap->bitmap, sector);
484 } else {
485 return 0;
490 * Chooses a default granularity based on the existing cluster size,
491 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
492 * is no cluster size information available.
494 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
496 BlockDriverInfo bdi;
497 uint32_t granularity;
499 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
500 granularity = MAX(4096, bdi.cluster_size);
501 granularity = MIN(65536, granularity);
502 } else {
503 granularity = 65536;
506 return granularity;
509 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
511 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
514 uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
516 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
519 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
520 uint64_t first_sector)
522 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
523 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, first_sector);
524 iter->bitmap = bitmap;
525 bitmap->active_iterators++;
526 return iter;
529 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
531 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
532 hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
533 iter->bitmap = bitmap;
534 bitmap->active_iterators++;
535 return iter;
538 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
540 if (!iter) {
541 return;
543 assert(iter->bitmap->active_iterators > 0);
544 iter->bitmap->active_iterators--;
545 g_free(iter);
548 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
550 return hbitmap_iter_next(&iter->hbi);
553 /* Called within bdrv_dirty_bitmap_lock..unlock */
554 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
555 int64_t cur_sector, int64_t nr_sectors)
557 assert(bdrv_dirty_bitmap_enabled(bitmap));
558 assert(!bdrv_dirty_bitmap_readonly(bitmap));
559 hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
562 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
563 int64_t cur_sector, int64_t nr_sectors)
565 bdrv_dirty_bitmap_lock(bitmap);
566 bdrv_set_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
567 bdrv_dirty_bitmap_unlock(bitmap);
570 /* Called within bdrv_dirty_bitmap_lock..unlock */
571 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
572 int64_t cur_sector, int64_t nr_sectors)
574 assert(bdrv_dirty_bitmap_enabled(bitmap));
575 assert(!bdrv_dirty_bitmap_readonly(bitmap));
576 hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
579 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
580 int64_t cur_sector, int64_t nr_sectors)
582 bdrv_dirty_bitmap_lock(bitmap);
583 bdrv_reset_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
584 bdrv_dirty_bitmap_unlock(bitmap);
587 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
589 assert(bdrv_dirty_bitmap_enabled(bitmap));
590 assert(!bdrv_dirty_bitmap_readonly(bitmap));
591 bdrv_dirty_bitmap_lock(bitmap);
592 if (!out) {
593 hbitmap_reset_all(bitmap->bitmap);
594 } else {
595 HBitmap *backup = bitmap->bitmap;
596 bitmap->bitmap = hbitmap_alloc(bitmap->size,
597 hbitmap_granularity(backup));
598 *out = backup;
600 bdrv_dirty_bitmap_unlock(bitmap);
603 void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
605 HBitmap *tmp = bitmap->bitmap;
606 assert(bdrv_dirty_bitmap_enabled(bitmap));
607 assert(!bdrv_dirty_bitmap_readonly(bitmap));
608 bitmap->bitmap = in;
609 hbitmap_free(tmp);
612 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
613 uint64_t start, uint64_t count)
615 return hbitmap_serialization_size(bitmap->bitmap, start, count);
618 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
620 return hbitmap_serialization_granularity(bitmap->bitmap);
623 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
624 uint8_t *buf, uint64_t start,
625 uint64_t count)
627 hbitmap_serialize_part(bitmap->bitmap, buf, start, count);
630 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
631 uint8_t *buf, uint64_t start,
632 uint64_t count, bool finish)
634 hbitmap_deserialize_part(bitmap->bitmap, buf, start, count, finish);
637 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
638 uint64_t start, uint64_t count,
639 bool finish)
641 hbitmap_deserialize_zeroes(bitmap->bitmap, start, count, finish);
644 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
645 uint64_t start, uint64_t count,
646 bool finish)
648 hbitmap_deserialize_ones(bitmap->bitmap, start, count, finish);
651 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
653 hbitmap_deserialize_finish(bitmap->bitmap);
656 void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
657 int64_t nr_sectors)
659 BdrvDirtyBitmap *bitmap;
661 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
662 return;
665 bdrv_dirty_bitmaps_lock(bs);
666 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
667 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
668 continue;
670 assert(!bdrv_dirty_bitmap_readonly(bitmap));
671 hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
673 bdrv_dirty_bitmaps_unlock(bs);
677 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
679 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
681 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
684 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
686 return hbitmap_count(bitmap->bitmap);
689 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
691 return hbitmap_count(bitmap->meta);
694 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
696 return bitmap->readonly;
699 /* Called with BQL taken. */
700 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
702 qemu_mutex_lock(bitmap->mutex);
703 bitmap->readonly = value;
704 qemu_mutex_unlock(bitmap->mutex);
707 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
709 BdrvDirtyBitmap *bm;
710 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
711 if (bm->readonly) {
712 return true;
716 return false;
719 /* Called with BQL taken. */
720 void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload)
722 qemu_mutex_lock(bitmap->mutex);
723 bitmap->autoload = autoload;
724 qemu_mutex_unlock(bitmap->mutex);
727 bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
729 return bitmap->autoload;
732 /* Called with BQL taken. */
733 void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
735 qemu_mutex_lock(bitmap->mutex);
736 bitmap->persistent = persistent;
737 qemu_mutex_unlock(bitmap->mutex);
740 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
742 return bitmap->persistent;
745 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
747 BdrvDirtyBitmap *bm;
748 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
749 if (bm->persistent && !bm->readonly) {
750 return true;
754 return false;
757 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
758 BdrvDirtyBitmap *bitmap)
760 return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
761 QLIST_NEXT(bitmap, list);
764 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
766 return hbitmap_sha256(bitmap->bitmap, errp);