1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25#include "qapi/error.h"
26#include "trace.h"
27#include "block/block_int.h"
28#include "block/blockjob.h"
29
30struct BdrvDirtyBitmap {
31 QemuMutex *mutex;
32 HBitmap *bitmap;
33 HBitmap *meta;
34 bool busy;
35 BdrvDirtyBitmap *successor;
36 char *name;
37 int64_t size;
38 bool disabled;
39
40 int active_iterators;
41 bool readonly;
42
43
44
45
46
47 bool persistent;
48 bool inconsistent;
49
50
51 bool migration;
52
53
54
55 QLIST_ENTRY(BdrvDirtyBitmap) list;
56};
57
58struct BdrvDirtyBitmapIter {
59 HBitmapIter hbi;
60 BdrvDirtyBitmap *bitmap;
61};
62
63static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
64{
65 qemu_mutex_lock(&bs->dirty_bitmap_mutex);
66}
67
68static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
69{
70 qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
71}
72
73void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
74{
75 qemu_mutex_lock(bitmap->mutex);
76}
77
78void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
79{
80 qemu_mutex_unlock(bitmap->mutex);
81}
82
83
84BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
85{
86 BdrvDirtyBitmap *bm;
87
88 assert(name);
89 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
90 if (bm->name && !strcmp(name, bm->name)) {
91 return bm;
92 }
93 }
94 return NULL;
95}
96
97
98BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
99 uint32_t granularity,
100 const char *name,
101 Error **errp)
102{
103 int64_t bitmap_size;
104 BdrvDirtyBitmap *bitmap;
105
106 assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
107
108 if (name && bdrv_find_dirty_bitmap(bs, name)) {
109 error_setg(errp, "Bitmap already exists: %s", name);
110 return NULL;
111 }
112 bitmap_size = bdrv_getlength(bs);
113 if (bitmap_size < 0) {
114 error_setg_errno(errp, -bitmap_size, "could not get length of device");
115 errno = -bitmap_size;
116 return NULL;
117 }
118 bitmap = g_new0(BdrvDirtyBitmap, 1);
119 bitmap->mutex = &bs->dirty_bitmap_mutex;
120 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
121 bitmap->size = bitmap_size;
122 bitmap->name = g_strdup(name);
123 bitmap->disabled = false;
124 bdrv_dirty_bitmaps_lock(bs);
125 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
126 bdrv_dirty_bitmaps_unlock(bs);
127 return bitmap;
128}
129
130
131
132
133
134
135
136
137
138
139
140
141void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
142 int chunk_size)
143{
144 assert(!bitmap->meta);
145 qemu_mutex_lock(bitmap->mutex);
146 bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
147 chunk_size * BITS_PER_BYTE);
148 qemu_mutex_unlock(bitmap->mutex);
149}
150
151void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
152{
153 assert(bitmap->meta);
154 qemu_mutex_lock(bitmap->mutex);
155 hbitmap_free_meta(bitmap->bitmap);
156 bitmap->meta = NULL;
157 qemu_mutex_unlock(bitmap->mutex);
158}
159
160int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
161{
162 return bitmap->size;
163}
164
165const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
166{
167 return bitmap->name;
168}
169
170
171bool bdrv_dirty_bitmap_has_successor(BdrvDirtyBitmap *bitmap)
172{
173 return bitmap->successor;
174}
175
176static bool bdrv_dirty_bitmap_busy(const BdrvDirtyBitmap *bitmap)
177{
178 return bitmap->busy;
179}
180
181void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy)
182{
183 qemu_mutex_lock(bitmap->mutex);
184 bitmap->busy = busy;
185 qemu_mutex_unlock(bitmap->mutex);
186}
187
188
189bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
190{
191 return !bitmap->disabled;
192}
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
217{
218 if (bdrv_dirty_bitmap_inconsistent(bitmap)) {
219 return DIRTY_BITMAP_STATUS_INCONSISTENT;
220 } else if (bdrv_dirty_bitmap_has_successor(bitmap)) {
221 return DIRTY_BITMAP_STATUS_FROZEN;
222 } else if (bdrv_dirty_bitmap_busy(bitmap)) {
223 return DIRTY_BITMAP_STATUS_LOCKED;
224 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
225 return DIRTY_BITMAP_STATUS_DISABLED;
226 } else {
227 return DIRTY_BITMAP_STATUS_ACTIVE;
228 }
229}
230
231
232static bool bdrv_dirty_bitmap_recording(BdrvDirtyBitmap *bitmap)
233{
234 return !bitmap->disabled || (bitmap->successor &&
235 !bitmap->successor->disabled);
236}
237
238int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags,
239 Error **errp)
240{
241 if ((flags & BDRV_BITMAP_BUSY) && bdrv_dirty_bitmap_busy(bitmap)) {
242 error_setg(errp, "Bitmap '%s' is currently in use by another"
243 " operation and cannot be used", bitmap->name);
244 return -1;
245 }
246
247 if ((flags & BDRV_BITMAP_RO) && bdrv_dirty_bitmap_readonly(bitmap)) {
248 error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
249 bitmap->name);
250 return -1;
251 }
252
253 if ((flags & BDRV_BITMAP_INCONSISTENT) &&
254 bdrv_dirty_bitmap_inconsistent(bitmap)) {
255 error_setg(errp, "Bitmap '%s' is inconsistent and cannot be used",
256 bitmap->name);
257 error_append_hint(errp, "Try block-dirty-bitmap-remove to delete"
258 " this bitmap from disk");
259 return -1;
260 }
261
262 return 0;
263}
264
265
266
267
268
269
270
271int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
272 BdrvDirtyBitmap *bitmap, Error **errp)
273{
274 uint64_t granularity;
275 BdrvDirtyBitmap *child;
276
277 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY, errp)) {
278 return -1;
279 }
280 if (bdrv_dirty_bitmap_has_successor(bitmap)) {
281 error_setg(errp, "Cannot create a successor for a bitmap that already "
282 "has one");
283 return -1;
284 }
285
286
287 granularity = bdrv_dirty_bitmap_granularity(bitmap);
288 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
289 if (!child) {
290 return -1;
291 }
292
293
294 child->disabled = bitmap->disabled;
295 bitmap->disabled = true;
296
297
298 bitmap->successor = child;
299 bitmap->busy = true;
300 return 0;
301}
302
303void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
304{
305 bitmap->disabled = false;
306}
307
308
309void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
310{
311 assert(bitmap->mutex == bitmap->successor->mutex);
312 qemu_mutex_lock(bitmap->mutex);
313 bdrv_enable_dirty_bitmap_locked(bitmap->successor);
314 qemu_mutex_unlock(bitmap->mutex);
315}
316
317
318static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
319{
320 assert(!bitmap->active_iterators);
321 assert(!bdrv_dirty_bitmap_busy(bitmap));
322 assert(!bdrv_dirty_bitmap_has_successor(bitmap));
323 assert(!bitmap->meta);
324 QLIST_REMOVE(bitmap, list);
325 hbitmap_free(bitmap->bitmap);
326 g_free(bitmap->name);
327 g_free(bitmap);
328}
329
330
331
332
333
334
335BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
336 BdrvDirtyBitmap *bitmap,
337 Error **errp)
338{
339 char *name;
340 BdrvDirtyBitmap *successor = bitmap->successor;
341
342 if (successor == NULL) {
343 error_setg(errp, "Cannot relinquish control if "
344 "there's no successor present");
345 return NULL;
346 }
347
348 name = bitmap->name;
349 bitmap->name = NULL;
350 successor->name = name;
351 bitmap->successor = NULL;
352 successor->persistent = bitmap->persistent;
353 bitmap->persistent = false;
354 bitmap->busy = false;
355 bdrv_release_dirty_bitmap(bs, bitmap);
356
357 return successor;
358}
359
360
361
362
363
364
365
366
367BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
368 BdrvDirtyBitmap *parent,
369 Error **errp)
370{
371 BdrvDirtyBitmap *successor = parent->successor;
372
373 if (!successor) {
374 error_setg(errp, "Cannot reclaim a successor when none is present");
375 return NULL;
376 }
377
378 if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
379 error_setg(errp, "Merging of parent and successor bitmap failed");
380 return NULL;
381 }
382
383 parent->disabled = successor->disabled;
384 parent->busy = false;
385 bdrv_release_dirty_bitmap_locked(successor);
386 parent->successor = NULL;
387
388 return parent;
389}
390
391
392BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
393 BdrvDirtyBitmap *parent,
394 Error **errp)
395{
396 BdrvDirtyBitmap *ret;
397
398 qemu_mutex_lock(parent->mutex);
399 ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp);
400 qemu_mutex_unlock(parent->mutex);
401
402 return ret;
403}
404
405
406
407
408
409void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
410{
411 BdrvDirtyBitmap *bitmap;
412
413 bdrv_dirty_bitmaps_lock(bs);
414 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
415 assert(!bdrv_dirty_bitmap_busy(bitmap));
416 assert(!bdrv_dirty_bitmap_has_successor(bitmap));
417 assert(!bitmap->active_iterators);
418 hbitmap_truncate(bitmap->bitmap, bytes);
419 bitmap->size = bytes;
420 }
421 bdrv_dirty_bitmaps_unlock(bs);
422}
423
424
425void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
426{
427 bdrv_dirty_bitmaps_lock(bs);
428 bdrv_release_dirty_bitmap_locked(bitmap);
429 bdrv_dirty_bitmaps_unlock(bs);
430}
431
432
433
434
435
436
437
438void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
439{
440 BdrvDirtyBitmap *bm, *next;
441
442 bdrv_dirty_bitmaps_lock(bs);
443 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
444 if (bdrv_dirty_bitmap_name(bm)) {
445 bdrv_release_dirty_bitmap_locked(bm);
446 }
447 }
448 bdrv_dirty_bitmaps_unlock(bs);
449}
450
451
452
453
454
455
456
457
458
459void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
460 const char *name,
461 Error **errp)
462{
463 if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
464 bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
465 }
466}
467
468void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
469{
470 bdrv_dirty_bitmap_lock(bitmap);
471 bitmap->disabled = true;
472 bdrv_dirty_bitmap_unlock(bitmap);
473}
474
475void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
476{
477 bdrv_dirty_bitmap_lock(bitmap);
478 bdrv_enable_dirty_bitmap_locked(bitmap);
479 bdrv_dirty_bitmap_unlock(bitmap);
480}
481
482BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
483{
484 BdrvDirtyBitmap *bm;
485 BlockDirtyInfoList *list = NULL;
486 BlockDirtyInfoList **plist = &list;
487
488 bdrv_dirty_bitmaps_lock(bs);
489 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
490 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
491 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
492 info->count = bdrv_get_dirty_count(bm);
493 info->granularity = bdrv_dirty_bitmap_granularity(bm);
494 info->has_name = !!bm->name;
495 info->name = g_strdup(bm->name);
496 info->status = bdrv_dirty_bitmap_status(bm);
497 info->recording = bdrv_dirty_bitmap_recording(bm);
498 info->busy = bdrv_dirty_bitmap_busy(bm);
499 info->persistent = bm->persistent;
500 info->has_inconsistent = bm->inconsistent;
501 info->inconsistent = bm->inconsistent;
502 entry->value = info;
503 *plist = entry;
504 plist = &entry->next;
505 }
506 bdrv_dirty_bitmaps_unlock(bs);
507
508 return list;
509}
510
511
512bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
513 int64_t offset)
514{
515 if (bitmap) {
516 return hbitmap_get(bitmap->bitmap, offset);
517 } else {
518 return false;
519 }
520}
521
522
523
524
525
526
527uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
528{
529 BlockDriverInfo bdi;
530 uint32_t granularity;
531
532 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
533 granularity = MAX(4096, bdi.cluster_size);
534 granularity = MIN(65536, granularity);
535 } else {
536 granularity = 65536;
537 }
538
539 return granularity;
540}
541
542uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
543{
544 return 1U << hbitmap_granularity(bitmap->bitmap);
545}
546
547BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
548{
549 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
550 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
551 iter->bitmap = bitmap;
552 bitmap->active_iterators++;
553 return iter;
554}
555
556BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
557{
558 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
559 hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
560 iter->bitmap = bitmap;
561 bitmap->active_iterators++;
562 return iter;
563}
564
565void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
566{
567 if (!iter) {
568 return;
569 }
570 assert(iter->bitmap->active_iterators > 0);
571 iter->bitmap->active_iterators--;
572 g_free(iter);
573}
574
575int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
576{
577 return hbitmap_iter_next(&iter->hbi);
578}
579
580
581void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
582 int64_t offset, int64_t bytes)
583{
584 assert(!bdrv_dirty_bitmap_readonly(bitmap));
585 hbitmap_set(bitmap->bitmap, offset, bytes);
586}
587
588void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
589 int64_t offset, int64_t bytes)
590{
591 bdrv_dirty_bitmap_lock(bitmap);
592 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
593 bdrv_dirty_bitmap_unlock(bitmap);
594}
595
596
597void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
598 int64_t offset, int64_t bytes)
599{
600 assert(!bdrv_dirty_bitmap_readonly(bitmap));
601 hbitmap_reset(bitmap->bitmap, offset, bytes);
602}
603
604void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
605 int64_t offset, int64_t bytes)
606{
607 bdrv_dirty_bitmap_lock(bitmap);
608 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
609 bdrv_dirty_bitmap_unlock(bitmap);
610}
611
612void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
613{
614 assert(!bdrv_dirty_bitmap_readonly(bitmap));
615 bdrv_dirty_bitmap_lock(bitmap);
616 if (!out) {
617 hbitmap_reset_all(bitmap->bitmap);
618 } else {
619 HBitmap *backup = bitmap->bitmap;
620 bitmap->bitmap = hbitmap_alloc(bitmap->size,
621 hbitmap_granularity(backup));
622 *out = backup;
623 }
624 bdrv_dirty_bitmap_unlock(bitmap);
625}
626
627void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
628{
629 HBitmap *tmp = bitmap->bitmap;
630 assert(!bdrv_dirty_bitmap_readonly(bitmap));
631 bitmap->bitmap = backup;
632 hbitmap_free(tmp);
633}
634
635uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
636 uint64_t offset, uint64_t bytes)
637{
638 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
639}
640
641uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
642{
643 return hbitmap_serialization_align(bitmap->bitmap);
644}
645
646void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
647 uint8_t *buf, uint64_t offset,
648 uint64_t bytes)
649{
650 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
651}
652
653void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
654 uint8_t *buf, uint64_t offset,
655 uint64_t bytes, bool finish)
656{
657 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
658}
659
660void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
661 uint64_t offset, uint64_t bytes,
662 bool finish)
663{
664 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
665}
666
667void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
668 uint64_t offset, uint64_t bytes,
669 bool finish)
670{
671 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
672}
673
674void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
675{
676 hbitmap_deserialize_finish(bitmap->bitmap);
677}
678
679void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
680{
681 BdrvDirtyBitmap *bitmap;
682
683 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
684 return;
685 }
686
687 bdrv_dirty_bitmaps_lock(bs);
688 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
689 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
690 continue;
691 }
692 assert(!bdrv_dirty_bitmap_readonly(bitmap));
693 hbitmap_set(bitmap->bitmap, offset, bytes);
694 }
695 bdrv_dirty_bitmaps_unlock(bs);
696}
697
698
699
700
701void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
702{
703 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
704}
705
706int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
707{
708 return hbitmap_count(bitmap->bitmap);
709}
710
711int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
712{
713 return hbitmap_count(bitmap->meta);
714}
715
716bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
717{
718 return bitmap->readonly;
719}
720
721
722void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
723{
724 qemu_mutex_lock(bitmap->mutex);
725 bitmap->readonly = value;
726 qemu_mutex_unlock(bitmap->mutex);
727}
728
729bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
730{
731 BdrvDirtyBitmap *bm;
732 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
733 if (bm->readonly) {
734 return true;
735 }
736 }
737
738 return false;
739}
740
741
742void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent)
743{
744 qemu_mutex_lock(bitmap->mutex);
745 bitmap->persistent = persistent;
746 qemu_mutex_unlock(bitmap->mutex);
747}
748
749
750void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
751{
752 qemu_mutex_lock(bitmap->mutex);
753 assert(bitmap->persistent == true);
754 bitmap->inconsistent = true;
755 bitmap->disabled = true;
756 qemu_mutex_unlock(bitmap->mutex);
757}
758
759
760void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration)
761{
762 qemu_mutex_lock(bitmap->mutex);
763 bitmap->migration = migration;
764 qemu_mutex_unlock(bitmap->mutex);
765}
766
767bool bdrv_dirty_bitmap_get_persistence(BdrvDirtyBitmap *bitmap)
768{
769 return bitmap->persistent && !bitmap->migration;
770}
771
772bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
773{
774 return bitmap->inconsistent;
775}
776
777bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
778{
779 BdrvDirtyBitmap *bm;
780 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
781 if (bm->persistent && !bm->readonly && !bm->migration) {
782 return true;
783 }
784 }
785
786 return false;
787}
788
789BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
790 BdrvDirtyBitmap *bitmap)
791{
792 return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
793 QLIST_NEXT(bitmap, list);
794}
795
796char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
797{
798 return hbitmap_sha256(bitmap->bitmap, errp);
799}
800
801int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
802 uint64_t bytes)
803{
804 return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
805}
806
807bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
808 uint64_t *offset, uint64_t *bytes)
809{
810 return hbitmap_next_dirty_area(bitmap->bitmap, offset, bytes);
811}
812
813void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
814 HBitmap **backup, Error **errp)
815{
816 bool ret;
817
818 qemu_mutex_lock(dest->mutex);
819 if (src->mutex != dest->mutex) {
820 qemu_mutex_lock(src->mutex);
821 }
822
823 if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) {
824 goto out;
825 }
826
827 if (bdrv_dirty_bitmap_check(src, BDRV_BITMAP_ALLOW_RO, errp)) {
828 goto out;
829 }
830
831 if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
832 error_setg(errp, "Bitmaps are incompatible and can't be merged");
833 goto out;
834 }
835
836 if (backup) {
837 *backup = dest->bitmap;
838 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
839 ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
840 } else {
841 ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
842 }
843 assert(ret);
844
845out:
846 qemu_mutex_unlock(dest->mutex);
847 if (src->mutex != dest->mutex) {
848 qemu_mutex_unlock(src->mutex);
849 }
850}
851