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