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