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
24 #include "qemu/osdep.h"
25 #include "qapi/error.h"
26 #include "qemu-common.h"
28 #include "block/block_int.h"
29 #include "block/blockjob.h"
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
{
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
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
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
{
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
)
92 QLIST_FOREACH(bm
, &bs
->dirty_bitmaps
, list
) {
93 if (bm
->name
&& !strcmp(name
, bm
->name
)) {
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
);
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
,
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
);
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
;
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
);
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
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
157 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap
*bitmap
,
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
);
173 qemu_mutex_unlock(bitmap
->mutex
);
176 int bdrv_dirty_bitmap_get_meta_locked(BlockDriverState
*bs
,
177 BdrvDirtyBitmap
*bitmap
, int64_t sector
,
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
)) {
193 int bdrv_dirty_bitmap_get_meta(BlockDriverState
*bs
,
194 BdrvDirtyBitmap
*bitmap
, int64_t sector
,
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
);
206 void bdrv_dirty_bitmap_reset_meta(BlockDriverState
*bs
,
207 BdrvDirtyBitmap
*bitmap
, int64_t sector
,
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
)
220 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap
*bitmap
)
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
;
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 "
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
);
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
;
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
,
292 BdrvDirtyBitmap
*successor
= bitmap
->successor
;
294 if (successor
== NULL
) {
295 error_setg(errp
, "Cannot relinquish control if "
296 "there's no successor present");
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
);
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
,
323 BdrvDirtyBitmap
*successor
= parent
->successor
;
326 error_setg(errp
, "Cannot reclaim a successor when none is present");
330 if (!hbitmap_merge(parent
->bitmap
, successor
->bitmap
)) {
331 error_setg(errp
, "Merging of parent and successor bitmap failed");
334 bdrv_release_dirty_bitmap(bs
, successor
);
335 parent
->successor
= NULL
;
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
);
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
));
376 QLIST_REMOVE(bm
, list
);
377 hbitmap_free(bm
->bitmap
);
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
429 * This function doesn't release corresponding BdrvDirtyBitmap.
431 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState
*bs
,
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
)
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
);
471 plist
= &entry
->next
;
473 bdrv_dirty_bitmaps_unlock(bs
);
478 /* Called within bdrv_dirty_bitmap_lock..unlock */
479 int bdrv_get_dirty_locked(BlockDriverState
*bs
, BdrvDirtyBitmap
*bitmap
,
483 return hbitmap_get(bitmap
->bitmap
, sector
);
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
)
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
);
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
++;
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
++;
538 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter
*iter
)
543 assert(iter
->bitmap
->active_iterators
> 0);
544 iter
->bitmap
->active_iterators
--;
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
);
593 hbitmap_reset_all(bitmap
->bitmap
);
595 HBitmap
*backup
= bitmap
->bitmap
;
596 bitmap
->bitmap
= hbitmap_alloc(bitmap
->size
,
597 hbitmap_granularity(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
));
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
,
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
,
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
,
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
,
659 BdrvDirtyBitmap
*bitmap
;
661 if (QLIST_EMPTY(&bs
->dirty_bitmaps
)) {
665 bdrv_dirty_bitmaps_lock(bs
);
666 QLIST_FOREACH(bitmap
, &bs
->dirty_bitmaps
, list
) {
667 if (!bdrv_dirty_bitmap_enabled(bitmap
)) {
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
)
710 QLIST_FOREACH(bm
, &bs
->dirty_bitmaps
, list
) {
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
)
748 QLIST_FOREACH(bm
, &bs
->dirty_bitmaps
, list
) {
749 if (bm
->persistent
&& !bm
->readonly
) {
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
);