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