xref: /openbmc/qemu/block/dirty-bitmap.c (revision d1fd31f8)
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     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 
61 struct BdrvDirtyBitmapIter {
62     HBitmapIter hbi;
63     BdrvDirtyBitmap *bitmap;
64 };
65 
66 static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
67 {
68     qemu_mutex_lock(&bs->dirty_bitmap_mutex);
69 }
70 
71 static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
72 {
73     qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
74 }
75 
76 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
77 {
78     qemu_mutex_lock(bitmap->mutex);
79 }
80 
81 void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
82 {
83     qemu_mutex_unlock(bitmap->mutex);
84 }
85 
86 /* Called with BQL or dirty_bitmap lock taken.  */
87 BdrvDirtyBitmap *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.  */
101 void 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.  */
110 BdrvDirtyBitmap *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  */
153 void 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 
163 void 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 
172 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
173 {
174     return bitmap->size;
175 }
176 
177 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
178 {
179     return bitmap->name;
180 }
181 
182 /* Called with BQL taken.  */
183 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
184 {
185     return bitmap->successor;
186 }
187 
188 void 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 
195 bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap)
196 {
197     return bitmap->qmp_locked;
198 }
199 
200 /* Called with BQL taken.  */
201 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
202 {
203     return !(bitmap->disabled || bitmap->successor);
204 }
205 
206 /* Called with BQL taken.  */
207 DirtyBitmapStatus 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  */
225 int 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. */
254 void 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 */
262 static 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.  */
290 static 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 */
300 static 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  */
311 BdrvDirtyBitmap *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  */
341 BdrvDirtyBitmap *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. */
363 BdrvDirtyBitmap *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  */
380 void 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 
394 static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
395 {
396     return !!bdrv_dirty_bitmap_name(bitmap);
397 }
398 
399 /* Called with BQL taken.  */
400 void 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  */
411 void 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  */
422 void 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  */
436 void 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.  */
446 void 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.  */
453 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
454 {
455     assert(!bdrv_dirty_bitmap_frozen(bitmap));
456     bitmap->disabled = false;
457 }
458 
459 BlockDirtyInfoList *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 */
484 bool 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  */
499 uint32_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 
514 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
515 {
516     return 1U << hbitmap_granularity(bitmap->bitmap);
517 }
518 
519 BdrvDirtyBitmapIter *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 
528 BdrvDirtyBitmapIter *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 
537 void 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 
547 int64_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 */
553 void 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 
561 void 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 */
570 void 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 
578 void 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 
586 void 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 
602 void 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 
611 uint64_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 
617 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
618 {
619     return hbitmap_serialization_align(bitmap->bitmap);
620 }
621 
622 void 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 
629 void 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 
636 void 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 
643 void 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 
650 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
651 {
652     hbitmap_deserialize_finish(bitmap->bitmap);
653 }
654 
655 void 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  */
677 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
678 {
679     hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
680 }
681 
682 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
683 {
684     return hbitmap_count(bitmap->bitmap);
685 }
686 
687 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
688 {
689     return hbitmap_count(bitmap->meta);
690 }
691 
692 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
693 {
694     return bitmap->readonly;
695 }
696 
697 /* Called with BQL taken. */
698 void 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 
705 bool 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. */
718 void 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 
725 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
726 {
727     return bitmap->persistent;
728 }
729 
730 bool 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 
742 BdrvDirtyBitmap *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 
749 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
750 {
751     return hbitmap_sha256(bitmap->bitmap, errp);
752 }
753 
754 int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
755 {
756     return hbitmap_next_zero(bitmap->bitmap, offset);
757 }
758