]> git.proxmox.com Git - mirror_qemu.git/blob - block/dirty-bitmap.c
block/dirty-bitmap: Documentation and Comment fixups
[mirror_qemu.git] / block / dirty-bitmap.c
1 /*
2 * Block Dirty Bitmap
3 *
4 * Copyright (c) 2016-2017 Red Hat. Inc
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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.
23 */
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"
30
31 /**
32 * A BdrvDirtyBitmap can be in four possible user-visible states:
33 * (1) Active: successor is NULL, and disabled is false: full r/w mode
34 * (2) Disabled: successor is NULL, and disabled is true: qualified r/w mode,
35 * guest writes are dropped, but monitor writes are possible,
36 * through commands like merge and clear.
37 * (3) Frozen: successor is not NULL.
38 * A frozen bitmap cannot be renamed, deleted, cleared, set,
39 * enabled, merged to, etc. A frozen bitmap can only abdicate()
40 * or reclaim().
41 * In this state, the anonymous successor bitmap may be either
42 * Active and recording writes from the guest (e.g. backup jobs),
43 * but it can be Disabled and not recording writes.
44 * (4) Locked: Whether Active or Disabled, the user cannot modify this bitmap
45 * in any way from the monitor.
46 */
47 struct BdrvDirtyBitmap {
48 QemuMutex *mutex;
49 HBitmap *bitmap; /* Dirty bitmap implementation */
50 HBitmap *meta; /* Meta dirty bitmap */
51 bool qmp_locked; /* Bitmap is locked, it can't be modified
52 through QMP */
53 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
54 char *name; /* Optional non-empty unique ID */
55 int64_t size; /* Size of the bitmap, in bytes */
56 bool disabled; /* Bitmap is disabled. It ignores all writes to
57 the device */
58 int active_iterators; /* How many iterators are active */
59 bool readonly; /* Bitmap is read-only. This field also
60 prevents the respective image from being
61 modified (i.e. blocks writes and discards).
62 Such operations must fail and both the image
63 and this bitmap must remain unchanged while
64 this flag is set. */
65 bool persistent; /* bitmap must be saved to owner disk image */
66 bool migration; /* Bitmap is selected for migration, it should
67 not be stored on the next inactivation
68 (persistent flag doesn't matter until next
69 invalidation).*/
70 QLIST_ENTRY(BdrvDirtyBitmap) list;
71 };
72
73 struct BdrvDirtyBitmapIter {
74 HBitmapIter hbi;
75 BdrvDirtyBitmap *bitmap;
76 };
77
78 static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
79 {
80 qemu_mutex_lock(&bs->dirty_bitmap_mutex);
81 }
82
83 static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
84 {
85 qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
86 }
87
88 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
89 {
90 qemu_mutex_lock(bitmap->mutex);
91 }
92
93 void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
94 {
95 qemu_mutex_unlock(bitmap->mutex);
96 }
97
98 /* Called with BQL or dirty_bitmap lock taken. */
99 BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
100 {
101 BdrvDirtyBitmap *bm;
102
103 assert(name);
104 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
105 if (bm->name && !strcmp(name, bm->name)) {
106 return bm;
107 }
108 }
109 return NULL;
110 }
111
112 /* Called with BQL taken. */
113 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
114 uint32_t granularity,
115 const char *name,
116 Error **errp)
117 {
118 int64_t bitmap_size;
119 BdrvDirtyBitmap *bitmap;
120
121 assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
122
123 if (name && bdrv_find_dirty_bitmap(bs, name)) {
124 error_setg(errp, "Bitmap already exists: %s", name);
125 return NULL;
126 }
127 bitmap_size = bdrv_getlength(bs);
128 if (bitmap_size < 0) {
129 error_setg_errno(errp, -bitmap_size, "could not get length of device");
130 errno = -bitmap_size;
131 return NULL;
132 }
133 bitmap = g_new0(BdrvDirtyBitmap, 1);
134 bitmap->mutex = &bs->dirty_bitmap_mutex;
135 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
136 bitmap->size = bitmap_size;
137 bitmap->name = g_strdup(name);
138 bitmap->disabled = false;
139 bdrv_dirty_bitmaps_lock(bs);
140 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
141 bdrv_dirty_bitmaps_unlock(bs);
142 return bitmap;
143 }
144
145 /* bdrv_create_meta_dirty_bitmap
146 *
147 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
148 * when a dirty status bit in @bitmap is changed (either from reset to set or
149 * the other way around), its respective meta dirty bitmap bit will be marked
150 * dirty as well.
151 *
152 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
153 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
154 * track.
155 */
156 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
157 int chunk_size)
158 {
159 assert(!bitmap->meta);
160 qemu_mutex_lock(bitmap->mutex);
161 bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
162 chunk_size * BITS_PER_BYTE);
163 qemu_mutex_unlock(bitmap->mutex);
164 }
165
166 void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
167 {
168 assert(bitmap->meta);
169 qemu_mutex_lock(bitmap->mutex);
170 hbitmap_free_meta(bitmap->bitmap);
171 bitmap->meta = NULL;
172 qemu_mutex_unlock(bitmap->mutex);
173 }
174
175 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
176 {
177 return bitmap->size;
178 }
179
180 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
181 {
182 return bitmap->name;
183 }
184
185 /* Called with BQL taken. */
186 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
187 {
188 return bitmap->successor;
189 }
190
191 /* Both conditions disallow user-modification via QMP. */
192 bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap) {
193 return bdrv_dirty_bitmap_frozen(bitmap) ||
194 bdrv_dirty_bitmap_qmp_locked(bitmap);
195 }
196
197 void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked)
198 {
199 qemu_mutex_lock(bitmap->mutex);
200 bitmap->qmp_locked = qmp_locked;
201 qemu_mutex_unlock(bitmap->mutex);
202 }
203
204 bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap)
205 {
206 return bitmap->qmp_locked;
207 }
208
209 /* Called with BQL taken. */
210 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
211 {
212 return !(bitmap->disabled || bitmap->successor);
213 }
214
215 /* Called with BQL taken. */
216 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
217 {
218 if (bdrv_dirty_bitmap_frozen(bitmap)) {
219 return DIRTY_BITMAP_STATUS_FROZEN;
220 } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) {
221 return DIRTY_BITMAP_STATUS_LOCKED;
222 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
223 return DIRTY_BITMAP_STATUS_DISABLED;
224 } else {
225 return DIRTY_BITMAP_STATUS_ACTIVE;
226 }
227 }
228
229 /**
230 * Create a successor bitmap destined to replace this bitmap after an operation.
231 * Requires that the bitmap is not frozen and has no successor.
232 * Called with BQL taken.
233 */
234 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
235 BdrvDirtyBitmap *bitmap, Error **errp)
236 {
237 uint64_t granularity;
238 BdrvDirtyBitmap *child;
239
240 if (bdrv_dirty_bitmap_frozen(bitmap)) {
241 error_setg(errp, "Cannot create a successor for a bitmap that is "
242 "currently frozen");
243 return -1;
244 }
245 assert(!bitmap->successor);
246
247 /* Create an anonymous successor */
248 granularity = bdrv_dirty_bitmap_granularity(bitmap);
249 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
250 if (!child) {
251 return -1;
252 }
253
254 /* Successor will be on or off based on our current state. */
255 child->disabled = bitmap->disabled;
256
257 /* Install the successor and freeze the parent */
258 bitmap->successor = child;
259 return 0;
260 }
261
262 void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
263 {
264 assert(!bdrv_dirty_bitmap_frozen(bitmap));
265 bitmap->disabled = false;
266 }
267
268 /* Called with BQL taken. */
269 void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
270 {
271 assert(bitmap->mutex == bitmap->successor->mutex);
272 qemu_mutex_lock(bitmap->mutex);
273 bdrv_enable_dirty_bitmap_locked(bitmap->successor);
274 qemu_mutex_unlock(bitmap->mutex);
275 }
276
277 /* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */
278 static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
279 {
280 assert(!bitmap->active_iterators);
281 assert(!bdrv_dirty_bitmap_frozen(bitmap));
282 assert(!bitmap->meta);
283 QLIST_REMOVE(bitmap, list);
284 hbitmap_free(bitmap->bitmap);
285 g_free(bitmap->name);
286 g_free(bitmap);
287 }
288
289 /**
290 * For a bitmap with a successor, yield our name to the successor,
291 * delete the old bitmap, and return a handle to the new bitmap.
292 * Called with BQL taken.
293 */
294 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
295 BdrvDirtyBitmap *bitmap,
296 Error **errp)
297 {
298 char *name;
299 BdrvDirtyBitmap *successor = bitmap->successor;
300
301 if (successor == NULL) {
302 error_setg(errp, "Cannot relinquish control if "
303 "there's no successor present");
304 return NULL;
305 }
306
307 name = bitmap->name;
308 bitmap->name = NULL;
309 successor->name = name;
310 bitmap->successor = NULL;
311 successor->persistent = bitmap->persistent;
312 bitmap->persistent = false;
313 bdrv_release_dirty_bitmap(bs, bitmap);
314
315 return successor;
316 }
317
318 /**
319 * In cases of failure where we can no longer safely delete the parent,
320 * we may wish to re-join the parent and child/successor.
321 * The merged parent will be un-frozen, but not explicitly re-enabled.
322 * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
323 */
324 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
325 BdrvDirtyBitmap *parent,
326 Error **errp)
327 {
328 BdrvDirtyBitmap *successor = parent->successor;
329
330 if (!successor) {
331 error_setg(errp, "Cannot reclaim a successor when none is present");
332 return NULL;
333 }
334
335 if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
336 error_setg(errp, "Merging of parent and successor bitmap failed");
337 return NULL;
338 }
339 bdrv_release_dirty_bitmap_locked(successor);
340 parent->successor = NULL;
341
342 return parent;
343 }
344
345 /* Called with BQL taken. */
346 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
347 BdrvDirtyBitmap *parent,
348 Error **errp)
349 {
350 BdrvDirtyBitmap *ret;
351
352 qemu_mutex_lock(parent->mutex);
353 ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp);
354 qemu_mutex_unlock(parent->mutex);
355
356 return ret;
357 }
358
359 /**
360 * Truncates _all_ bitmaps attached to a BDS.
361 * Called with BQL taken.
362 */
363 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
364 {
365 BdrvDirtyBitmap *bitmap;
366
367 bdrv_dirty_bitmaps_lock(bs);
368 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
369 assert(!bdrv_dirty_bitmap_frozen(bitmap));
370 assert(!bitmap->active_iterators);
371 hbitmap_truncate(bitmap->bitmap, bytes);
372 bitmap->size = bytes;
373 }
374 bdrv_dirty_bitmaps_unlock(bs);
375 }
376
377 /* Called with BQL taken. */
378 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
379 {
380 bdrv_dirty_bitmaps_lock(bs);
381 bdrv_release_dirty_bitmap_locked(bitmap);
382 bdrv_dirty_bitmaps_unlock(bs);
383 }
384
385 /**
386 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
387 * There must not be any frozen bitmaps attached.
388 * This function does not remove persistent bitmaps from the storage.
389 * Called with BQL taken.
390 */
391 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
392 {
393 BdrvDirtyBitmap *bm, *next;
394
395 bdrv_dirty_bitmaps_lock(bs);
396 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
397 if (bdrv_dirty_bitmap_name(bm)) {
398 bdrv_release_dirty_bitmap_locked(bm);
399 }
400 }
401 bdrv_dirty_bitmaps_unlock(bs);
402 }
403
404 /**
405 * Remove persistent dirty bitmap from the storage if it exists.
406 * Absence of bitmap is not an error, because we have the following scenario:
407 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
408 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
409 * not fail.
410 * This function doesn't release corresponding BdrvDirtyBitmap.
411 */
412 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
413 const char *name,
414 Error **errp)
415 {
416 if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
417 bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
418 }
419 }
420
421 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
422 {
423 bdrv_dirty_bitmap_lock(bitmap);
424 assert(!bdrv_dirty_bitmap_frozen(bitmap));
425 bitmap->disabled = true;
426 bdrv_dirty_bitmap_unlock(bitmap);
427 }
428
429 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
430 {
431 bdrv_dirty_bitmap_lock(bitmap);
432 bdrv_enable_dirty_bitmap_locked(bitmap);
433 bdrv_dirty_bitmap_unlock(bitmap);
434 }
435
436 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
437 {
438 BdrvDirtyBitmap *bm;
439 BlockDirtyInfoList *list = NULL;
440 BlockDirtyInfoList **plist = &list;
441
442 bdrv_dirty_bitmaps_lock(bs);
443 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
444 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
445 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
446 info->count = bdrv_get_dirty_count(bm);
447 info->granularity = bdrv_dirty_bitmap_granularity(bm);
448 info->has_name = !!bm->name;
449 info->name = g_strdup(bm->name);
450 info->status = bdrv_dirty_bitmap_status(bm);
451 info->persistent = bm->persistent;
452 entry->value = info;
453 *plist = entry;
454 plist = &entry->next;
455 }
456 bdrv_dirty_bitmaps_unlock(bs);
457
458 return list;
459 }
460
461 /* Called within bdrv_dirty_bitmap_lock..unlock */
462 bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
463 int64_t offset)
464 {
465 if (bitmap) {
466 return hbitmap_get(bitmap->bitmap, offset);
467 } else {
468 return false;
469 }
470 }
471
472 /**
473 * Chooses a default granularity based on the existing cluster size,
474 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
475 * is no cluster size information available.
476 */
477 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
478 {
479 BlockDriverInfo bdi;
480 uint32_t granularity;
481
482 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
483 granularity = MAX(4096, bdi.cluster_size);
484 granularity = MIN(65536, granularity);
485 } else {
486 granularity = 65536;
487 }
488
489 return granularity;
490 }
491
492 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
493 {
494 return 1U << hbitmap_granularity(bitmap->bitmap);
495 }
496
497 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
498 {
499 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
500 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
501 iter->bitmap = bitmap;
502 bitmap->active_iterators++;
503 return iter;
504 }
505
506 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
507 {
508 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
509 hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
510 iter->bitmap = bitmap;
511 bitmap->active_iterators++;
512 return iter;
513 }
514
515 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
516 {
517 if (!iter) {
518 return;
519 }
520 assert(iter->bitmap->active_iterators > 0);
521 iter->bitmap->active_iterators--;
522 g_free(iter);
523 }
524
525 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
526 {
527 return hbitmap_iter_next(&iter->hbi);
528 }
529
530 /* Called within bdrv_dirty_bitmap_lock..unlock */
531 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
532 int64_t offset, int64_t bytes)
533 {
534 assert(bdrv_dirty_bitmap_enabled(bitmap));
535 assert(!bdrv_dirty_bitmap_readonly(bitmap));
536 hbitmap_set(bitmap->bitmap, offset, bytes);
537 }
538
539 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
540 int64_t offset, int64_t bytes)
541 {
542 bdrv_dirty_bitmap_lock(bitmap);
543 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
544 bdrv_dirty_bitmap_unlock(bitmap);
545 }
546
547 /* Called within bdrv_dirty_bitmap_lock..unlock */
548 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
549 int64_t offset, int64_t bytes)
550 {
551 assert(bdrv_dirty_bitmap_enabled(bitmap));
552 assert(!bdrv_dirty_bitmap_readonly(bitmap));
553 hbitmap_reset(bitmap->bitmap, offset, bytes);
554 }
555
556 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
557 int64_t offset, int64_t bytes)
558 {
559 bdrv_dirty_bitmap_lock(bitmap);
560 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
561 bdrv_dirty_bitmap_unlock(bitmap);
562 }
563
564 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
565 {
566 assert(!bdrv_dirty_bitmap_readonly(bitmap));
567 bdrv_dirty_bitmap_lock(bitmap);
568 if (!out) {
569 hbitmap_reset_all(bitmap->bitmap);
570 } else {
571 HBitmap *backup = bitmap->bitmap;
572 bitmap->bitmap = hbitmap_alloc(bitmap->size,
573 hbitmap_granularity(backup));
574 *out = backup;
575 }
576 bdrv_dirty_bitmap_unlock(bitmap);
577 }
578
579 void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
580 {
581 HBitmap *tmp = bitmap->bitmap;
582 assert(!bdrv_dirty_bitmap_readonly(bitmap));
583 bitmap->bitmap = backup;
584 hbitmap_free(tmp);
585 }
586
587 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
588 uint64_t offset, uint64_t bytes)
589 {
590 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
591 }
592
593 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
594 {
595 return hbitmap_serialization_align(bitmap->bitmap);
596 }
597
598 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
599 uint8_t *buf, uint64_t offset,
600 uint64_t bytes)
601 {
602 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
603 }
604
605 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
606 uint8_t *buf, uint64_t offset,
607 uint64_t bytes, bool finish)
608 {
609 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
610 }
611
612 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
613 uint64_t offset, uint64_t bytes,
614 bool finish)
615 {
616 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
617 }
618
619 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
620 uint64_t offset, uint64_t bytes,
621 bool finish)
622 {
623 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
624 }
625
626 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
627 {
628 hbitmap_deserialize_finish(bitmap->bitmap);
629 }
630
631 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
632 {
633 BdrvDirtyBitmap *bitmap;
634
635 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
636 return;
637 }
638
639 bdrv_dirty_bitmaps_lock(bs);
640 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
641 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
642 continue;
643 }
644 assert(!bdrv_dirty_bitmap_readonly(bitmap));
645 hbitmap_set(bitmap->bitmap, offset, bytes);
646 }
647 bdrv_dirty_bitmaps_unlock(bs);
648 }
649
650 /**
651 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
652 */
653 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
654 {
655 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
656 }
657
658 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
659 {
660 return hbitmap_count(bitmap->bitmap);
661 }
662
663 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
664 {
665 return hbitmap_count(bitmap->meta);
666 }
667
668 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
669 {
670 return bitmap->readonly;
671 }
672
673 /* Called with BQL taken. */
674 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
675 {
676 qemu_mutex_lock(bitmap->mutex);
677 bitmap->readonly = value;
678 qemu_mutex_unlock(bitmap->mutex);
679 }
680
681 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
682 {
683 BdrvDirtyBitmap *bm;
684 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
685 if (bm->readonly) {
686 return true;
687 }
688 }
689
690 return false;
691 }
692
693 /* Called with BQL taken. */
694 void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
695 {
696 qemu_mutex_lock(bitmap->mutex);
697 bitmap->persistent = persistent;
698 qemu_mutex_unlock(bitmap->mutex);
699 }
700
701 /* Called with BQL taken. */
702 void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration)
703 {
704 qemu_mutex_lock(bitmap->mutex);
705 bitmap->migration = migration;
706 qemu_mutex_unlock(bitmap->mutex);
707 }
708
709 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
710 {
711 return bitmap->persistent && !bitmap->migration;
712 }
713
714 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
715 {
716 BdrvDirtyBitmap *bm;
717 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
718 if (bm->persistent && !bm->readonly && !bm->migration) {
719 return true;
720 }
721 }
722
723 return false;
724 }
725
726 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
727 BdrvDirtyBitmap *bitmap)
728 {
729 return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
730 QLIST_NEXT(bitmap, list);
731 }
732
733 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
734 {
735 return hbitmap_sha256(bitmap->bitmap, errp);
736 }
737
738 int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
739 uint64_t bytes)
740 {
741 return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
742 }
743
744 bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
745 uint64_t *offset, uint64_t *bytes)
746 {
747 return hbitmap_next_dirty_area(bitmap->bitmap, offset, bytes);
748 }
749
750 void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
751 HBitmap **backup, Error **errp)
752 {
753 bool ret;
754
755 /* only bitmaps from one bds are supported */
756 assert(dest->mutex == src->mutex);
757
758 qemu_mutex_lock(dest->mutex);
759
760 if (bdrv_dirty_bitmap_user_locked(dest)) {
761 error_setg(errp, "Bitmap '%s' is currently in use by another"
762 " operation and cannot be modified", dest->name);
763 goto out;
764 }
765
766 if (bdrv_dirty_bitmap_readonly(dest)) {
767 error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
768 dest->name);
769 goto out;
770 }
771
772 if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
773 error_setg(errp, "Bitmaps are incompatible and can't be merged");
774 goto out;
775 }
776
777 if (backup) {
778 *backup = dest->bitmap;
779 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
780 ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
781 } else {
782 ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
783 }
784 assert(ret);
785
786 out:
787 qemu_mutex_unlock(dest->mutex);
788 }