]> git.proxmox.com Git - mirror_qemu.git/blame - block/dirty-bitmap.c
block/dirty-bitmap: add _locked version of bdrv_reclaim_dirty_bitmap
[mirror_qemu.git] / block / dirty-bitmap.c
CommitLineData
ebab2259
FZ
1/*
2 * Block Dirty Bitmap
3 *
1b6cc579 4 * Copyright (c) 2016-2017 Red Hat. Inc
ebab2259
FZ
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"
da34e65c 25#include "qapi/error.h"
ebab2259
FZ
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 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().
38 */
39struct BdrvDirtyBitmap {
b64bd51e 40 QemuMutex *mutex;
ca759622 41 HBitmap *bitmap; /* Dirty bitmap implementation */
fb933437 42 HBitmap *meta; /* Meta dirty bitmap */
ebab2259
FZ
43 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
44 char *name; /* Optional non-empty unique ID */
993e6525 45 int64_t size; /* Size of the bitmap, in bytes */
8bfc932e
VSO
46 bool disabled; /* Bitmap is disabled. It ignores all writes to
47 the device */
dc162c8e 48 int active_iterators; /* How many iterators are active */
d6883bc9
VSO
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. */
a88b179f 55 bool persistent; /* bitmap must be saved to owner disk image */
ebab2259
FZ
56 QLIST_ENTRY(BdrvDirtyBitmap) list;
57};
58
dc162c8e
FZ
59struct BdrvDirtyBitmapIter {
60 HBitmapIter hbi;
61 BdrvDirtyBitmap *bitmap;
62};
63
2119882c
PB
64static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
65{
66 qemu_mutex_lock(&bs->dirty_bitmap_mutex);
67}
68
69static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
70{
71 qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
72}
73
b64bd51e
PB
74void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
75{
76 qemu_mutex_lock(bitmap->mutex);
77}
78
79void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
80{
81 qemu_mutex_unlock(bitmap->mutex);
82}
83
2119882c 84/* Called with BQL or dirty_bitmap lock taken. */
ebab2259
FZ
85BdrvDirtyBitmap *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
2119882c 98/* Called with BQL taken. */
ebab2259
FZ
99void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
100{
101 assert(!bdrv_dirty_bitmap_frozen(bitmap));
102 g_free(bitmap->name);
103 bitmap->name = NULL;
a88b179f 104 bitmap->persistent = false;
ebab2259
FZ
105}
106
2119882c 107/* Called with BQL taken. */
ebab2259
FZ
108BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
109 uint32_t granularity,
110 const char *name,
111 Error **errp)
112{
113 int64_t bitmap_size;
114 BdrvDirtyBitmap *bitmap;
ebab2259 115
993e6525 116 assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
ebab2259
FZ
117
118 if (name && bdrv_find_dirty_bitmap(bs, name)) {
119 error_setg(errp, "Bitmap already exists: %s", name);
120 return NULL;
121 }
993e6525 122 bitmap_size = bdrv_getlength(bs);
ebab2259
FZ
123 if (bitmap_size < 0) {
124 error_setg_errno(errp, -bitmap_size, "could not get length of device");
125 errno = -bitmap_size;
126 return NULL;
127 }
128 bitmap = g_new0(BdrvDirtyBitmap, 1);
b64bd51e 129 bitmap->mutex = &bs->dirty_bitmap_mutex;
ca759622 130 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
ebab2259
FZ
131 bitmap->size = bitmap_size;
132 bitmap->name = g_strdup(name);
133 bitmap->disabled = false;
2119882c 134 bdrv_dirty_bitmaps_lock(bs);
ebab2259 135 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
2119882c 136 bdrv_dirty_bitmaps_unlock(bs);
ebab2259
FZ
137 return bitmap;
138}
139
fb933437
FZ
140/* bdrv_create_meta_dirty_bitmap
141 *
142 * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
143 * when a dirty status bit in @bitmap is changed (either from reset to set or
144 * the other way around), its respective meta dirty bitmap bit will be marked
145 * dirty as well.
146 *
147 * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
148 * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
149 * track.
150 */
151void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
152 int chunk_size)
153{
154 assert(!bitmap->meta);
b64bd51e 155 qemu_mutex_lock(bitmap->mutex);
fb933437
FZ
156 bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
157 chunk_size * BITS_PER_BYTE);
b64bd51e 158 qemu_mutex_unlock(bitmap->mutex);
fb933437
FZ
159}
160
161void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
162{
163 assert(bitmap->meta);
b64bd51e 164 qemu_mutex_lock(bitmap->mutex);
fb933437
FZ
165 hbitmap_free_meta(bitmap->bitmap);
166 bitmap->meta = NULL;
b64bd51e 167 qemu_mutex_unlock(bitmap->mutex);
fb933437
FZ
168}
169
15891fac
FZ
170int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
171{
993e6525 172 return bitmap->size;
15891fac
FZ
173}
174
175const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
176{
177 return bitmap->name;
178}
179
2119882c 180/* Called with BQL taken. */
ebab2259
FZ
181bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
182{
183 return bitmap->successor;
184}
185
2119882c 186/* Called with BQL taken. */
ebab2259
FZ
187bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
188{
189 return !(bitmap->disabled || bitmap->successor);
190}
191
2119882c 192/* Called with BQL taken. */
ebab2259
FZ
193DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
194{
195 if (bdrv_dirty_bitmap_frozen(bitmap)) {
196 return DIRTY_BITMAP_STATUS_FROZEN;
197 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
198 return DIRTY_BITMAP_STATUS_DISABLED;
199 } else {
200 return DIRTY_BITMAP_STATUS_ACTIVE;
201 }
202}
203
204/**
205 * Create a successor bitmap destined to replace this bitmap after an operation.
206 * Requires that the bitmap is not frozen and has no successor.
2119882c 207 * Called with BQL taken.
ebab2259
FZ
208 */
209int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
210 BdrvDirtyBitmap *bitmap, Error **errp)
211{
212 uint64_t granularity;
213 BdrvDirtyBitmap *child;
214
215 if (bdrv_dirty_bitmap_frozen(bitmap)) {
216 error_setg(errp, "Cannot create a successor for a bitmap that is "
217 "currently frozen");
218 return -1;
219 }
220 assert(!bitmap->successor);
221
222 /* Create an anonymous successor */
223 granularity = bdrv_dirty_bitmap_granularity(bitmap);
224 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
225 if (!child) {
226 return -1;
227 }
228
229 /* Successor will be on or off based on our current state. */
230 child->disabled = bitmap->disabled;
231
232 /* Install the successor and freeze the parent */
233 bitmap->successor = child;
234 return 0;
235}
236
e73a265e
VSO
237/* Called with BQL taken. */
238void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
239{
240 qemu_mutex_lock(bitmap->mutex);
241 bdrv_enable_dirty_bitmap(bitmap->successor);
242 qemu_mutex_unlock(bitmap->mutex);
243}
244
604ab74b
VSO
245/* Called within bdrv_dirty_bitmap_lock..unlock */
246static void bdrv_do_release_matching_dirty_bitmap_locked(
247 BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
248 bool (*cond)(BdrvDirtyBitmap *bitmap))
249{
250 BdrvDirtyBitmap *bm, *next;
251
252 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
253 if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
254 assert(!bm->active_iterators);
255 assert(!bdrv_dirty_bitmap_frozen(bm));
256 assert(!bm->meta);
257 QLIST_REMOVE(bm, list);
258 hbitmap_free(bm->bitmap);
259 g_free(bm->name);
260 g_free(bm);
261
262 if (bitmap) {
263 return;
264 }
265 }
266 }
267
268 if (bitmap) {
269 abort();
270 }
271}
272
273/* Called with BQL taken. */
274static void bdrv_do_release_matching_dirty_bitmap(
275 BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
276 bool (*cond)(BdrvDirtyBitmap *bitmap))
277{
278 bdrv_dirty_bitmaps_lock(bs);
279 bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, cond);
280 bdrv_dirty_bitmaps_unlock(bs);
281}
282
283/* Called within bdrv_dirty_bitmap_lock..unlock */
284static void bdrv_release_dirty_bitmap_locked(BlockDriverState *bs,
285 BdrvDirtyBitmap *bitmap)
286{
287 bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, NULL);
288}
289
ebab2259
FZ
290/**
291 * For a bitmap with a successor, yield our name to the successor,
292 * delete the old bitmap, and return a handle to the new bitmap.
2119882c 293 * Called with BQL taken.
ebab2259
FZ
294 */
295BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
296 BdrvDirtyBitmap *bitmap,
297 Error **errp)
298{
299 char *name;
300 BdrvDirtyBitmap *successor = bitmap->successor;
301
302 if (successor == NULL) {
303 error_setg(errp, "Cannot relinquish control if "
304 "there's no successor present");
305 return NULL;
306 }
307
308 name = bitmap->name;
309 bitmap->name = NULL;
310 successor->name = name;
311 bitmap->successor = NULL;
a88b179f
VSO
312 successor->persistent = bitmap->persistent;
313 bitmap->persistent = false;
ebab2259
FZ
314 bdrv_release_dirty_bitmap(bs, bitmap);
315
316 return successor;
317}
318
319/**
320 * In cases of failure where we can no longer safely delete the parent,
321 * we may wish to re-join the parent and child/successor.
322 * The merged parent will be un-frozen, but not explicitly re-enabled.
044ee8e1 323 * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
ebab2259 324 */
044ee8e1
VSO
325BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
326 BdrvDirtyBitmap *parent,
327 Error **errp)
ebab2259 328{
044ee8e1 329 BdrvDirtyBitmap *successor = parent->successor;
ebab2259
FZ
330
331 if (!successor) {
332 error_setg(errp, "Cannot reclaim a successor when none is present");
333 return NULL;
334 }
335
336 if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
337 error_setg(errp, "Merging of parent and successor bitmap failed");
338 return NULL;
339 }
604ab74b 340 bdrv_release_dirty_bitmap_locked(bs, successor);
ebab2259
FZ
341 parent->successor = NULL;
342
044ee8e1
VSO
343 return parent;
344}
345
346/* Called with BQL taken. */
347BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
348 BdrvDirtyBitmap *parent,
349 Error **errp)
350{
351 BdrvDirtyBitmap *ret;
352
353 qemu_mutex_lock(parent->mutex);
354 ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp);
604ab74b
VSO
355 qemu_mutex_unlock(parent->mutex);
356
044ee8e1 357 return ret;
ebab2259
FZ
358}
359
360/**
361 * Truncates _all_ bitmaps attached to a BDS.
2119882c 362 * Called with BQL taken.
ebab2259 363 */
1b6cc579 364void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
ebab2259
FZ
365{
366 BdrvDirtyBitmap *bitmap;
ebab2259 367
2119882c 368 bdrv_dirty_bitmaps_lock(bs);
ebab2259
FZ
369 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
370 assert(!bdrv_dirty_bitmap_frozen(bitmap));
dc162c8e 371 assert(!bitmap->active_iterators);
ca759622 372 hbitmap_truncate(bitmap->bitmap, bytes);
993e6525 373 bitmap->size = bytes;
ebab2259 374 }
2119882c 375 bdrv_dirty_bitmaps_unlock(bs);
ebab2259
FZ
376}
377
615b5dcf
VSO
378static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
379{
380 return !!bdrv_dirty_bitmap_name(bitmap);
381}
382
2119882c 383/* Called with BQL taken. */
ebab2259
FZ
384void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
385{
615b5dcf 386 bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
ebab2259
FZ
387}
388
389/**
390 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
391 * There must not be any frozen bitmaps attached.
56f364e6 392 * This function does not remove persistent bitmaps from the storage.
2119882c 393 * Called with BQL taken.
ebab2259
FZ
394 */
395void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
396{
615b5dcf
VSO
397 bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
398}
399
400/**
401 * Release all persistent dirty bitmaps attached to a BDS (for use in
402 * bdrv_inactivate_recurse()).
403 * There must not be any frozen bitmaps attached.
404 * This function does not remove persistent bitmaps from the storage.
405 */
406void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
407{
408 bdrv_do_release_matching_dirty_bitmap(bs, NULL,
409 bdrv_dirty_bitmap_get_persistance);
ebab2259
FZ
410}
411
56f364e6
VSO
412/**
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.
419 */
420void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
421 const char *name,
422 Error **errp)
423{
424 if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
425 bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
426 }
427}
428
2119882c 429/* Called with BQL taken. */
ebab2259
FZ
430void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
431{
432 assert(!bdrv_dirty_bitmap_frozen(bitmap));
433 bitmap->disabled = true;
434}
435
2119882c 436/* Called with BQL taken. */
ebab2259
FZ
437void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
438{
439 assert(!bdrv_dirty_bitmap_frozen(bitmap));
440 bitmap->disabled = false;
441}
442
443BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
444{
445 BdrvDirtyBitmap *bm;
446 BlockDirtyInfoList *list = NULL;
447 BlockDirtyInfoList **plist = &list;
448
2119882c 449 bdrv_dirty_bitmaps_lock(bs);
ebab2259
FZ
450 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
451 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
452 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
9a46dba7 453 info->count = bdrv_get_dirty_count(bm);
ebab2259
FZ
454 info->granularity = bdrv_dirty_bitmap_granularity(bm);
455 info->has_name = !!bm->name;
456 info->name = g_strdup(bm->name);
457 info->status = bdrv_dirty_bitmap_status(bm);
458 entry->value = info;
459 *plist = entry;
460 plist = &entry->next;
461 }
2119882c 462 bdrv_dirty_bitmaps_unlock(bs);
ebab2259
FZ
463
464 return list;
465}
466
b64bd51e 467/* Called within bdrv_dirty_bitmap_lock..unlock */
3b5d4df0
EB
468bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
469 int64_t offset)
ebab2259
FZ
470{
471 if (bitmap) {
ca759622 472 return hbitmap_get(bitmap->bitmap, offset);
ebab2259 473 } else {
3b5d4df0 474 return false;
ebab2259
FZ
475 }
476}
477
478/**
479 * Chooses a default granularity based on the existing cluster size,
480 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
481 * is no cluster size information available.
482 */
483uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
484{
485 BlockDriverInfo bdi;
486 uint32_t granularity;
487
488 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
489 granularity = MAX(4096, bdi.cluster_size);
490 granularity = MIN(65536, granularity);
491 } else {
492 granularity = 65536;
493 }
494
495 return granularity;
496}
497
ba06ff1a 498uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
ebab2259 499{
ca759622 500 return 1U << hbitmap_granularity(bitmap->bitmap);
ebab2259
FZ
501}
502
715a74d8 503BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
dc162c8e
FZ
504{
505 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
715a74d8 506 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
dc162c8e
FZ
507 iter->bitmap = bitmap;
508 bitmap->active_iterators++;
509 return iter;
510}
511
6d3f4049
FZ
512BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
513{
514 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
515 hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
516 iter->bitmap = bitmap;
517 bitmap->active_iterators++;
518 return iter;
519}
520
dc162c8e
FZ
521void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
522{
523 if (!iter) {
524 return;
525 }
526 assert(iter->bitmap->active_iterators > 0);
527 iter->bitmap->active_iterators--;
528 g_free(iter);
529}
530
531int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
ebab2259 532{
ca759622 533 return hbitmap_iter_next(&iter->hbi);
ebab2259
FZ
534}
535
b64bd51e
PB
536/* Called within bdrv_dirty_bitmap_lock..unlock */
537void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
e0d7f73e 538 int64_t offset, int64_t bytes)
b64bd51e
PB
539{
540 assert(bdrv_dirty_bitmap_enabled(bitmap));
d6883bc9 541 assert(!bdrv_dirty_bitmap_readonly(bitmap));
ca759622 542 hbitmap_set(bitmap->bitmap, offset, bytes);
b64bd51e
PB
543}
544
ebab2259 545void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
e0d7f73e 546 int64_t offset, int64_t bytes)
b64bd51e
PB
547{
548 bdrv_dirty_bitmap_lock(bitmap);
e0d7f73e 549 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
b64bd51e
PB
550 bdrv_dirty_bitmap_unlock(bitmap);
551}
552
553/* Called within bdrv_dirty_bitmap_lock..unlock */
554void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
e0d7f73e 555 int64_t offset, int64_t bytes)
ebab2259
FZ
556{
557 assert(bdrv_dirty_bitmap_enabled(bitmap));
d6883bc9 558 assert(!bdrv_dirty_bitmap_readonly(bitmap));
ca759622 559 hbitmap_reset(bitmap->bitmap, offset, bytes);
ebab2259
FZ
560}
561
562void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
e0d7f73e 563 int64_t offset, int64_t bytes)
ebab2259 564{
b64bd51e 565 bdrv_dirty_bitmap_lock(bitmap);
e0d7f73e 566 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
b64bd51e 567 bdrv_dirty_bitmap_unlock(bitmap);
ebab2259
FZ
568}
569
570void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
571{
572 assert(bdrv_dirty_bitmap_enabled(bitmap));
d6883bc9 573 assert(!bdrv_dirty_bitmap_readonly(bitmap));
b64bd51e 574 bdrv_dirty_bitmap_lock(bitmap);
ebab2259
FZ
575 if (!out) {
576 hbitmap_reset_all(bitmap->bitmap);
577 } else {
578 HBitmap *backup = bitmap->bitmap;
ca759622 579 bitmap->bitmap = hbitmap_alloc(bitmap->size,
ebab2259
FZ
580 hbitmap_granularity(backup));
581 *out = backup;
582 }
b64bd51e 583 bdrv_dirty_bitmap_unlock(bitmap);
ebab2259
FZ
584}
585
586void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
587{
588 HBitmap *tmp = bitmap->bitmap;
589 assert(bdrv_dirty_bitmap_enabled(bitmap));
d6883bc9 590 assert(!bdrv_dirty_bitmap_readonly(bitmap));
ebab2259
FZ
591 bitmap->bitmap = in;
592 hbitmap_free(tmp);
593}
594
882c36f5 595uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
86f6ae67 596 uint64_t offset, uint64_t bytes)
882c36f5 597{
ca759622 598 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
882c36f5
VSO
599}
600
601uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
602{
ca759622 603 return hbitmap_serialization_align(bitmap->bitmap);
882c36f5
VSO
604}
605
606void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
86f6ae67
EB
607 uint8_t *buf, uint64_t offset,
608 uint64_t bytes)
882c36f5 609{
ca759622 610 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
882c36f5
VSO
611}
612
613void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
86f6ae67
EB
614 uint8_t *buf, uint64_t offset,
615 uint64_t bytes, bool finish)
882c36f5 616{
ca759622 617 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
882c36f5
VSO
618}
619
620void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
86f6ae67 621 uint64_t offset, uint64_t bytes,
882c36f5
VSO
622 bool finish)
623{
ca759622 624 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
6bdc8b71
VSO
625}
626
627void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
86f6ae67 628 uint64_t offset, uint64_t bytes,
6bdc8b71
VSO
629 bool finish)
630{
ca759622 631 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
882c36f5
VSO
632}
633
634void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
635{
636 hbitmap_deserialize_finish(bitmap->bitmap);
637}
638
0fdf1a4f 639void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
ebab2259
FZ
640{
641 BdrvDirtyBitmap *bitmap;
2119882c
PB
642
643 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
644 return;
645 }
646
647 bdrv_dirty_bitmaps_lock(bs);
ebab2259
FZ
648 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
649 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
650 continue;
651 }
d6883bc9 652 assert(!bdrv_dirty_bitmap_readonly(bitmap));
ca759622 653 hbitmap_set(bitmap->bitmap, offset, bytes);
ebab2259 654 }
2119882c 655 bdrv_dirty_bitmaps_unlock(bs);
ebab2259
FZ
656}
657
658/**
dc162c8e 659 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
ebab2259 660 */
715a74d8 661void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
ebab2259 662{
ca759622 663 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
ebab2259
FZ
664}
665
666int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
667{
ca759622 668 return hbitmap_count(bitmap->bitmap);
ebab2259 669}
6d3f4049
FZ
670
671int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
672{
673 return hbitmap_count(bitmap->meta);
674}
d6883bc9
VSO
675
676bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
677{
678 return bitmap->readonly;
679}
680
681/* Called with BQL taken. */
682void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
683{
684 qemu_mutex_lock(bitmap->mutex);
685 bitmap->readonly = value;
686 qemu_mutex_unlock(bitmap->mutex);
687}
688
689bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
690{
691 BdrvDirtyBitmap *bm;
692 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
693 if (bm->readonly) {
694 return true;
695 }
696 }
697
698 return false;
699}
a0319aac 700
a88b179f
VSO
701/* Called with BQL taken. */
702void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
703{
704 qemu_mutex_lock(bitmap->mutex);
705 bitmap->persistent = persistent;
706 qemu_mutex_unlock(bitmap->mutex);
707}
708
709bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
710{
711 return bitmap->persistent;
712}
713
714bool 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) {
719 return true;
720 }
721 }
722
723 return false;
724}
3dd10a06
VSO
725
726BdrvDirtyBitmap *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}
a3b52535
VSO
732
733char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
734{
735 return hbitmap_sha256(bitmap->bitmap, errp);
736}
56207df5
VSO
737
738int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
739{
740 return hbitmap_next_zero(bitmap->bitmap, offset);
741}