tests: test-hmp: print command execution result
[qemu/ar7.git] / block / dirty-bitmap.c
blobbd04e991b10d95669e49268e28c54e0b2a3eabad
1 /*
2 * Block Dirty Bitmap
4 * Copyright (c) 2016-2017 Red Hat. Inc
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 #include "qemu/osdep.h"
25 #include "qapi/error.h"
26 #include "qemu-common.h"
27 #include "trace.h"
28 #include "block/block_int.h"
29 #include "block/blockjob.h"
31 /**
32 * A BdrvDirtyBitmap can be in three possible states:
33 * (1) successor is NULL and disabled is false: full r/w mode
34 * (2) successor is NULL and disabled is true: read only mode ("disabled")
35 * (3) successor is set: frozen mode.
36 * A frozen bitmap cannot be renamed, deleted, anonymized, cleared, set,
37 * or enabled. A frozen bitmap can only abdicate() or reclaim().
39 struct BdrvDirtyBitmap {
40 QemuMutex *mutex;
41 HBitmap *bitmap; /* Dirty bitmap implementation */
42 HBitmap *meta; /* Meta dirty bitmap */
43 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
44 char *name; /* Optional non-empty unique ID */
45 int64_t size; /* Size of the bitmap, in bytes */
46 bool disabled; /* Bitmap is disabled. It ignores all writes to
47 the device */
48 int active_iterators; /* How many iterators are active */
49 bool readonly; /* Bitmap is read-only. This field also
50 prevents the respective image from being
51 modified (i.e. blocks writes and discards).
52 Such operations must fail and both the image
53 and this bitmap must remain unchanged while
54 this flag is set. */
55 bool autoload; /* For persistent bitmaps: bitmap must be
56 autoloaded on image opening */
57 bool persistent; /* bitmap must be saved to owner disk image */
58 QLIST_ENTRY(BdrvDirtyBitmap) list;
61 struct BdrvDirtyBitmapIter {
62 HBitmapIter hbi;
63 BdrvDirtyBitmap *bitmap;
66 static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
68 qemu_mutex_lock(&bs->dirty_bitmap_mutex);
71 static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
73 qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
76 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
78 qemu_mutex_lock(bitmap->mutex);
81 void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
83 qemu_mutex_unlock(bitmap->mutex);
86 /* Called with BQL or dirty_bitmap lock taken. */
87 BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
89 BdrvDirtyBitmap *bm;
91 assert(name);
92 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
93 if (bm->name && !strcmp(name, bm->name)) {
94 return bm;
97 return NULL;
100 /* Called with BQL taken. */
101 void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
103 assert(!bdrv_dirty_bitmap_frozen(bitmap));
104 g_free(bitmap->name);
105 bitmap->name = NULL;
106 bitmap->persistent = false;
107 bitmap->autoload = false;
110 /* Called with BQL taken. */
111 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
112 uint32_t granularity,
113 const char *name,
114 Error **errp)
116 int64_t bitmap_size;
117 BdrvDirtyBitmap *bitmap;
119 assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
121 if (name && bdrv_find_dirty_bitmap(bs, name)) {
122 error_setg(errp, "Bitmap already exists: %s", name);
123 return NULL;
125 bitmap_size = bdrv_getlength(bs);
126 if (bitmap_size < 0) {
127 error_setg_errno(errp, -bitmap_size, "could not get length of device");
128 errno = -bitmap_size;
129 return NULL;
131 bitmap = g_new0(BdrvDirtyBitmap, 1);
132 bitmap->mutex = &bs->dirty_bitmap_mutex;
133 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
134 bitmap->size = bitmap_size;
135 bitmap->name = g_strdup(name);
136 bitmap->disabled = false;
137 bdrv_dirty_bitmaps_lock(bs);
138 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
139 bdrv_dirty_bitmaps_unlock(bs);
140 return bitmap;
143 /* bdrv_create_meta_dirty_bitmap
145 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
146 * when a dirty status bit in @bitmap is changed (either from reset to set or
147 * the other way around), its respective meta dirty bitmap bit will be marked
148 * dirty as well.
150 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
151 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
152 * track.
154 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
155 int chunk_size)
157 assert(!bitmap->meta);
158 qemu_mutex_lock(bitmap->mutex);
159 bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
160 chunk_size * BITS_PER_BYTE);
161 qemu_mutex_unlock(bitmap->mutex);
164 void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
166 assert(bitmap->meta);
167 qemu_mutex_lock(bitmap->mutex);
168 hbitmap_free_meta(bitmap->bitmap);
169 bitmap->meta = NULL;
170 qemu_mutex_unlock(bitmap->mutex);
173 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
175 return bitmap->size;
178 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
180 return bitmap->name;
183 /* Called with BQL taken. */
184 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
186 return bitmap->successor;
189 /* Called with BQL taken. */
190 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
192 return !(bitmap->disabled || bitmap->successor);
195 /* Called with BQL taken. */
196 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
198 if (bdrv_dirty_bitmap_frozen(bitmap)) {
199 return DIRTY_BITMAP_STATUS_FROZEN;
200 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
201 return DIRTY_BITMAP_STATUS_DISABLED;
202 } else {
203 return DIRTY_BITMAP_STATUS_ACTIVE;
208 * Create a successor bitmap destined to replace this bitmap after an operation.
209 * Requires that the bitmap is not frozen and has no successor.
210 * Called with BQL taken.
212 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
213 BdrvDirtyBitmap *bitmap, Error **errp)
215 uint64_t granularity;
216 BdrvDirtyBitmap *child;
218 if (bdrv_dirty_bitmap_frozen(bitmap)) {
219 error_setg(errp, "Cannot create a successor for a bitmap that is "
220 "currently frozen");
221 return -1;
223 assert(!bitmap->successor);
225 /* Create an anonymous successor */
226 granularity = bdrv_dirty_bitmap_granularity(bitmap);
227 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
228 if (!child) {
229 return -1;
232 /* Successor will be on or off based on our current state. */
233 child->disabled = bitmap->disabled;
235 /* Install the successor and freeze the parent */
236 bitmap->successor = child;
237 return 0;
241 * For a bitmap with a successor, yield our name to the successor,
242 * delete the old bitmap, and return a handle to the new bitmap.
243 * Called with BQL taken.
245 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
246 BdrvDirtyBitmap *bitmap,
247 Error **errp)
249 char *name;
250 BdrvDirtyBitmap *successor = bitmap->successor;
252 if (successor == NULL) {
253 error_setg(errp, "Cannot relinquish control if "
254 "there's no successor present");
255 return NULL;
258 name = bitmap->name;
259 bitmap->name = NULL;
260 successor->name = name;
261 bitmap->successor = NULL;
262 successor->persistent = bitmap->persistent;
263 bitmap->persistent = false;
264 successor->autoload = bitmap->autoload;
265 bitmap->autoload = false;
266 bdrv_release_dirty_bitmap(bs, bitmap);
268 return successor;
272 * In cases of failure where we can no longer safely delete the parent,
273 * we may wish to re-join the parent and child/successor.
274 * The merged parent will be un-frozen, but not explicitly re-enabled.
275 * Called with BQL taken.
277 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
278 BdrvDirtyBitmap *parent,
279 Error **errp)
281 BdrvDirtyBitmap *successor = parent->successor;
283 if (!successor) {
284 error_setg(errp, "Cannot reclaim a successor when none is present");
285 return NULL;
288 if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
289 error_setg(errp, "Merging of parent and successor bitmap failed");
290 return NULL;
292 bdrv_release_dirty_bitmap(bs, successor);
293 parent->successor = NULL;
295 return parent;
299 * Truncates _all_ bitmaps attached to a BDS.
300 * Called with BQL taken.
302 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
304 BdrvDirtyBitmap *bitmap;
306 bdrv_dirty_bitmaps_lock(bs);
307 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
308 assert(!bdrv_dirty_bitmap_frozen(bitmap));
309 assert(!bitmap->active_iterators);
310 hbitmap_truncate(bitmap->bitmap, bytes);
311 bitmap->size = bytes;
313 bdrv_dirty_bitmaps_unlock(bs);
316 static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
318 return !!bdrv_dirty_bitmap_name(bitmap);
321 /* Called with BQL taken. */
322 static void bdrv_do_release_matching_dirty_bitmap(
323 BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
324 bool (*cond)(BdrvDirtyBitmap *bitmap))
326 BdrvDirtyBitmap *bm, *next;
327 bdrv_dirty_bitmaps_lock(bs);
328 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
329 if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
330 assert(!bm->active_iterators);
331 assert(!bdrv_dirty_bitmap_frozen(bm));
332 assert(!bm->meta);
333 QLIST_REMOVE(bm, list);
334 hbitmap_free(bm->bitmap);
335 g_free(bm->name);
336 g_free(bm);
338 if (bitmap) {
339 goto out;
343 if (bitmap) {
344 abort();
347 out:
348 bdrv_dirty_bitmaps_unlock(bs);
351 /* Called with BQL taken. */
352 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
354 bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
358 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
359 * There must not be any frozen bitmaps attached.
360 * This function does not remove persistent bitmaps from the storage.
361 * Called with BQL taken.
363 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
365 bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
369 * Release all persistent dirty bitmaps attached to a BDS (for use in
370 * bdrv_inactivate_recurse()).
371 * There must not be any frozen bitmaps attached.
372 * This function does not remove persistent bitmaps from the storage.
374 void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
376 bdrv_do_release_matching_dirty_bitmap(bs, NULL,
377 bdrv_dirty_bitmap_get_persistance);
381 * Remove persistent dirty bitmap from the storage if it exists.
382 * Absence of bitmap is not an error, because we have the following scenario:
383 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
384 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
385 * not fail.
386 * This function doesn't release corresponding BdrvDirtyBitmap.
388 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
389 const char *name,
390 Error **errp)
392 if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
393 bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
397 /* Called with BQL taken. */
398 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
400 assert(!bdrv_dirty_bitmap_frozen(bitmap));
401 bitmap->disabled = true;
404 /* Called with BQL taken. */
405 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
407 assert(!bdrv_dirty_bitmap_frozen(bitmap));
408 bitmap->disabled = false;
411 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
413 BdrvDirtyBitmap *bm;
414 BlockDirtyInfoList *list = NULL;
415 BlockDirtyInfoList **plist = &list;
417 bdrv_dirty_bitmaps_lock(bs);
418 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
419 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
420 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
421 info->count = bdrv_get_dirty_count(bm);
422 info->granularity = bdrv_dirty_bitmap_granularity(bm);
423 info->has_name = !!bm->name;
424 info->name = g_strdup(bm->name);
425 info->status = bdrv_dirty_bitmap_status(bm);
426 entry->value = info;
427 *plist = entry;
428 plist = &entry->next;
430 bdrv_dirty_bitmaps_unlock(bs);
432 return list;
435 /* Called within bdrv_dirty_bitmap_lock..unlock */
436 bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
437 int64_t offset)
439 if (bitmap) {
440 return hbitmap_get(bitmap->bitmap, offset);
441 } else {
442 return false;
447 * Chooses a default granularity based on the existing cluster size,
448 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
449 * is no cluster size information available.
451 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
453 BlockDriverInfo bdi;
454 uint32_t granularity;
456 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
457 granularity = MAX(4096, bdi.cluster_size);
458 granularity = MIN(65536, granularity);
459 } else {
460 granularity = 65536;
463 return granularity;
466 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
468 return 1U << hbitmap_granularity(bitmap->bitmap);
471 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
473 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
474 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
475 iter->bitmap = bitmap;
476 bitmap->active_iterators++;
477 return iter;
480 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
482 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
483 hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
484 iter->bitmap = bitmap;
485 bitmap->active_iterators++;
486 return iter;
489 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
491 if (!iter) {
492 return;
494 assert(iter->bitmap->active_iterators > 0);
495 iter->bitmap->active_iterators--;
496 g_free(iter);
499 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
501 return hbitmap_iter_next(&iter->hbi);
504 /* Called within bdrv_dirty_bitmap_lock..unlock */
505 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
506 int64_t offset, int64_t bytes)
508 assert(bdrv_dirty_bitmap_enabled(bitmap));
509 assert(!bdrv_dirty_bitmap_readonly(bitmap));
510 hbitmap_set(bitmap->bitmap, offset, bytes);
513 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
514 int64_t offset, int64_t bytes)
516 bdrv_dirty_bitmap_lock(bitmap);
517 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
518 bdrv_dirty_bitmap_unlock(bitmap);
521 /* Called within bdrv_dirty_bitmap_lock..unlock */
522 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
523 int64_t offset, int64_t bytes)
525 assert(bdrv_dirty_bitmap_enabled(bitmap));
526 assert(!bdrv_dirty_bitmap_readonly(bitmap));
527 hbitmap_reset(bitmap->bitmap, offset, bytes);
530 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
531 int64_t offset, int64_t bytes)
533 bdrv_dirty_bitmap_lock(bitmap);
534 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
535 bdrv_dirty_bitmap_unlock(bitmap);
538 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
540 assert(bdrv_dirty_bitmap_enabled(bitmap));
541 assert(!bdrv_dirty_bitmap_readonly(bitmap));
542 bdrv_dirty_bitmap_lock(bitmap);
543 if (!out) {
544 hbitmap_reset_all(bitmap->bitmap);
545 } else {
546 HBitmap *backup = bitmap->bitmap;
547 bitmap->bitmap = hbitmap_alloc(bitmap->size,
548 hbitmap_granularity(backup));
549 *out = backup;
551 bdrv_dirty_bitmap_unlock(bitmap);
554 void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
556 HBitmap *tmp = bitmap->bitmap;
557 assert(bdrv_dirty_bitmap_enabled(bitmap));
558 assert(!bdrv_dirty_bitmap_readonly(bitmap));
559 bitmap->bitmap = in;
560 hbitmap_free(tmp);
563 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
564 uint64_t offset, uint64_t bytes)
566 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
569 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
571 return hbitmap_serialization_align(bitmap->bitmap);
574 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
575 uint8_t *buf, uint64_t offset,
576 uint64_t bytes)
578 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
581 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
582 uint8_t *buf, uint64_t offset,
583 uint64_t bytes, bool finish)
585 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
588 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
589 uint64_t offset, uint64_t bytes,
590 bool finish)
592 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
595 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
596 uint64_t offset, uint64_t bytes,
597 bool finish)
599 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
602 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
604 hbitmap_deserialize_finish(bitmap->bitmap);
607 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
609 BdrvDirtyBitmap *bitmap;
611 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
612 return;
615 bdrv_dirty_bitmaps_lock(bs);
616 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
617 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
618 continue;
620 assert(!bdrv_dirty_bitmap_readonly(bitmap));
621 hbitmap_set(bitmap->bitmap, offset, bytes);
623 bdrv_dirty_bitmaps_unlock(bs);
627 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
629 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
631 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
634 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
636 return hbitmap_count(bitmap->bitmap);
639 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
641 return hbitmap_count(bitmap->meta);
644 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
646 return bitmap->readonly;
649 /* Called with BQL taken. */
650 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
652 qemu_mutex_lock(bitmap->mutex);
653 bitmap->readonly = value;
654 qemu_mutex_unlock(bitmap->mutex);
657 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
659 BdrvDirtyBitmap *bm;
660 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
661 if (bm->readonly) {
662 return true;
666 return false;
669 /* Called with BQL taken. */
670 void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload)
672 qemu_mutex_lock(bitmap->mutex);
673 bitmap->autoload = autoload;
674 qemu_mutex_unlock(bitmap->mutex);
677 bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
679 return bitmap->autoload;
682 /* Called with BQL taken. */
683 void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
685 qemu_mutex_lock(bitmap->mutex);
686 bitmap->persistent = persistent;
687 qemu_mutex_unlock(bitmap->mutex);
690 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
692 return bitmap->persistent;
695 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
697 BdrvDirtyBitmap *bm;
698 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
699 if (bm->persistent && !bm->readonly) {
700 return true;
704 return false;
707 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
708 BdrvDirtyBitmap *bitmap)
710 return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
711 QLIST_NEXT(bitmap, list);
714 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
716 return hbitmap_sha256(bitmap->bitmap, errp);