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