xref: /openbmc/qemu/block/dirty-bitmap.c (revision 2cfb3b6c)
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 "trace.h"
27 #include "block/block-io.h"
28 #include "block/block_int.h"
29 #include "block/blockjob.h"
30 #include "block/dirty-bitmap.h"
31 #include "qemu/main-loop.h"
32 
33 struct BdrvDirtyBitmap {
34     BlockDriverState *bs;
35     HBitmap *bitmap;            /* Dirty bitmap implementation */
36     bool busy;                  /* Bitmap is busy, it can't be used via QMP */
37     BdrvDirtyBitmap *successor; /* Anonymous child, if any. */
38     char *name;                 /* Optional non-empty unique ID */
39     int64_t size;               /* Size of the bitmap, in bytes */
40     bool disabled;              /* Bitmap is disabled. It ignores all writes to
41                                    the device */
42     int active_iterators;       /* How many iterators are active */
43     bool readonly;              /* Bitmap is read-only. This field also
44                                    prevents the respective image from being
45                                    modified (i.e. blocks writes and discards).
46                                    Such operations must fail and both the image
47                                    and this bitmap must remain unchanged while
48                                    this flag is set. */
49     bool persistent;            /* bitmap must be saved to owner disk image */
50     bool inconsistent;          /* bitmap is persistent, but inconsistent.
51                                    It cannot be used at all in any way, except
52                                    a QMP user can remove it. */
53     bool skip_store;            /* We are either migrating or deleting this
54                                  * bitmap; it should not be stored on the next
55                                  * inactivation. */
56     QLIST_ENTRY(BdrvDirtyBitmap) list;
57 };
58 
59 struct BdrvDirtyBitmapIter {
60     HBitmapIter hbi;
61     BdrvDirtyBitmap *bitmap;
62 };
63 
64 static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
65 {
66     qemu_mutex_lock(&bs->dirty_bitmap_mutex);
67 }
68 
69 static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
70 {
71     qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
72 }
73 
74 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
75 {
76     bdrv_dirty_bitmaps_lock(bitmap->bs);
77 }
78 
79 void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
80 {
81     bdrv_dirty_bitmaps_unlock(bitmap->bs);
82 }
83 
84 /* Called with BQL or dirty_bitmap lock taken.  */
85 BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
86 {
87     BdrvDirtyBitmap *bm;
88 
89     assert(name);
90     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
91         if (bm->name && !strcmp(name, bm->name)) {
92             return bm;
93         }
94     }
95     return NULL;
96 }
97 
98 /* Called with BQL taken.  */
99 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
100                                           uint32_t granularity,
101                                           const char *name,
102                                           Error **errp)
103 {
104     int64_t bitmap_size;
105     BdrvDirtyBitmap *bitmap;
106 
107     assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
108 
109     if (name) {
110         if (bdrv_find_dirty_bitmap(bs, name)) {
111             error_setg(errp, "Bitmap already exists: %s", name);
112             return NULL;
113         }
114         if (strlen(name) > BDRV_BITMAP_MAX_NAME_SIZE) {
115             error_setg(errp, "Bitmap name too long: %s", name);
116             return NULL;
117         }
118     }
119     bitmap_size = bdrv_getlength(bs);
120     if (bitmap_size < 0) {
121         error_setg_errno(errp, -bitmap_size, "could not get length of device");
122         errno = -bitmap_size;
123         return NULL;
124     }
125     bitmap = g_new0(BdrvDirtyBitmap, 1);
126     bitmap->bs = bs;
127     bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
128     bitmap->size = bitmap_size;
129     bitmap->name = g_strdup(name);
130     bitmap->disabled = false;
131     bdrv_dirty_bitmaps_lock(bs);
132     QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
133     bdrv_dirty_bitmaps_unlock(bs);
134     return bitmap;
135 }
136 
137 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
138 {
139     return bitmap->size;
140 }
141 
142 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
143 {
144     return bitmap->name;
145 }
146 
147 /* Called with BQL taken.  */
148 bool bdrv_dirty_bitmap_has_successor(BdrvDirtyBitmap *bitmap)
149 {
150     return bitmap->successor;
151 }
152 
153 static bool bdrv_dirty_bitmap_busy(const BdrvDirtyBitmap *bitmap)
154 {
155     return bitmap->busy;
156 }
157 
158 void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy)
159 {
160     bdrv_dirty_bitmaps_lock(bitmap->bs);
161     bitmap->busy = busy;
162     bdrv_dirty_bitmaps_unlock(bitmap->bs);
163 }
164 
165 /* Called with BQL taken.  */
166 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
167 {
168     return !bitmap->disabled;
169 }
170 
171 /* Called with BQL taken.  */
172 static bool bdrv_dirty_bitmap_recording(BdrvDirtyBitmap *bitmap)
173 {
174     return !bitmap->disabled || (bitmap->successor &&
175                                  !bitmap->successor->disabled);
176 }
177 
178 int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags,
179                             Error **errp)
180 {
181     if ((flags & BDRV_BITMAP_BUSY) && bdrv_dirty_bitmap_busy(bitmap)) {
182         error_setg(errp, "Bitmap '%s' is currently in use by another"
183                    " operation and cannot be used", bitmap->name);
184         return -1;
185     }
186 
187     if ((flags & BDRV_BITMAP_RO) && bdrv_dirty_bitmap_readonly(bitmap)) {
188         error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
189                    bitmap->name);
190         return -1;
191     }
192 
193     if ((flags & BDRV_BITMAP_INCONSISTENT) &&
194         bdrv_dirty_bitmap_inconsistent(bitmap)) {
195         error_setg(errp, "Bitmap '%s' is inconsistent and cannot be used",
196                    bitmap->name);
197         error_append_hint(errp, "Try block-dirty-bitmap-remove to delete"
198                           " this bitmap from disk\n");
199         return -1;
200     }
201 
202     return 0;
203 }
204 
205 /**
206  * Create a successor bitmap destined to replace this bitmap after an operation.
207  * Requires that the bitmap is not marked busy and has no successor.
208  * The successor will be enabled if the parent bitmap was.
209  * Called with BQL taken.
210  */
211 int bdrv_dirty_bitmap_create_successor(BdrvDirtyBitmap *bitmap, Error **errp)
212 {
213     uint64_t granularity;
214     BdrvDirtyBitmap *child;
215 
216     if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY, errp)) {
217         return -1;
218     }
219     if (bdrv_dirty_bitmap_has_successor(bitmap)) {
220         error_setg(errp, "Cannot create a successor for a bitmap that already "
221                    "has one");
222         return -1;
223     }
224 
225     /* Create an anonymous successor */
226     granularity = bdrv_dirty_bitmap_granularity(bitmap);
227     child = bdrv_create_dirty_bitmap(bitmap->bs, granularity, NULL, errp);
228     if (!child) {
229         return -1;
230     }
231 
232     /* Successor will be on or off based on our current state. */
233     child->disabled = bitmap->disabled;
234     bitmap->disabled = true;
235 
236     /* Install the successor and mark the parent as busy */
237     bitmap->successor = child;
238     bitmap->busy = true;
239     return 0;
240 }
241 
242 void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
243 {
244     bitmap->disabled = false;
245 }
246 
247 /* Called with BQL taken. */
248 void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
249 {
250     assert(bitmap->bs == bitmap->successor->bs);
251     bdrv_dirty_bitmaps_lock(bitmap->bs);
252     bdrv_enable_dirty_bitmap_locked(bitmap->successor);
253     bdrv_dirty_bitmaps_unlock(bitmap->bs);
254 }
255 
256 /* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.  */
257 static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
258 {
259     assert(!bitmap->active_iterators);
260     assert(!bdrv_dirty_bitmap_busy(bitmap));
261     assert(!bdrv_dirty_bitmap_has_successor(bitmap));
262     QLIST_REMOVE(bitmap, list);
263     hbitmap_free(bitmap->bitmap);
264     g_free(bitmap->name);
265     g_free(bitmap);
266 }
267 
268 /**
269  * For a bitmap with a successor, yield our name to the successor,
270  * delete the old bitmap, and return a handle to the new bitmap.
271  * Called with BQL taken.
272  */
273 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BdrvDirtyBitmap *bitmap,
274                                             Error **errp)
275 {
276     char *name;
277     BdrvDirtyBitmap *successor = bitmap->successor;
278 
279     if (successor == NULL) {
280         error_setg(errp, "Cannot relinquish control if "
281                    "there's no successor present");
282         return NULL;
283     }
284 
285     name = bitmap->name;
286     bitmap->name = NULL;
287     successor->name = name;
288     bitmap->successor = NULL;
289     successor->persistent = bitmap->persistent;
290     bitmap->persistent = false;
291     bitmap->busy = false;
292     bdrv_release_dirty_bitmap(bitmap);
293 
294     return successor;
295 }
296 
297 /**
298  * In cases of failure where we can no longer safely delete the parent,
299  * we may wish to re-join the parent and child/successor.
300  * The merged parent will be marked as not busy.
301  * The marged parent will be enabled if and only if the successor was enabled.
302  * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
303  */
304 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BdrvDirtyBitmap *parent,
305                                                   Error **errp)
306 {
307     BdrvDirtyBitmap *successor = parent->successor;
308 
309     if (!successor) {
310         error_setg(errp, "Cannot reclaim a successor when none is present");
311         return NULL;
312     }
313 
314     hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap);
315 
316     parent->disabled = successor->disabled;
317     parent->busy = false;
318     bdrv_release_dirty_bitmap_locked(successor);
319     parent->successor = NULL;
320 
321     return parent;
322 }
323 
324 /* Called with BQL taken. */
325 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BdrvDirtyBitmap *parent,
326                                            Error **errp)
327 {
328     BdrvDirtyBitmap *ret;
329 
330     bdrv_dirty_bitmaps_lock(parent->bs);
331     ret = bdrv_reclaim_dirty_bitmap_locked(parent, errp);
332     bdrv_dirty_bitmaps_unlock(parent->bs);
333 
334     return ret;
335 }
336 
337 /**
338  * Truncates _all_ bitmaps attached to a BDS.
339  * Called with BQL taken.
340  */
341 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
342 {
343     BdrvDirtyBitmap *bitmap;
344 
345     bdrv_dirty_bitmaps_lock(bs);
346     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
347         assert(!bdrv_dirty_bitmap_busy(bitmap));
348         assert(!bdrv_dirty_bitmap_has_successor(bitmap));
349         assert(!bitmap->active_iterators);
350         hbitmap_truncate(bitmap->bitmap, bytes);
351         bitmap->size = bytes;
352     }
353     bdrv_dirty_bitmaps_unlock(bs);
354 }
355 
356 /* Called with BQL taken.  */
357 void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap)
358 {
359     BlockDriverState *bs = bitmap->bs;
360 
361     bdrv_dirty_bitmaps_lock(bs);
362     bdrv_release_dirty_bitmap_locked(bitmap);
363     bdrv_dirty_bitmaps_unlock(bs);
364 }
365 
366 /**
367  * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
368  * There must not be any busy bitmaps attached.
369  * This function does not remove persistent bitmaps from the storage.
370  * Called with BQL taken.
371  */
372 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
373 {
374     BdrvDirtyBitmap *bm, *next;
375 
376     bdrv_dirty_bitmaps_lock(bs);
377     QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
378         if (bdrv_dirty_bitmap_name(bm)) {
379             bdrv_release_dirty_bitmap_locked(bm);
380         }
381     }
382     bdrv_dirty_bitmaps_unlock(bs);
383 }
384 
385 /**
386  * Remove persistent dirty bitmap from the storage if it exists.
387  * Absence of bitmap is not an error, because we have the following scenario:
388  * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
389  * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
390  * not fail.
391  * This function doesn't release corresponding BdrvDirtyBitmap.
392  */
393 int coroutine_fn
394 bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
395                                        Error **errp)
396 {
397     if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
398         return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
399     }
400 
401     return 0;
402 }
403 
404 bool
405 bdrv_supports_persistent_dirty_bitmap(BlockDriverState *bs)
406 {
407     if (bs->drv && bs->drv->bdrv_supports_persistent_dirty_bitmap) {
408         return bs->drv->bdrv_supports_persistent_dirty_bitmap(bs);
409     }
410     return false;
411 }
412 
413 bool coroutine_fn
414 bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
415                                    uint32_t granularity, Error **errp)
416 {
417     BlockDriver *drv = bs->drv;
418 
419     if (!drv) {
420         error_setg_errno(errp, ENOMEDIUM,
421                          "Can't store persistent bitmaps to %s",
422                          bdrv_get_device_or_node_name(bs));
423         return false;
424     }
425 
426     if (!drv->bdrv_co_can_store_new_dirty_bitmap) {
427         error_setg_errno(errp, ENOTSUP,
428                          "Can't store persistent bitmaps to %s",
429                          bdrv_get_device_or_node_name(bs));
430         return false;
431     }
432 
433     return drv->bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
434 }
435 
436 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
437 {
438     bdrv_dirty_bitmaps_lock(bitmap->bs);
439     bitmap->disabled = true;
440     bdrv_dirty_bitmaps_unlock(bitmap->bs);
441 }
442 
443 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
444 {
445     bdrv_dirty_bitmaps_lock(bitmap->bs);
446     bdrv_enable_dirty_bitmap_locked(bitmap);
447     bdrv_dirty_bitmaps_unlock(bitmap->bs);
448 }
449 
450 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
451 {
452     BdrvDirtyBitmap *bm;
453     BlockDirtyInfoList *list = NULL;
454     BlockDirtyInfoList **tail = &list;
455 
456     bdrv_dirty_bitmaps_lock(bs);
457     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
458         BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
459 
460         info->count = bdrv_get_dirty_count(bm);
461         info->granularity = bdrv_dirty_bitmap_granularity(bm);
462         info->name = g_strdup(bm->name);
463         info->recording = bdrv_dirty_bitmap_recording(bm);
464         info->busy = bdrv_dirty_bitmap_busy(bm);
465         info->persistent = bm->persistent;
466         info->has_inconsistent = bm->inconsistent;
467         info->inconsistent = bm->inconsistent;
468         QAPI_LIST_APPEND(tail, info);
469     }
470     bdrv_dirty_bitmaps_unlock(bs);
471 
472     return list;
473 }
474 
475 /* Called within bdrv_dirty_bitmap_lock..unlock */
476 bool bdrv_dirty_bitmap_get_locked(BdrvDirtyBitmap *bitmap, int64_t offset)
477 {
478     return hbitmap_get(bitmap->bitmap, offset);
479 }
480 
481 bool bdrv_dirty_bitmap_get(BdrvDirtyBitmap *bitmap, int64_t offset)
482 {
483     bool ret;
484     bdrv_dirty_bitmaps_lock(bitmap->bs);
485     ret = bdrv_dirty_bitmap_get_locked(bitmap, offset);
486     bdrv_dirty_bitmaps_unlock(bitmap->bs);
487 
488     return ret;
489 }
490 
491 /**
492  * Chooses a default granularity based on the existing cluster size,
493  * but clamped between [4K, 64K]. Defaults to 64K in the case that there
494  * is no cluster size information available.
495  */
496 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
497 {
498     BlockDriverInfo bdi;
499     uint32_t granularity;
500 
501     if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
502         granularity = MAX(4096, bdi.cluster_size);
503         granularity = MIN(65536, granularity);
504     } else {
505         granularity = 65536;
506     }
507 
508     return granularity;
509 }
510 
511 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
512 {
513     return 1U << hbitmap_granularity(bitmap->bitmap);
514 }
515 
516 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
517 {
518     BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
519     hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
520     iter->bitmap = bitmap;
521     bitmap->active_iterators++;
522     return iter;
523 }
524 
525 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
526 {
527     if (!iter) {
528         return;
529     }
530     assert(iter->bitmap->active_iterators > 0);
531     iter->bitmap->active_iterators--;
532     g_free(iter);
533 }
534 
535 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
536 {
537     return hbitmap_iter_next(&iter->hbi);
538 }
539 
540 /* Called within bdrv_dirty_bitmap_lock..unlock */
541 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
542                                   int64_t offset, int64_t bytes)
543 {
544     assert(!bdrv_dirty_bitmap_readonly(bitmap));
545     hbitmap_set(bitmap->bitmap, offset, bytes);
546 }
547 
548 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
549                            int64_t offset, int64_t bytes)
550 {
551     bdrv_dirty_bitmaps_lock(bitmap->bs);
552     bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
553     bdrv_dirty_bitmaps_unlock(bitmap->bs);
554 }
555 
556 /* Called within bdrv_dirty_bitmap_lock..unlock */
557 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
558                                     int64_t offset, int64_t bytes)
559 {
560     assert(!bdrv_dirty_bitmap_readonly(bitmap));
561     hbitmap_reset(bitmap->bitmap, offset, bytes);
562 }
563 
564 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
565                              int64_t offset, int64_t bytes)
566 {
567     bdrv_dirty_bitmaps_lock(bitmap->bs);
568     bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
569     bdrv_dirty_bitmaps_unlock(bitmap->bs);
570 }
571 
572 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
573 {
574     IO_CODE();
575     assert(!bdrv_dirty_bitmap_readonly(bitmap));
576     bdrv_dirty_bitmaps_lock(bitmap->bs);
577     if (!out) {
578         hbitmap_reset_all(bitmap->bitmap);
579     } else {
580         HBitmap *backup = bitmap->bitmap;
581         bitmap->bitmap = hbitmap_alloc(bitmap->size,
582                                        hbitmap_granularity(backup));
583         *out = backup;
584     }
585     bdrv_dirty_bitmaps_unlock(bitmap->bs);
586 }
587 
588 void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
589 {
590     HBitmap *tmp = bitmap->bitmap;
591     assert(!bdrv_dirty_bitmap_readonly(bitmap));
592     GLOBAL_STATE_CODE();
593     bitmap->bitmap = backup;
594     hbitmap_free(tmp);
595 }
596 
597 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
598                                               uint64_t offset, uint64_t bytes)
599 {
600     return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
601 }
602 
603 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
604 {
605     return hbitmap_serialization_align(bitmap->bitmap);
606 }
607 
608 /* Return the disk size covered by a chunk of serialized bitmap data. */
609 uint64_t bdrv_dirty_bitmap_serialization_coverage(int serialized_chunk_size,
610                                                   const BdrvDirtyBitmap *bitmap)
611 {
612     uint64_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
613     uint64_t limit = granularity * (serialized_chunk_size << 3);
614 
615     assert(QEMU_IS_ALIGNED(limit,
616                            bdrv_dirty_bitmap_serialization_align(bitmap)));
617     return limit;
618 }
619 
620 
621 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
622                                       uint8_t *buf, uint64_t offset,
623                                       uint64_t bytes)
624 {
625     hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
626 }
627 
628 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
629                                         uint8_t *buf, uint64_t offset,
630                                         uint64_t bytes, bool finish)
631 {
632     hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
633 }
634 
635 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
636                                           uint64_t offset, uint64_t bytes,
637                                           bool finish)
638 {
639     hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
640 }
641 
642 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
643                                         uint64_t offset, uint64_t bytes,
644                                         bool finish)
645 {
646     hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
647 }
648 
649 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
650 {
651     hbitmap_deserialize_finish(bitmap->bitmap);
652 }
653 
654 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
655 {
656     BdrvDirtyBitmap *bitmap;
657     IO_CODE();
658 
659     if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
660         return;
661     }
662 
663     bdrv_dirty_bitmaps_lock(bs);
664     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
665         if (!bdrv_dirty_bitmap_enabled(bitmap)) {
666             continue;
667         }
668         assert(!bdrv_dirty_bitmap_readonly(bitmap));
669         hbitmap_set(bitmap->bitmap, offset, bytes);
670     }
671     bdrv_dirty_bitmaps_unlock(bs);
672 }
673 
674 /**
675  * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
676  */
677 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
678 {
679     hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
680 }
681 
682 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
683 {
684     return hbitmap_count(bitmap->bitmap);
685 }
686 
687 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
688 {
689     return bitmap->readonly;
690 }
691 
692 /* Called with BQL taken. */
693 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
694 {
695     bdrv_dirty_bitmaps_lock(bitmap->bs);
696     bitmap->readonly = value;
697     bdrv_dirty_bitmaps_unlock(bitmap->bs);
698 }
699 
700 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
701 {
702     BdrvDirtyBitmap *bm;
703     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
704         if (bm->readonly) {
705             return true;
706         }
707     }
708 
709     return false;
710 }
711 
712 bool bdrv_has_named_bitmaps(BlockDriverState *bs)
713 {
714     BdrvDirtyBitmap *bm;
715 
716     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
717         if (bdrv_dirty_bitmap_name(bm)) {
718             return true;
719         }
720     }
721 
722     return false;
723 }
724 
725 /* Called with BQL taken. */
726 void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent)
727 {
728     bdrv_dirty_bitmaps_lock(bitmap->bs);
729     bitmap->persistent = persistent;
730     bdrv_dirty_bitmaps_unlock(bitmap->bs);
731 }
732 
733 /* Called with BQL taken. */
734 void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
735 {
736     bdrv_dirty_bitmaps_lock(bitmap->bs);
737     assert(bitmap->persistent == true);
738     bitmap->inconsistent = true;
739     bitmap->disabled = true;
740     bdrv_dirty_bitmaps_unlock(bitmap->bs);
741 }
742 
743 /* Called with BQL taken. */
744 void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip)
745 {
746     bdrv_dirty_bitmaps_lock(bitmap->bs);
747     bitmap->skip_store = skip;
748     bdrv_dirty_bitmaps_unlock(bitmap->bs);
749 }
750 
751 bool bdrv_dirty_bitmap_get_persistence(BdrvDirtyBitmap *bitmap)
752 {
753     return bitmap->persistent && !bitmap->skip_store;
754 }
755 
756 bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
757 {
758     return bitmap->inconsistent;
759 }
760 
761 BdrvDirtyBitmap *bdrv_dirty_bitmap_first(BlockDriverState *bs)
762 {
763     return QLIST_FIRST(&bs->dirty_bitmaps);
764 }
765 
766 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BdrvDirtyBitmap *bitmap)
767 {
768     return QLIST_NEXT(bitmap, list);
769 }
770 
771 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
772 {
773     return hbitmap_sha256(bitmap->bitmap, errp);
774 }
775 
776 int64_t bdrv_dirty_bitmap_next_dirty(BdrvDirtyBitmap *bitmap, int64_t offset,
777                                      int64_t bytes)
778 {
779     return hbitmap_next_dirty(bitmap->bitmap, offset, bytes);
780 }
781 
782 int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, int64_t offset,
783                                     int64_t bytes)
784 {
785     return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
786 }
787 
788 bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
789         int64_t start, int64_t end, int64_t max_dirty_count,
790         int64_t *dirty_start, int64_t *dirty_count)
791 {
792     return hbitmap_next_dirty_area(bitmap->bitmap, start, end, max_dirty_count,
793                                    dirty_start, dirty_count);
794 }
795 
796 bool bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap, int64_t offset,
797                               int64_t bytes, int64_t *count)
798 {
799     return hbitmap_status(bitmap->bitmap, offset, bytes, count);
800 }
801 
802 /**
803  * bdrv_merge_dirty_bitmap: merge src into dest.
804  * Ensures permissions on bitmaps are reasonable; use for public API.
805  *
806  * @backup: If provided, make a copy of dest here prior to merge.
807  *
808  * Returns true on success, false on failure. In case of failure bitmaps are
809  * untouched.
810  */
811 bool bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
812                              HBitmap **backup, Error **errp)
813 {
814     bool ret = false;
815 
816     bdrv_dirty_bitmaps_lock(dest->bs);
817     if (src->bs != dest->bs) {
818         bdrv_dirty_bitmaps_lock(src->bs);
819     }
820 
821     if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) {
822         goto out;
823     }
824 
825     if (bdrv_dirty_bitmap_check(src, BDRV_BITMAP_ALLOW_RO, errp)) {
826         goto out;
827     }
828 
829     if (bdrv_dirty_bitmap_size(src) != bdrv_dirty_bitmap_size(dest)) {
830         error_setg(errp, "Bitmaps are of different sizes (destination size is %"
831                    PRId64 ", source size is %" PRId64 ") and can't be merged",
832                    bdrv_dirty_bitmap_size(dest), bdrv_dirty_bitmap_size(src));
833         goto out;
834     }
835 
836     bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
837     ret = true;
838 
839 out:
840     bdrv_dirty_bitmaps_unlock(dest->bs);
841     if (src->bs != dest->bs) {
842         bdrv_dirty_bitmaps_unlock(src->bs);
843     }
844 
845     return ret;
846 }
847 
848 /**
849  * bdrv_dirty_bitmap_merge_internal: merge src into dest.
850  * Does NOT check bitmap permissions; not suitable for use as public API.
851  * @dest, @src and @backup (if not NULL) must have same size.
852  *
853  * @backup: If provided, make a copy of dest here prior to merge.
854  * @lock: If true, lock and unlock bitmaps on the way in/out.
855  */
856 void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
857                                       const BdrvDirtyBitmap *src,
858                                       HBitmap **backup,
859                                       bool lock)
860 {
861     IO_CODE();
862 
863     assert(!bdrv_dirty_bitmap_readonly(dest));
864     assert(!bdrv_dirty_bitmap_inconsistent(dest));
865     assert(!bdrv_dirty_bitmap_inconsistent(src));
866 
867     if (lock) {
868         bdrv_dirty_bitmaps_lock(dest->bs);
869         if (src->bs != dest->bs) {
870             bdrv_dirty_bitmaps_lock(src->bs);
871         }
872     }
873 
874     if (backup) {
875         *backup = dest->bitmap;
876         dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
877         hbitmap_merge(*backup, src->bitmap, dest->bitmap);
878     } else {
879         hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
880     }
881 
882     if (lock) {
883         bdrv_dirty_bitmaps_unlock(dest->bs);
884         if (src->bs != dest->bs) {
885             bdrv_dirty_bitmaps_unlock(src->bs);
886         }
887     }
888 }
889