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