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