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