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