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 hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap);
313
314 parent->disabled = successor->disabled;
315 parent->busy = false;
316 bdrv_release_dirty_bitmap_locked(successor);
317 parent->successor = NULL;
318
319 return parent;
320}
321
322
323BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BdrvDirtyBitmap *parent,
324 Error **errp)
325{
326 BdrvDirtyBitmap *ret;
327
328 bdrv_dirty_bitmaps_lock(parent->bs);
329 ret = bdrv_reclaim_dirty_bitmap_locked(parent, errp);
330 bdrv_dirty_bitmaps_unlock(parent->bs);
331
332 return ret;
333}
334
335
336
337
338
339void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
340{
341 BdrvDirtyBitmap *bitmap;
342
343 bdrv_dirty_bitmaps_lock(bs);
344 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
345 assert(!bdrv_dirty_bitmap_busy(bitmap));
346 assert(!bdrv_dirty_bitmap_has_successor(bitmap));
347 assert(!bitmap->active_iterators);
348 hbitmap_truncate(bitmap->bitmap, bytes);
349 bitmap->size = bytes;
350 }
351 bdrv_dirty_bitmaps_unlock(bs);
352}
353
354
355void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap)
356{
357 BlockDriverState *bs = bitmap->bs;
358
359 bdrv_dirty_bitmaps_lock(bs);
360 bdrv_release_dirty_bitmap_locked(bitmap);
361 bdrv_dirty_bitmaps_unlock(bs);
362}
363
364
365
366
367
368
369
370void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
371{
372 BdrvDirtyBitmap *bm, *next;
373
374 bdrv_dirty_bitmaps_lock(bs);
375 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
376 if (bdrv_dirty_bitmap_name(bm)) {
377 bdrv_release_dirty_bitmap_locked(bm);
378 }
379 }
380 bdrv_dirty_bitmaps_unlock(bs);
381}
382
383
384
385
386
387
388
389
390
391static int coroutine_fn
392bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
393 Error **errp)
394{
395 if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
396 return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
397 }
398
399 return 0;
400}
401
402typedef struct BdrvRemovePersistentDirtyBitmapCo {
403 BlockDriverState *bs;
404 const char *name;
405 Error **errp;
406 int ret;
407} BdrvRemovePersistentDirtyBitmapCo;
408
409static void coroutine_fn
410bdrv_co_remove_persistent_dirty_bitmap_entry(void *opaque)
411{
412 BdrvRemovePersistentDirtyBitmapCo *s = opaque;
413
414 s->ret = bdrv_co_remove_persistent_dirty_bitmap(s->bs, s->name, s->errp);
415 aio_wait_kick();
416}
417
418int bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
419 Error **errp)
420{
421 if (qemu_in_coroutine()) {
422 return bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
423 } else {
424 Coroutine *co;
425 BdrvRemovePersistentDirtyBitmapCo s = {
426 .bs = bs,
427 .name = name,
428 .errp = errp,
429 .ret = -EINPROGRESS,
430 };
431
432 co = qemu_coroutine_create(bdrv_co_remove_persistent_dirty_bitmap_entry,
433 &s);
434 bdrv_coroutine_enter(bs, co);
435 BDRV_POLL_WHILE(bs, s.ret == -EINPROGRESS);
436
437 return s.ret;
438 }
439}
440
441bool
442bdrv_supports_persistent_dirty_bitmap(BlockDriverState *bs)
443{
444 if (bs->drv && bs->drv->bdrv_supports_persistent_dirty_bitmap) {
445 return bs->drv->bdrv_supports_persistent_dirty_bitmap(bs);
446 }
447 return false;
448}
449
450static bool coroutine_fn
451bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
452 uint32_t granularity, Error **errp)
453{
454 BlockDriver *drv = bs->drv;
455
456 if (!drv) {
457 error_setg_errno(errp, ENOMEDIUM,
458 "Can't store persistent bitmaps to %s",
459 bdrv_get_device_or_node_name(bs));
460 return false;
461 }
462
463 if (!drv->bdrv_co_can_store_new_dirty_bitmap) {
464 error_setg_errno(errp, ENOTSUP,
465 "Can't store persistent bitmaps to %s",
466 bdrv_get_device_or_node_name(bs));
467 return false;
468 }
469
470 return drv->bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
471}
472
473typedef struct BdrvCanStoreNewDirtyBitmapCo {
474 BlockDriverState *bs;
475 const char *name;
476 uint32_t granularity;
477 Error **errp;
478 bool ret;
479
480 bool in_progress;
481} BdrvCanStoreNewDirtyBitmapCo;
482
483static void coroutine_fn bdrv_co_can_store_new_dirty_bitmap_entry(void *opaque)
484{
485 BdrvCanStoreNewDirtyBitmapCo *s = opaque;
486
487 s->ret = bdrv_co_can_store_new_dirty_bitmap(s->bs, s->name, s->granularity,
488 s->errp);
489 s->in_progress = false;
490 aio_wait_kick();
491}
492
493bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
494 uint32_t granularity, Error **errp)
495{
496 IO_CODE();
497 if (qemu_in_coroutine()) {
498 return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
499 } else {
500 Coroutine *co;
501 BdrvCanStoreNewDirtyBitmapCo s = {
502 .bs = bs,
503 .name = name,
504 .granularity = granularity,
505 .errp = errp,
506 .in_progress = true,
507 };
508
509 co = qemu_coroutine_create(bdrv_co_can_store_new_dirty_bitmap_entry,
510 &s);
511 bdrv_coroutine_enter(bs, co);
512 BDRV_POLL_WHILE(bs, s.in_progress);
513
514 return s.ret;
515 }
516}
517
518void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
519{
520 bdrv_dirty_bitmaps_lock(bitmap->bs);
521 bitmap->disabled = true;
522 bdrv_dirty_bitmaps_unlock(bitmap->bs);
523}
524
525void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
526{
527 bdrv_dirty_bitmaps_lock(bitmap->bs);
528 bdrv_enable_dirty_bitmap_locked(bitmap);
529 bdrv_dirty_bitmaps_unlock(bitmap->bs);
530}
531
532BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
533{
534 BdrvDirtyBitmap *bm;
535 BlockDirtyInfoList *list = NULL;
536 BlockDirtyInfoList **tail = &list;
537
538 bdrv_dirty_bitmaps_lock(bs);
539 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
540 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
541
542 info->count = bdrv_get_dirty_count(bm);
543 info->granularity = bdrv_dirty_bitmap_granularity(bm);
544 info->has_name = !!bm->name;
545 info->name = g_strdup(bm->name);
546 info->recording = bdrv_dirty_bitmap_recording(bm);
547 info->busy = bdrv_dirty_bitmap_busy(bm);
548 info->persistent = bm->persistent;
549 info->has_inconsistent = bm->inconsistent;
550 info->inconsistent = bm->inconsistent;
551 QAPI_LIST_APPEND(tail, info);
552 }
553 bdrv_dirty_bitmaps_unlock(bs);
554
555 return list;
556}
557
558
559bool bdrv_dirty_bitmap_get_locked(BdrvDirtyBitmap *bitmap, int64_t offset)
560{
561 return hbitmap_get(bitmap->bitmap, offset);
562}
563
564bool bdrv_dirty_bitmap_get(BdrvDirtyBitmap *bitmap, int64_t offset)
565{
566 bool ret;
567 bdrv_dirty_bitmaps_lock(bitmap->bs);
568 ret = bdrv_dirty_bitmap_get_locked(bitmap, offset);
569 bdrv_dirty_bitmaps_unlock(bitmap->bs);
570
571 return ret;
572}
573
574
575
576
577
578
579uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
580{
581 BlockDriverInfo bdi;
582 uint32_t granularity;
583
584 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
585 granularity = MAX(4096, bdi.cluster_size);
586 granularity = MIN(65536, granularity);
587 } else {
588 granularity = 65536;
589 }
590
591 return granularity;
592}
593
594uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
595{
596 return 1U << hbitmap_granularity(bitmap->bitmap);
597}
598
599BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
600{
601 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
602 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
603 iter->bitmap = bitmap;
604 bitmap->active_iterators++;
605 return iter;
606}
607
608void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
609{
610 if (!iter) {
611 return;
612 }
613 assert(iter->bitmap->active_iterators > 0);
614 iter->bitmap->active_iterators--;
615 g_free(iter);
616}
617
618int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
619{
620 return hbitmap_iter_next(&iter->hbi);
621}
622
623
624void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
625 int64_t offset, int64_t bytes)
626{
627 assert(!bdrv_dirty_bitmap_readonly(bitmap));
628 hbitmap_set(bitmap->bitmap, offset, bytes);
629}
630
631void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
632 int64_t offset, int64_t bytes)
633{
634 bdrv_dirty_bitmaps_lock(bitmap->bs);
635 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
636 bdrv_dirty_bitmaps_unlock(bitmap->bs);
637}
638
639
640void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
641 int64_t offset, int64_t bytes)
642{
643 assert(!bdrv_dirty_bitmap_readonly(bitmap));
644 hbitmap_reset(bitmap->bitmap, offset, bytes);
645}
646
647void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
648 int64_t offset, int64_t bytes)
649{
650 bdrv_dirty_bitmaps_lock(bitmap->bs);
651 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
652 bdrv_dirty_bitmaps_unlock(bitmap->bs);
653}
654
655void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
656{
657 IO_CODE();
658 assert(!bdrv_dirty_bitmap_readonly(bitmap));
659 bdrv_dirty_bitmaps_lock(bitmap->bs);
660 if (!out) {
661 hbitmap_reset_all(bitmap->bitmap);
662 } else {
663 HBitmap *backup = bitmap->bitmap;
664 bitmap->bitmap = hbitmap_alloc(bitmap->size,
665 hbitmap_granularity(backup));
666 *out = backup;
667 }
668 bdrv_dirty_bitmaps_unlock(bitmap->bs);
669}
670
671void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
672{
673 HBitmap *tmp = bitmap->bitmap;
674 assert(!bdrv_dirty_bitmap_readonly(bitmap));
675 GLOBAL_STATE_CODE();
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 IO_CODE();
741
742 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
743 return;
744 }
745
746 bdrv_dirty_bitmaps_lock(bs);
747 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
748 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
749 continue;
750 }
751 assert(!bdrv_dirty_bitmap_readonly(bitmap));
752 hbitmap_set(bitmap->bitmap, offset, bytes);
753 }
754 bdrv_dirty_bitmaps_unlock(bs);
755}
756
757
758
759
760void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
761{
762 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
763}
764
765int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
766{
767 return hbitmap_count(bitmap->bitmap);
768}
769
770bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
771{
772 return bitmap->readonly;
773}
774
775
776void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
777{
778 bdrv_dirty_bitmaps_lock(bitmap->bs);
779 bitmap->readonly = value;
780 bdrv_dirty_bitmaps_unlock(bitmap->bs);
781}
782
783bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
784{
785 BdrvDirtyBitmap *bm;
786 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
787 if (bm->readonly) {
788 return true;
789 }
790 }
791
792 return false;
793}
794
795bool bdrv_has_named_bitmaps(BlockDriverState *bs)
796{
797 BdrvDirtyBitmap *bm;
798
799 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
800 if (bdrv_dirty_bitmap_name(bm)) {
801 return true;
802 }
803 }
804
805 return false;
806}
807
808
809void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent)
810{
811 bdrv_dirty_bitmaps_lock(bitmap->bs);
812 bitmap->persistent = persistent;
813 bdrv_dirty_bitmaps_unlock(bitmap->bs);
814}
815
816
817void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
818{
819 bdrv_dirty_bitmaps_lock(bitmap->bs);
820 assert(bitmap->persistent == true);
821 bitmap->inconsistent = true;
822 bitmap->disabled = true;
823 bdrv_dirty_bitmaps_unlock(bitmap->bs);
824}
825
826
827void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip)
828{
829 bdrv_dirty_bitmaps_lock(bitmap->bs);
830 bitmap->skip_store = skip;
831 bdrv_dirty_bitmaps_unlock(bitmap->bs);
832}
833
834bool bdrv_dirty_bitmap_get_persistence(BdrvDirtyBitmap *bitmap)
835{
836 return bitmap->persistent && !bitmap->skip_store;
837}
838
839bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
840{
841 return bitmap->inconsistent;
842}
843
844BdrvDirtyBitmap *bdrv_dirty_bitmap_first(BlockDriverState *bs)
845{
846 return QLIST_FIRST(&bs->dirty_bitmaps);
847}
848
849BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BdrvDirtyBitmap *bitmap)
850{
851 return QLIST_NEXT(bitmap, list);
852}
853
854char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
855{
856 return hbitmap_sha256(bitmap->bitmap, errp);
857}
858
859int64_t bdrv_dirty_bitmap_next_dirty(BdrvDirtyBitmap *bitmap, int64_t offset,
860 int64_t bytes)
861{
862 return hbitmap_next_dirty(bitmap->bitmap, offset, bytes);
863}
864
865int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, int64_t offset,
866 int64_t bytes)
867{
868 return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
869}
870
871bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
872 int64_t start, int64_t end, int64_t max_dirty_count,
873 int64_t *dirty_start, int64_t *dirty_count)
874{
875 return hbitmap_next_dirty_area(bitmap->bitmap, start, end, max_dirty_count,
876 dirty_start, dirty_count);
877}
878
879bool bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap, int64_t offset,
880 int64_t bytes, int64_t *count)
881{
882 return hbitmap_status(bitmap->bitmap, offset, bytes, count);
883}
884
885
886
887
888
889
890
891
892
893
894bool bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
895 HBitmap **backup, Error **errp)
896{
897 bool ret = false;
898
899 bdrv_dirty_bitmaps_lock(dest->bs);
900 if (src->bs != dest->bs) {
901 bdrv_dirty_bitmaps_lock(src->bs);
902 }
903
904 if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) {
905 goto out;
906 }
907
908 if (bdrv_dirty_bitmap_check(src, BDRV_BITMAP_ALLOW_RO, errp)) {
909 goto out;
910 }
911
912 if (bdrv_dirty_bitmap_size(src) != bdrv_dirty_bitmap_size(dest)) {
913 error_setg(errp, "Bitmaps are of different sizes (destination size is %"
914 PRId64 ", source size is %" PRId64 ") and can't be merged",
915 bdrv_dirty_bitmap_size(dest), bdrv_dirty_bitmap_size(src));
916 goto out;
917 }
918
919 bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
920 ret = true;
921
922out:
923 bdrv_dirty_bitmaps_unlock(dest->bs);
924 if (src->bs != dest->bs) {
925 bdrv_dirty_bitmaps_unlock(src->bs);
926 }
927
928 return ret;
929}
930
931
932
933
934
935
936
937
938
939void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
940 const BdrvDirtyBitmap *src,
941 HBitmap **backup,
942 bool lock)
943{
944 IO_CODE();
945
946 assert(!bdrv_dirty_bitmap_readonly(dest));
947 assert(!bdrv_dirty_bitmap_inconsistent(dest));
948 assert(!bdrv_dirty_bitmap_inconsistent(src));
949
950 if (lock) {
951 bdrv_dirty_bitmaps_lock(dest->bs);
952 if (src->bs != dest->bs) {
953 bdrv_dirty_bitmaps_lock(src->bs);
954 }
955 }
956
957 if (backup) {
958 *backup = dest->bitmap;
959 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
960 hbitmap_merge(*backup, src->bitmap, dest->bitmap);
961 } else {
962 hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
963 }
964
965 if (lock) {
966 bdrv_dirty_bitmaps_unlock(dest->bs);
967 if (src->bs != dest->bs) {
968 bdrv_dirty_bitmaps_unlock(src->bs);
969 }
970 }
971}
972