Lines Matching +full:non +full:- +full:persistent
4 * Copyright (c) 2016-2017 Red Hat. Inc
27 #include "block/block-io.h"
30 #include "block/dirty-bitmap.h"
31 #include "qemu/main-loop.h"
38 char *name; /* Optional non-empty unique ID */
43 bool readonly; /* Bitmap is read-only. This field also
49 bool persistent; /* bitmap must be saved to owner disk image */ member
50 bool inconsistent; /* bitmap is persistent, but inconsistent.
66 qemu_mutex_lock(&bs->dirty_bitmap_mutex); in bdrv_dirty_bitmaps_lock()
71 qemu_mutex_unlock(&bs->dirty_bitmap_mutex); in bdrv_dirty_bitmaps_unlock()
76 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_lock()
81 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_unlock()
90 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { in bdrv_find_dirty_bitmap()
91 if (bm->name && !strcmp(name, bm->name)) { in bdrv_find_dirty_bitmap()
121 error_setg_errno(errp, -bitmap_size, "could not get length of device"); in bdrv_create_dirty_bitmap()
122 errno = -bitmap_size; in bdrv_create_dirty_bitmap()
126 bitmap->bs = bs; in bdrv_create_dirty_bitmap()
127 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity)); in bdrv_create_dirty_bitmap()
128 bitmap->size = bitmap_size; in bdrv_create_dirty_bitmap()
129 bitmap->name = g_strdup(name); in bdrv_create_dirty_bitmap()
130 bitmap->disabled = false; in bdrv_create_dirty_bitmap()
132 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list); in bdrv_create_dirty_bitmap()
139 return bitmap->size; in bdrv_dirty_bitmap_size()
144 return bitmap->name; in bdrv_dirty_bitmap_name()
150 return bitmap->successor; in bdrv_dirty_bitmap_has_successor()
155 return bitmap->busy; in bdrv_dirty_bitmap_busy()
160 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_set_busy()
161 bitmap->busy = busy; in bdrv_dirty_bitmap_set_busy()
162 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_set_busy()
168 return !bitmap->disabled; in bdrv_dirty_bitmap_enabled()
174 return !bitmap->disabled || (bitmap->successor && in bdrv_dirty_bitmap_recording()
175 !bitmap->successor->disabled); in bdrv_dirty_bitmap_recording()
183 " operation and cannot be used", bitmap->name); in bdrv_dirty_bitmap_check()
184 return -1; in bdrv_dirty_bitmap_check()
189 bitmap->name); in bdrv_dirty_bitmap_check()
190 return -1; in bdrv_dirty_bitmap_check()
196 bitmap->name); in bdrv_dirty_bitmap_check()
197 error_append_hint(errp, "Try block-dirty-bitmap-remove to delete" in bdrv_dirty_bitmap_check()
199 return -1; in bdrv_dirty_bitmap_check()
217 return -1; in bdrv_dirty_bitmap_create_successor()
222 return -1; in bdrv_dirty_bitmap_create_successor()
227 child = bdrv_create_dirty_bitmap(bitmap->bs, granularity, NULL, errp); in bdrv_dirty_bitmap_create_successor()
229 return -1; in bdrv_dirty_bitmap_create_successor()
233 child->disabled = bitmap->disabled; in bdrv_dirty_bitmap_create_successor()
234 bitmap->disabled = true; in bdrv_dirty_bitmap_create_successor()
237 bitmap->successor = child; in bdrv_dirty_bitmap_create_successor()
238 bitmap->busy = true; in bdrv_dirty_bitmap_create_successor()
244 bitmap->disabled = false; in bdrv_enable_dirty_bitmap_locked()
250 assert(bitmap->bs == bitmap->successor->bs); in bdrv_dirty_bitmap_enable_successor()
251 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_enable_successor()
252 bdrv_enable_dirty_bitmap_locked(bitmap->successor); in bdrv_dirty_bitmap_enable_successor()
253 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_enable_successor()
259 assert(!bitmap->active_iterators); in bdrv_release_dirty_bitmap_locked()
263 hbitmap_free(bitmap->bitmap); in bdrv_release_dirty_bitmap_locked()
264 g_free(bitmap->name); in bdrv_release_dirty_bitmap_locked()
277 BdrvDirtyBitmap *successor = bitmap->successor; in bdrv_dirty_bitmap_abdicate()
285 name = bitmap->name; in bdrv_dirty_bitmap_abdicate()
286 bitmap->name = NULL; in bdrv_dirty_bitmap_abdicate()
287 successor->name = name; in bdrv_dirty_bitmap_abdicate()
288 bitmap->successor = NULL; in bdrv_dirty_bitmap_abdicate()
289 successor->persistent = bitmap->persistent; in bdrv_dirty_bitmap_abdicate()
290 bitmap->persistent = false; in bdrv_dirty_bitmap_abdicate()
291 bitmap->busy = false; in bdrv_dirty_bitmap_abdicate()
299 * we may wish to re-join the parent and child/successor.
307 BdrvDirtyBitmap *successor = parent->successor; in bdrv_reclaim_dirty_bitmap_locked()
314 hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap); in bdrv_reclaim_dirty_bitmap_locked()
316 parent->disabled = successor->disabled; in bdrv_reclaim_dirty_bitmap_locked()
317 parent->busy = false; in bdrv_reclaim_dirty_bitmap_locked()
319 parent->successor = NULL; in bdrv_reclaim_dirty_bitmap_locked()
330 bdrv_dirty_bitmaps_lock(parent->bs); in bdrv_reclaim_dirty_bitmap()
332 bdrv_dirty_bitmaps_unlock(parent->bs); in bdrv_reclaim_dirty_bitmap()
346 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { in bdrv_dirty_bitmap_truncate()
349 assert(!bitmap->active_iterators); in bdrv_dirty_bitmap_truncate()
350 hbitmap_truncate(bitmap->bitmap, bytes); in bdrv_dirty_bitmap_truncate()
351 bitmap->size = bytes; in bdrv_dirty_bitmap_truncate()
359 BlockDriverState *bs = bitmap->bs; in bdrv_release_dirty_bitmap()
369 * This function does not remove persistent bitmaps from the storage.
377 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { in bdrv_release_named_dirty_bitmaps()
386 * Remove persistent dirty bitmap from the storage if it exists.
388 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
398 if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) { in bdrv_co_remove_persistent_dirty_bitmap()
399 return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp); in bdrv_co_remove_persistent_dirty_bitmap()
408 if (bs->drv && bs->drv->bdrv_supports_persistent_dirty_bitmap) { in bdrv_supports_persistent_dirty_bitmap()
409 return bs->drv->bdrv_supports_persistent_dirty_bitmap(bs); in bdrv_supports_persistent_dirty_bitmap()
418 BlockDriver *drv = bs->drv; in bdrv_co_can_store_new_dirty_bitmap()
423 "Can't store persistent bitmaps to %s", in bdrv_co_can_store_new_dirty_bitmap()
428 if (!drv->bdrv_co_can_store_new_dirty_bitmap) { in bdrv_co_can_store_new_dirty_bitmap()
430 "Can't store persistent bitmaps to %s", in bdrv_co_can_store_new_dirty_bitmap()
435 return drv->bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp); in bdrv_co_can_store_new_dirty_bitmap()
440 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_disable_dirty_bitmap()
441 bitmap->disabled = true; in bdrv_disable_dirty_bitmap()
442 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_disable_dirty_bitmap()
447 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_enable_dirty_bitmap()
449 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_enable_dirty_bitmap()
459 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { in bdrv_query_dirty_bitmaps()
462 info->count = bdrv_get_dirty_count(bm); in bdrv_query_dirty_bitmaps()
463 info->granularity = bdrv_dirty_bitmap_granularity(bm); in bdrv_query_dirty_bitmaps()
464 info->name = g_strdup(bm->name); in bdrv_query_dirty_bitmaps()
465 info->recording = bdrv_dirty_bitmap_recording(bm); in bdrv_query_dirty_bitmaps()
466 info->busy = bdrv_dirty_bitmap_busy(bm); in bdrv_query_dirty_bitmaps()
467 info->persistent = bm->persistent; in bdrv_query_dirty_bitmaps()
468 info->has_inconsistent = bm->inconsistent; in bdrv_query_dirty_bitmaps()
469 info->inconsistent = bm->inconsistent; in bdrv_query_dirty_bitmaps()
480 return hbitmap_get(bitmap->bitmap, offset); in bdrv_dirty_bitmap_get_locked()
486 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_get()
488 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_get()
515 return 1U << hbitmap_granularity(bitmap->bitmap); in bdrv_dirty_bitmap_granularity()
521 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0); in bdrv_dirty_iter_new()
522 iter->bitmap = bitmap; in bdrv_dirty_iter_new()
523 bitmap->active_iterators++; in bdrv_dirty_iter_new()
532 assert(iter->bitmap->active_iterators > 0); in bdrv_dirty_iter_free()
533 iter->bitmap->active_iterators--; in bdrv_dirty_iter_free()
539 return hbitmap_iter_next(&iter->hbi); in bdrv_dirty_iter_next()
547 hbitmap_set(bitmap->bitmap, offset, bytes); in bdrv_set_dirty_bitmap_locked()
553 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_set_dirty_bitmap()
555 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_set_dirty_bitmap()
563 hbitmap_reset(bitmap->bitmap, offset, bytes); in bdrv_reset_dirty_bitmap_locked()
569 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_reset_dirty_bitmap()
571 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_reset_dirty_bitmap()
578 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_clear_dirty_bitmap()
580 hbitmap_reset_all(bitmap->bitmap); in bdrv_clear_dirty_bitmap()
582 HBitmap *backup = bitmap->bitmap; in bdrv_clear_dirty_bitmap()
583 bitmap->bitmap = hbitmap_alloc(bitmap->size, in bdrv_clear_dirty_bitmap()
587 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_clear_dirty_bitmap()
592 HBitmap *tmp = bitmap->bitmap; in bdrv_restore_dirty_bitmap()
595 bitmap->bitmap = backup; in bdrv_restore_dirty_bitmap()
602 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes); in bdrv_dirty_bitmap_serialization_size()
607 return hbitmap_serialization_align(bitmap->bitmap); in bdrv_dirty_bitmap_serialization_align()
627 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes); in bdrv_dirty_bitmap_serialize_part()
634 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish); in bdrv_dirty_bitmap_deserialize_part()
641 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish); in bdrv_dirty_bitmap_deserialize_zeroes()
648 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish); in bdrv_dirty_bitmap_deserialize_ones()
653 hbitmap_deserialize_finish(bitmap->bitmap); in bdrv_dirty_bitmap_deserialize_finish()
661 if (QLIST_EMPTY(&bs->dirty_bitmaps)) { in bdrv_set_dirty()
666 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) { in bdrv_set_dirty()
671 hbitmap_set(bitmap->bitmap, offset, bytes); in bdrv_set_dirty()
681 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset); in bdrv_set_dirty_iter()
686 return hbitmap_count(bitmap->bitmap); in bdrv_get_dirty_count()
691 return bitmap->readonly; in bdrv_dirty_bitmap_readonly()
697 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_set_readonly()
698 bitmap->readonly = value; in bdrv_dirty_bitmap_set_readonly()
699 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_set_readonly()
705 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { in bdrv_has_readonly_bitmaps()
706 if (bm->readonly) { in bdrv_has_readonly_bitmaps()
718 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { in bdrv_has_named_bitmaps()
728 void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent) in bdrv_dirty_bitmap_set_persistence() argument
730 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_set_persistence()
731 bitmap->persistent = persistent; in bdrv_dirty_bitmap_set_persistence()
732 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_set_persistence()
738 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_set_inconsistent()
739 assert(bitmap->persistent == true); in bdrv_dirty_bitmap_set_inconsistent()
740 bitmap->inconsistent = true; in bdrv_dirty_bitmap_set_inconsistent()
741 bitmap->disabled = true; in bdrv_dirty_bitmap_set_inconsistent()
742 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_set_inconsistent()
748 bdrv_dirty_bitmaps_lock(bitmap->bs); in bdrv_dirty_bitmap_skip_store()
749 bitmap->skip_store = skip; in bdrv_dirty_bitmap_skip_store()
750 bdrv_dirty_bitmaps_unlock(bitmap->bs); in bdrv_dirty_bitmap_skip_store()
755 return bitmap->persistent && !bitmap->skip_store; in bdrv_dirty_bitmap_get_persistence()
760 return bitmap->inconsistent; in bdrv_dirty_bitmap_inconsistent()
765 return QLIST_FIRST(&bs->dirty_bitmaps); in bdrv_dirty_bitmap_first()
775 return hbitmap_sha256(bitmap->bitmap, errp); in bdrv_dirty_bitmap_sha256()
781 return hbitmap_next_dirty(bitmap->bitmap, offset, bytes); in bdrv_dirty_bitmap_next_dirty()
787 return hbitmap_next_zero(bitmap->bitmap, offset, bytes); in bdrv_dirty_bitmap_next_zero()
794 return hbitmap_next_dirty_area(bitmap->bitmap, start, end, max_dirty_count, in bdrv_dirty_bitmap_next_dirty_area()
801 return hbitmap_status(bitmap->bitmap, offset, bytes, count); in bdrv_dirty_bitmap_status()
818 bdrv_dirty_bitmaps_lock(dest->bs); in bdrv_merge_dirty_bitmap()
819 if (src->bs != dest->bs) { in bdrv_merge_dirty_bitmap()
820 bdrv_dirty_bitmaps_lock(src->bs); in bdrv_merge_dirty_bitmap()
842 bdrv_dirty_bitmaps_unlock(dest->bs); in bdrv_merge_dirty_bitmap()
843 if (src->bs != dest->bs) { in bdrv_merge_dirty_bitmap()
844 bdrv_dirty_bitmaps_unlock(src->bs); in bdrv_merge_dirty_bitmap()
870 bdrv_dirty_bitmaps_lock(dest->bs); in bdrv_dirty_bitmap_merge_internal()
871 if (src->bs != dest->bs) { in bdrv_dirty_bitmap_merge_internal()
872 bdrv_dirty_bitmaps_lock(src->bs); in bdrv_dirty_bitmap_merge_internal()
877 *backup = dest->bitmap; in bdrv_dirty_bitmap_merge_internal()
878 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup)); in bdrv_dirty_bitmap_merge_internal()
879 hbitmap_merge(*backup, src->bitmap, dest->bitmap); in bdrv_dirty_bitmap_merge_internal()
881 hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap); in bdrv_dirty_bitmap_merge_internal()
885 bdrv_dirty_bitmaps_unlock(dest->bs); in bdrv_dirty_bitmap_merge_internal()
886 if (src->bs != dest->bs) { in bdrv_dirty_bitmap_merge_internal()
887 bdrv_dirty_bitmaps_unlock(src->bs); in bdrv_dirty_bitmap_merge_internal()