block/dirty-bitmaps: add user_locked status checker
[qemu.git] / block / dirty-bitmap.c
blob9603cdd29bf3437354d49cd4a7c7cd8ffc504bce
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 bool qmp_locked; /* Bitmap is locked, it can't be modified
44 through QMP */
45 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
46 char *name; /* Optional non-empty unique ID */
47 int64_t size; /* Size of the bitmap, in bytes */
48 bool disabled; /* Bitmap is disabled. It ignores all writes to
49 the device */
50 int active_iterators; /* How many iterators are active */
51 bool readonly; /* Bitmap is read-only. This field also
52 prevents the respective image from being
53 modified (i.e. blocks writes and discards).
54 Such operations must fail and both the image
55 and this bitmap must remain unchanged while
56 this flag is set. */
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 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
102 uint32_t granularity,
103 const char *name,
104 Error **errp)
106 int64_t bitmap_size;
107 BdrvDirtyBitmap *bitmap;
109 assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
111 if (name && bdrv_find_dirty_bitmap(bs, name)) {
112 error_setg(errp, "Bitmap already exists: %s", name);
113 return NULL;
115 bitmap_size = bdrv_getlength(bs);
116 if (bitmap_size < 0) {
117 error_setg_errno(errp, -bitmap_size, "could not get length of device");
118 errno = -bitmap_size;
119 return NULL;
121 bitmap = g_new0(BdrvDirtyBitmap, 1);
122 bitmap->mutex = &bs->dirty_bitmap_mutex;
123 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
124 bitmap->size = bitmap_size;
125 bitmap->name = g_strdup(name);
126 bitmap->disabled = false;
127 bdrv_dirty_bitmaps_lock(bs);
128 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
129 bdrv_dirty_bitmaps_unlock(bs);
130 return bitmap;
133 /* bdrv_create_meta_dirty_bitmap
135 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
136 * when a dirty status bit in @bitmap is changed (either from reset to set or
137 * the other way around), its respective meta dirty bitmap bit will be marked
138 * dirty as well.
140 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
141 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
142 * track.
144 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
145 int chunk_size)
147 assert(!bitmap->meta);
148 qemu_mutex_lock(bitmap->mutex);
149 bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
150 chunk_size * BITS_PER_BYTE);
151 qemu_mutex_unlock(bitmap->mutex);
154 void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
156 assert(bitmap->meta);
157 qemu_mutex_lock(bitmap->mutex);
158 hbitmap_free_meta(bitmap->bitmap);
159 bitmap->meta = NULL;
160 qemu_mutex_unlock(bitmap->mutex);
163 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
165 return bitmap->size;
168 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
170 return bitmap->name;
173 /* Called with BQL taken. */
174 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
176 return bitmap->successor;
179 /* Both conditions disallow user-modification via QMP. */
180 bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap) {
181 return bdrv_dirty_bitmap_frozen(bitmap) ||
182 bdrv_dirty_bitmap_qmp_locked(bitmap);
185 void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked)
187 qemu_mutex_lock(bitmap->mutex);
188 bitmap->qmp_locked = qmp_locked;
189 qemu_mutex_unlock(bitmap->mutex);
192 bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap)
194 return bitmap->qmp_locked;
197 /* Called with BQL taken. */
198 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
200 return !(bitmap->disabled || bitmap->successor);
203 /* Called with BQL taken. */
204 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
206 if (bdrv_dirty_bitmap_frozen(bitmap)) {
207 return DIRTY_BITMAP_STATUS_FROZEN;
208 } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) {
209 return DIRTY_BITMAP_STATUS_LOCKED;
210 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
211 return DIRTY_BITMAP_STATUS_DISABLED;
212 } else {
213 return DIRTY_BITMAP_STATUS_ACTIVE;
218 * Create a successor bitmap destined to replace this bitmap after an operation.
219 * Requires that the bitmap is not frozen and has no successor.
220 * Called with BQL taken.
222 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
223 BdrvDirtyBitmap *bitmap, Error **errp)
225 uint64_t granularity;
226 BdrvDirtyBitmap *child;
228 if (bdrv_dirty_bitmap_frozen(bitmap)) {
229 error_setg(errp, "Cannot create a successor for a bitmap that is "
230 "currently frozen");
231 return -1;
233 assert(!bitmap->successor);
235 /* Create an anonymous successor */
236 granularity = bdrv_dirty_bitmap_granularity(bitmap);
237 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
238 if (!child) {
239 return -1;
242 /* Successor will be on or off based on our current state. */
243 child->disabled = bitmap->disabled;
245 /* Install the successor and freeze the parent */
246 bitmap->successor = child;
247 return 0;
250 void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
252 assert(!bdrv_dirty_bitmap_frozen(bitmap));
253 bitmap->disabled = false;
256 /* Called with BQL taken. */
257 void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
259 assert(bitmap->mutex == bitmap->successor->mutex);
260 qemu_mutex_lock(bitmap->mutex);
261 bdrv_enable_dirty_bitmap_locked(bitmap->successor);
262 qemu_mutex_unlock(bitmap->mutex);
265 /* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */
266 static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
268 assert(!bitmap->active_iterators);
269 assert(!bdrv_dirty_bitmap_frozen(bitmap));
270 assert(!bitmap->meta);
271 QLIST_REMOVE(bitmap, list);
272 hbitmap_free(bitmap->bitmap);
273 g_free(bitmap->name);
274 g_free(bitmap);
278 * For a bitmap with a successor, yield our name to the successor,
279 * delete the old bitmap, and return a handle to the new bitmap.
280 * Called with BQL taken.
282 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
283 BdrvDirtyBitmap *bitmap,
284 Error **errp)
286 char *name;
287 BdrvDirtyBitmap *successor = bitmap->successor;
289 if (successor == NULL) {
290 error_setg(errp, "Cannot relinquish control if "
291 "there's no successor present");
292 return NULL;
295 name = bitmap->name;
296 bitmap->name = NULL;
297 successor->name = name;
298 bitmap->successor = NULL;
299 successor->persistent = bitmap->persistent;
300 bitmap->persistent = false;
301 bdrv_release_dirty_bitmap(bs, bitmap);
303 return successor;
307 * In cases of failure where we can no longer safely delete the parent,
308 * we may wish to re-join the parent and child/successor.
309 * The merged parent will be un-frozen, but not explicitly re-enabled.
310 * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
312 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
313 BdrvDirtyBitmap *parent,
314 Error **errp)
316 BdrvDirtyBitmap *successor = parent->successor;
318 if (!successor) {
319 error_setg(errp, "Cannot reclaim a successor when none is present");
320 return NULL;
323 if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
324 error_setg(errp, "Merging of parent and successor bitmap failed");
325 return NULL;
327 bdrv_release_dirty_bitmap_locked(successor);
328 parent->successor = NULL;
330 return parent;
333 /* Called with BQL taken. */
334 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
335 BdrvDirtyBitmap *parent,
336 Error **errp)
338 BdrvDirtyBitmap *ret;
340 qemu_mutex_lock(parent->mutex);
341 ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp);
342 qemu_mutex_unlock(parent->mutex);
344 return ret;
348 * Truncates _all_ bitmaps attached to a BDS.
349 * Called with BQL taken.
351 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
353 BdrvDirtyBitmap *bitmap;
355 bdrv_dirty_bitmaps_lock(bs);
356 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
357 assert(!bdrv_dirty_bitmap_frozen(bitmap));
358 assert(!bitmap->active_iterators);
359 hbitmap_truncate(bitmap->bitmap, bytes);
360 bitmap->size = bytes;
362 bdrv_dirty_bitmaps_unlock(bs);
365 /* Called with BQL taken. */
366 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
368 bdrv_dirty_bitmaps_lock(bs);
369 bdrv_release_dirty_bitmap_locked(bitmap);
370 bdrv_dirty_bitmaps_unlock(bs);
374 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
375 * There must not be any frozen bitmaps attached.
376 * This function does not remove persistent bitmaps from the storage.
377 * Called with BQL taken.
379 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
381 BdrvDirtyBitmap *bm, *next;
383 bdrv_dirty_bitmaps_lock(bs);
384 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
385 if (bdrv_dirty_bitmap_name(bm)) {
386 bdrv_release_dirty_bitmap_locked(bm);
389 bdrv_dirty_bitmaps_unlock(bs);
393 * Release all persistent dirty bitmaps attached to a BDS (for use in
394 * bdrv_inactivate_recurse()).
395 * There must not be any frozen bitmaps attached.
396 * This function does not remove persistent bitmaps from the storage.
397 * Called with BQL taken.
399 void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
401 BdrvDirtyBitmap *bm, *next;
403 bdrv_dirty_bitmaps_lock(bs);
404 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
405 if (bdrv_dirty_bitmap_get_persistance(bm)) {
406 bdrv_release_dirty_bitmap_locked(bm);
409 bdrv_dirty_bitmaps_unlock(bs);
413 * Remove persistent dirty bitmap from the storage if it exists.
414 * Absence of bitmap is not an error, because we have the following scenario:
415 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
416 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
417 * not fail.
418 * This function doesn't release corresponding BdrvDirtyBitmap.
420 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
421 const char *name,
422 Error **errp)
424 if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
425 bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
429 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
431 bdrv_dirty_bitmap_lock(bitmap);
432 assert(!bdrv_dirty_bitmap_frozen(bitmap));
433 bitmap->disabled = true;
434 bdrv_dirty_bitmap_unlock(bitmap);
437 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
439 bdrv_dirty_bitmap_lock(bitmap);
440 bdrv_enable_dirty_bitmap_locked(bitmap);
441 bdrv_dirty_bitmap_unlock(bitmap);
444 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
446 BdrvDirtyBitmap *bm;
447 BlockDirtyInfoList *list = NULL;
448 BlockDirtyInfoList **plist = &list;
450 bdrv_dirty_bitmaps_lock(bs);
451 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
452 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
453 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
454 info->count = bdrv_get_dirty_count(bm);
455 info->granularity = bdrv_dirty_bitmap_granularity(bm);
456 info->has_name = !!bm->name;
457 info->name = g_strdup(bm->name);
458 info->status = bdrv_dirty_bitmap_status(bm);
459 entry->value = info;
460 *plist = entry;
461 plist = &entry->next;
463 bdrv_dirty_bitmaps_unlock(bs);
465 return list;
468 /* Called within bdrv_dirty_bitmap_lock..unlock */
469 bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
470 int64_t offset)
472 if (bitmap) {
473 return hbitmap_get(bitmap->bitmap, offset);
474 } else {
475 return false;
480 * Chooses a default granularity based on the existing cluster size,
481 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
482 * is no cluster size information available.
484 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
486 BlockDriverInfo bdi;
487 uint32_t granularity;
489 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
490 granularity = MAX(4096, bdi.cluster_size);
491 granularity = MIN(65536, granularity);
492 } else {
493 granularity = 65536;
496 return granularity;
499 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
501 return 1U << hbitmap_granularity(bitmap->bitmap);
504 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
506 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
507 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
508 iter->bitmap = bitmap;
509 bitmap->active_iterators++;
510 return iter;
513 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
515 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
516 hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
517 iter->bitmap = bitmap;
518 bitmap->active_iterators++;
519 return iter;
522 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
524 if (!iter) {
525 return;
527 assert(iter->bitmap->active_iterators > 0);
528 iter->bitmap->active_iterators--;
529 g_free(iter);
532 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
534 return hbitmap_iter_next(&iter->hbi, true);
538 * Return the next consecutively dirty area in the dirty bitmap
539 * belonging to the given iterator @iter.
541 * @max_offset: Maximum value that may be returned for
542 * *offset + *bytes
543 * @offset: Will contain the start offset of the next dirty area
544 * @bytes: Will contain the length of the next dirty area
546 * Returns: True if a dirty area could be found before max_offset
547 * (which means that *offset and *bytes then contain valid
548 * values), false otherwise.
550 * Note that @iter is never advanced if false is returned. If an area
551 * is found (which means that true is returned), it will be advanced
552 * past that area.
554 bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset,
555 uint64_t *offset, int *bytes)
557 uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap);
558 uint64_t gran_max_offset;
559 int64_t ret;
560 int size;
562 if (max_offset == iter->bitmap->size) {
563 /* If max_offset points to the image end, round it up by the
564 * bitmap granularity */
565 gran_max_offset = ROUND_UP(max_offset, granularity);
566 } else {
567 gran_max_offset = max_offset;
570 ret = hbitmap_iter_next(&iter->hbi, false);
571 if (ret < 0 || ret + granularity > gran_max_offset) {
572 return false;
575 *offset = ret;
576 size = 0;
578 assert(granularity <= INT_MAX);
580 do {
581 /* Advance iterator */
582 ret = hbitmap_iter_next(&iter->hbi, true);
583 size += granularity;
584 } while (ret + granularity <= gran_max_offset &&
585 hbitmap_iter_next(&iter->hbi, false) == ret + granularity &&
586 size <= INT_MAX - granularity);
588 *bytes = MIN(size, max_offset - *offset);
589 return true;
592 /* Called within bdrv_dirty_bitmap_lock..unlock */
593 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
594 int64_t offset, int64_t bytes)
596 assert(bdrv_dirty_bitmap_enabled(bitmap));
597 assert(!bdrv_dirty_bitmap_readonly(bitmap));
598 hbitmap_set(bitmap->bitmap, offset, bytes);
601 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
602 int64_t offset, int64_t bytes)
604 bdrv_dirty_bitmap_lock(bitmap);
605 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
606 bdrv_dirty_bitmap_unlock(bitmap);
609 /* Called within bdrv_dirty_bitmap_lock..unlock */
610 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
611 int64_t offset, int64_t bytes)
613 assert(bdrv_dirty_bitmap_enabled(bitmap));
614 assert(!bdrv_dirty_bitmap_readonly(bitmap));
615 hbitmap_reset(bitmap->bitmap, offset, bytes);
618 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
619 int64_t offset, int64_t bytes)
621 bdrv_dirty_bitmap_lock(bitmap);
622 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
623 bdrv_dirty_bitmap_unlock(bitmap);
626 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
628 assert(bdrv_dirty_bitmap_enabled(bitmap));
629 assert(!bdrv_dirty_bitmap_readonly(bitmap));
630 bdrv_dirty_bitmap_lock(bitmap);
631 if (!out) {
632 hbitmap_reset_all(bitmap->bitmap);
633 } else {
634 HBitmap *backup = bitmap->bitmap;
635 bitmap->bitmap = hbitmap_alloc(bitmap->size,
636 hbitmap_granularity(backup));
637 *out = backup;
639 bdrv_dirty_bitmap_unlock(bitmap);
642 void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
644 HBitmap *tmp = bitmap->bitmap;
645 assert(bdrv_dirty_bitmap_enabled(bitmap));
646 assert(!bdrv_dirty_bitmap_readonly(bitmap));
647 bitmap->bitmap = backup;
648 hbitmap_free(tmp);
651 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
652 uint64_t offset, uint64_t bytes)
654 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
657 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
659 return hbitmap_serialization_align(bitmap->bitmap);
662 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
663 uint8_t *buf, uint64_t offset,
664 uint64_t bytes)
666 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
669 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
670 uint8_t *buf, uint64_t offset,
671 uint64_t bytes, bool finish)
673 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
676 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
677 uint64_t offset, uint64_t bytes,
678 bool finish)
680 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
683 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
684 uint64_t offset, uint64_t bytes,
685 bool finish)
687 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
690 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
692 hbitmap_deserialize_finish(bitmap->bitmap);
695 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
697 BdrvDirtyBitmap *bitmap;
699 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
700 return;
703 bdrv_dirty_bitmaps_lock(bs);
704 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
705 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
706 continue;
708 assert(!bdrv_dirty_bitmap_readonly(bitmap));
709 hbitmap_set(bitmap->bitmap, offset, bytes);
711 bdrv_dirty_bitmaps_unlock(bs);
715 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
717 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
719 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
722 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
724 return hbitmap_count(bitmap->bitmap);
727 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
729 return hbitmap_count(bitmap->meta);
732 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
734 return bitmap->readonly;
737 /* Called with BQL taken. */
738 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
740 qemu_mutex_lock(bitmap->mutex);
741 bitmap->readonly = value;
742 qemu_mutex_unlock(bitmap->mutex);
745 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
747 BdrvDirtyBitmap *bm;
748 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
749 if (bm->readonly) {
750 return true;
754 return false;
757 /* Called with BQL taken. */
758 void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
760 qemu_mutex_lock(bitmap->mutex);
761 bitmap->persistent = persistent;
762 qemu_mutex_unlock(bitmap->mutex);
765 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
767 return bitmap->persistent;
770 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
772 BdrvDirtyBitmap *bm;
773 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
774 if (bm->persistent && !bm->readonly) {
775 return true;
779 return false;
782 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
783 BdrvDirtyBitmap *bitmap)
785 return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
786 QLIST_NEXT(bitmap, list);
789 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
791 return hbitmap_sha256(bitmap->bitmap, errp);
794 int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
796 return hbitmap_next_zero(bitmap->bitmap, offset);
799 void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
800 HBitmap **backup, Error **errp)
802 bool ret;
804 /* only bitmaps from one bds are supported */
805 assert(dest->mutex == src->mutex);
807 qemu_mutex_lock(dest->mutex);
809 if (bdrv_dirty_bitmap_frozen(dest)) {
810 error_setg(errp, "Bitmap '%s' is frozen and cannot be modified",
811 dest->name);
812 goto out;
815 if (bdrv_dirty_bitmap_readonly(dest)) {
816 error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
817 dest->name);
818 goto out;
821 if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
822 error_setg(errp, "Bitmaps are incompatible and can't be merged");
823 goto out;
826 if (backup) {
827 *backup = dest->bitmap;
828 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
829 ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
830 } else {
831 ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
833 assert(ret);
835 out:
836 qemu_mutex_unlock(dest->mutex);