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
481bool
482bdrv_supports_persistent_dirty_bitmap(BlockDriverState *bs)
483{
484 if (bs->drv && bs->drv->bdrv_supports_persistent_dirty_bitmap) {
485 return bs->drv->bdrv_supports_persistent_dirty_bitmap(bs);
486 }
487 return false;
488}
489
490static bool coroutine_fn
491bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
492 uint32_t granularity, Error **errp)
493{
494 BlockDriver *drv = bs->drv;
495
496 if (!drv) {
497 error_setg_errno(errp, ENOMEDIUM,
498 "Can't store persistent bitmaps to %s",
499 bdrv_get_device_or_node_name(bs));
500 return false;
501 }
502
503 if (!drv->bdrv_co_can_store_new_dirty_bitmap) {
504 error_setg_errno(errp, ENOTSUP,
505 "Can't store persistent bitmaps to %s",
506 bdrv_get_device_or_node_name(bs));
507 return false;
508 }
509
510 return drv->bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
511}
512
513typedef struct BdrvCanStoreNewDirtyBitmapCo {
514 BlockDriverState *bs;
515 const char *name;
516 uint32_t granularity;
517 Error **errp;
518 bool ret;
519
520 bool in_progress;
521} BdrvCanStoreNewDirtyBitmapCo;
522
523static void coroutine_fn bdrv_co_can_store_new_dirty_bitmap_entry(void *opaque)
524{
525 BdrvCanStoreNewDirtyBitmapCo *s = opaque;
526
527 s->ret = bdrv_co_can_store_new_dirty_bitmap(s->bs, s->name, s->granularity,
528 s->errp);
529 s->in_progress = false;
530 aio_wait_kick();
531}
532
533bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
534 uint32_t granularity, Error **errp)
535{
536 if (qemu_in_coroutine()) {
537 return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
538 } else {
539 Coroutine *co;
540 BdrvCanStoreNewDirtyBitmapCo s = {
541 .bs = bs,
542 .name = name,
543 .granularity = granularity,
544 .errp = errp,
545 .in_progress = true,
546 };
547
548 co = qemu_coroutine_create(bdrv_co_can_store_new_dirty_bitmap_entry,
549 &s);
550 bdrv_coroutine_enter(bs, co);
551 BDRV_POLL_WHILE(bs, s.in_progress);
552
553 return s.ret;
554 }
555}
556
557void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
558{
559 bdrv_dirty_bitmaps_lock(bitmap->bs);
560 bitmap->disabled = true;
561 bdrv_dirty_bitmaps_unlock(bitmap->bs);
562}
563
564void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
565{
566 bdrv_dirty_bitmaps_lock(bitmap->bs);
567 bdrv_enable_dirty_bitmap_locked(bitmap);
568 bdrv_dirty_bitmaps_unlock(bitmap->bs);
569}
570
571BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
572{
573 BdrvDirtyBitmap *bm;
574 BlockDirtyInfoList *list = NULL;
575 BlockDirtyInfoList **plist = &list;
576
577 bdrv_dirty_bitmaps_lock(bs);
578 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
579 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
580 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
581 info->count = bdrv_get_dirty_count(bm);
582 info->granularity = bdrv_dirty_bitmap_granularity(bm);
583 info->has_name = !!bm->name;
584 info->name = g_strdup(bm->name);
585 info->status = bdrv_dirty_bitmap_status(bm);
586 info->recording = bdrv_dirty_bitmap_recording(bm);
587 info->busy = bdrv_dirty_bitmap_busy(bm);
588 info->persistent = bm->persistent;
589 info->has_inconsistent = bm->inconsistent;
590 info->inconsistent = bm->inconsistent;
591 entry->value = info;
592 *plist = entry;
593 plist = &entry->next;
594 }
595 bdrv_dirty_bitmaps_unlock(bs);
596
597 return list;
598}
599
600
601bool bdrv_dirty_bitmap_get_locked(BdrvDirtyBitmap *bitmap, int64_t offset)
602{
603 return hbitmap_get(bitmap->bitmap, offset);
604}
605
606bool bdrv_dirty_bitmap_get(BdrvDirtyBitmap *bitmap, int64_t offset)
607{
608 bool ret;
609 bdrv_dirty_bitmaps_lock(bitmap->bs);
610 ret = bdrv_dirty_bitmap_get_locked(bitmap, offset);
611 bdrv_dirty_bitmaps_unlock(bitmap->bs);
612
613 return ret;
614}
615
616
617
618
619
620
621uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
622{
623 BlockDriverInfo bdi;
624 uint32_t granularity;
625
626 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
627 granularity = MAX(4096, bdi.cluster_size);
628 granularity = MIN(65536, granularity);
629 } else {
630 granularity = 65536;
631 }
632
633 return granularity;
634}
635
636uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
637{
638 return 1U << hbitmap_granularity(bitmap->bitmap);
639}
640
641BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
642{
643 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
644 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
645 iter->bitmap = bitmap;
646 bitmap->active_iterators++;
647 return iter;
648}
649
650void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
651{
652 if (!iter) {
653 return;
654 }
655 assert(iter->bitmap->active_iterators > 0);
656 iter->bitmap->active_iterators--;
657 g_free(iter);
658}
659
660int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
661{
662 return hbitmap_iter_next(&iter->hbi);
663}
664
665
666void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
667 int64_t offset, int64_t bytes)
668{
669 assert(!bdrv_dirty_bitmap_readonly(bitmap));
670 hbitmap_set(bitmap->bitmap, offset, bytes);
671}
672
673void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
674 int64_t offset, int64_t bytes)
675{
676 bdrv_dirty_bitmaps_lock(bitmap->bs);
677 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
678 bdrv_dirty_bitmaps_unlock(bitmap->bs);
679}
680
681
682void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
683 int64_t offset, int64_t bytes)
684{
685 assert(!bdrv_dirty_bitmap_readonly(bitmap));
686 hbitmap_reset(bitmap->bitmap, offset, bytes);
687}
688
689void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
690 int64_t offset, int64_t bytes)
691{
692 bdrv_dirty_bitmaps_lock(bitmap->bs);
693 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
694 bdrv_dirty_bitmaps_unlock(bitmap->bs);
695}
696
697void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
698{
699 assert(!bdrv_dirty_bitmap_readonly(bitmap));
700 bdrv_dirty_bitmaps_lock(bitmap->bs);
701 if (!out) {
702 hbitmap_reset_all(bitmap->bitmap);
703 } else {
704 HBitmap *backup = bitmap->bitmap;
705 bitmap->bitmap = hbitmap_alloc(bitmap->size,
706 hbitmap_granularity(backup));
707 *out = backup;
708 }
709 bdrv_dirty_bitmaps_unlock(bitmap->bs);
710}
711
712void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
713{
714 HBitmap *tmp = bitmap->bitmap;
715 assert(!bdrv_dirty_bitmap_readonly(bitmap));
716 bitmap->bitmap = backup;
717 hbitmap_free(tmp);
718}
719
720uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
721 uint64_t offset, uint64_t bytes)
722{
723 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
724}
725
726uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
727{
728 return hbitmap_serialization_align(bitmap->bitmap);
729}
730
731void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
732 uint8_t *buf, uint64_t offset,
733 uint64_t bytes)
734{
735 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
736}
737
738void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
739 uint8_t *buf, uint64_t offset,
740 uint64_t bytes, bool finish)
741{
742 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
743}
744
745void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
746 uint64_t offset, uint64_t bytes,
747 bool finish)
748{
749 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
750}
751
752void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
753 uint64_t offset, uint64_t bytes,
754 bool finish)
755{
756 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
757}
758
759void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
760{
761 hbitmap_deserialize_finish(bitmap->bitmap);
762}
763
764void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
765{
766 BdrvDirtyBitmap *bitmap;
767
768 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
769 return;
770 }
771
772 bdrv_dirty_bitmaps_lock(bs);
773 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
774 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
775 continue;
776 }
777 assert(!bdrv_dirty_bitmap_readonly(bitmap));
778 hbitmap_set(bitmap->bitmap, offset, bytes);
779 }
780 bdrv_dirty_bitmaps_unlock(bs);
781}
782
783
784
785
786void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
787{
788 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
789}
790
791int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
792{
793 return hbitmap_count(bitmap->bitmap);
794}
795
796bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
797{
798 return bitmap->readonly;
799}
800
801
802void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
803{
804 bdrv_dirty_bitmaps_lock(bitmap->bs);
805 bitmap->readonly = value;
806 bdrv_dirty_bitmaps_unlock(bitmap->bs);
807}
808
809bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
810{
811 BdrvDirtyBitmap *bm;
812 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
813 if (bm->readonly) {
814 return true;
815 }
816 }
817
818 return false;
819}
820
821bool bdrv_has_named_bitmaps(BlockDriverState *bs)
822{
823 BdrvDirtyBitmap *bm;
824
825 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
826 if (bdrv_dirty_bitmap_name(bm)) {
827 return true;
828 }
829 }
830
831 return false;
832}
833
834
835void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent)
836{
837 bdrv_dirty_bitmaps_lock(bitmap->bs);
838 bitmap->persistent = persistent;
839 bdrv_dirty_bitmaps_unlock(bitmap->bs);
840}
841
842
843void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
844{
845 bdrv_dirty_bitmaps_lock(bitmap->bs);
846 assert(bitmap->persistent == true);
847 bitmap->inconsistent = true;
848 bitmap->disabled = true;
849 bdrv_dirty_bitmaps_unlock(bitmap->bs);
850}
851
852
853void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip)
854{
855 bdrv_dirty_bitmaps_lock(bitmap->bs);
856 bitmap->skip_store = skip;
857 bdrv_dirty_bitmaps_unlock(bitmap->bs);
858}
859
860bool bdrv_dirty_bitmap_get_persistence(BdrvDirtyBitmap *bitmap)
861{
862 return bitmap->persistent && !bitmap->skip_store;
863}
864
865bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
866{
867 return bitmap->inconsistent;
868}
869
870BdrvDirtyBitmap *bdrv_dirty_bitmap_first(BlockDriverState *bs)
871{
872 return QLIST_FIRST(&bs->dirty_bitmaps);
873}
874
875BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BdrvDirtyBitmap *bitmap)
876{
877 return QLIST_NEXT(bitmap, list);
878}
879
880char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
881{
882 return hbitmap_sha256(bitmap->bitmap, errp);
883}
884
885int64_t bdrv_dirty_bitmap_next_dirty(BdrvDirtyBitmap *bitmap, int64_t offset,
886 int64_t bytes)
887{
888 return hbitmap_next_dirty(bitmap->bitmap, offset, bytes);
889}
890
891int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, int64_t offset,
892 int64_t bytes)
893{
894 return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
895}
896
897bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
898 int64_t start, int64_t end, int64_t max_dirty_count,
899 int64_t *dirty_start, int64_t *dirty_count)
900{
901 return hbitmap_next_dirty_area(bitmap->bitmap, start, end, max_dirty_count,
902 dirty_start, dirty_count);
903}
904
905
906
907
908
909
910
911void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
912 HBitmap **backup, Error **errp)
913{
914 bool ret;
915
916 bdrv_dirty_bitmaps_lock(dest->bs);
917 if (src->bs != dest->bs) {
918 bdrv_dirty_bitmaps_lock(src->bs);
919 }
920
921 if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) {
922 goto out;
923 }
924
925 if (bdrv_dirty_bitmap_check(src, BDRV_BITMAP_ALLOW_RO, errp)) {
926 goto out;
927 }
928
929 if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
930 error_setg(errp, "Bitmaps are incompatible and can't be merged");
931 goto out;
932 }
933
934 ret = bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
935 assert(ret);
936
937out:
938 bdrv_dirty_bitmaps_unlock(dest->bs);
939 if (src->bs != dest->bs) {
940 bdrv_dirty_bitmaps_unlock(src->bs);
941 }
942}
943
944
945
946
947
948
949
950
951
952bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
953 const BdrvDirtyBitmap *src,
954 HBitmap **backup,
955 bool lock)
956{
957 bool ret;
958
959 assert(!bdrv_dirty_bitmap_readonly(dest));
960 assert(!bdrv_dirty_bitmap_inconsistent(dest));
961 assert(!bdrv_dirty_bitmap_inconsistent(src));
962
963 if (lock) {
964 bdrv_dirty_bitmaps_lock(dest->bs);
965 if (src->bs != dest->bs) {
966 bdrv_dirty_bitmaps_lock(src->bs);
967 }
968 }
969
970 if (backup) {
971 *backup = dest->bitmap;
972 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
973 ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
974 } else {
975 ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
976 }
977
978 if (lock) {
979 bdrv_dirty_bitmaps_unlock(dest->bs);
980 if (src->bs != dest->bs) {
981 bdrv_dirty_bitmaps_unlock(src->bs);
982 }
983 }
984
985 return ret;
986}
987