]> Git Repo - qemu.git/blob - block/dirty-bitmap.c
dirty-bitmap: Change bdrv_dirty_bitmap_*serialize*() to take bytes
[qemu.git] / block / dirty-bitmap.c
1 /*
2  * Block Dirty Bitmap
3  *
4  * Copyright (c) 2016-2017 Red Hat. Inc
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu/osdep.h"
25 #include "qapi/error.h"
26 #include "qemu-common.h"
27 #include "trace.h"
28 #include "block/block_int.h"
29 #include "block/blockjob.h"
30
31 /**
32  * A BdrvDirtyBitmap can be in 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, in bytes */
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
119     assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
120
121     if (name && bdrv_find_dirty_bitmap(bs, name)) {
122         error_setg(errp, "Bitmap already exists: %s", name);
123         return NULL;
124     }
125     bitmap_size = bdrv_getlength(bs);
126     if (bitmap_size < 0) {
127         error_setg_errno(errp, -bitmap_size, "could not get length of device");
128         errno = -bitmap_size;
129         return NULL;
130     }
131     bitmap = g_new0(BdrvDirtyBitmap, 1);
132     bitmap->mutex = &bs->dirty_bitmap_mutex;
133     /*
134      * TODO - let hbitmap track full granularity. For now, it is tracking
135      * only sector granularity, as a shortcut for our iterators.
136      */
137     bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap_size, BDRV_SECTOR_SIZE),
138                                    ctz32(granularity) - BDRV_SECTOR_BITS);
139     bitmap->size = bitmap_size;
140     bitmap->name = g_strdup(name);
141     bitmap->disabled = false;
142     bdrv_dirty_bitmaps_lock(bs);
143     QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
144     bdrv_dirty_bitmaps_unlock(bs);
145     return bitmap;
146 }
147
148 /* bdrv_create_meta_dirty_bitmap
149  *
150  * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
151  * when a dirty status bit in @bitmap is changed (either from reset to set or
152  * the other way around), its respective meta dirty bitmap bit will be marked
153  * dirty as well.
154  *
155  * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
156  * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
157  * track.
158  */
159 void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
160                                    int chunk_size)
161 {
162     assert(!bitmap->meta);
163     qemu_mutex_lock(bitmap->mutex);
164     bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
165                                        chunk_size * BITS_PER_BYTE);
166     qemu_mutex_unlock(bitmap->mutex);
167 }
168
169 void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
170 {
171     assert(bitmap->meta);
172     qemu_mutex_lock(bitmap->mutex);
173     hbitmap_free_meta(bitmap->bitmap);
174     bitmap->meta = NULL;
175     qemu_mutex_unlock(bitmap->mutex);
176 }
177
178 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
179 {
180     return bitmap->size;
181 }
182
183 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
184 {
185     return bitmap->name;
186 }
187
188 /* Called with BQL taken.  */
189 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
190 {
191     return bitmap->successor;
192 }
193
194 /* Called with BQL taken.  */
195 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
196 {
197     return !(bitmap->disabled || bitmap->successor);
198 }
199
200 /* Called with BQL taken.  */
201 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
202 {
203     if (bdrv_dirty_bitmap_frozen(bitmap)) {
204         return DIRTY_BITMAP_STATUS_FROZEN;
205     } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
206         return DIRTY_BITMAP_STATUS_DISABLED;
207     } else {
208         return DIRTY_BITMAP_STATUS_ACTIVE;
209     }
210 }
211
212 /**
213  * Create a successor bitmap destined to replace this bitmap after an operation.
214  * Requires that the bitmap is not frozen and has no successor.
215  * Called with BQL taken.
216  */
217 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
218                                        BdrvDirtyBitmap *bitmap, Error **errp)
219 {
220     uint64_t granularity;
221     BdrvDirtyBitmap *child;
222
223     if (bdrv_dirty_bitmap_frozen(bitmap)) {
224         error_setg(errp, "Cannot create a successor for a bitmap that is "
225                    "currently frozen");
226         return -1;
227     }
228     assert(!bitmap->successor);
229
230     /* Create an anonymous successor */
231     granularity = bdrv_dirty_bitmap_granularity(bitmap);
232     child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
233     if (!child) {
234         return -1;
235     }
236
237     /* Successor will be on or off based on our current state. */
238     child->disabled = bitmap->disabled;
239
240     /* Install the successor and freeze the parent */
241     bitmap->successor = child;
242     return 0;
243 }
244
245 /**
246  * For a bitmap with a successor, yield our name to the successor,
247  * delete the old bitmap, and return a handle to the new bitmap.
248  * Called with BQL taken.
249  */
250 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
251                                             BdrvDirtyBitmap *bitmap,
252                                             Error **errp)
253 {
254     char *name;
255     BdrvDirtyBitmap *successor = bitmap->successor;
256
257     if (successor == NULL) {
258         error_setg(errp, "Cannot relinquish control if "
259                    "there's no successor present");
260         return NULL;
261     }
262
263     name = bitmap->name;
264     bitmap->name = NULL;
265     successor->name = name;
266     bitmap->successor = NULL;
267     successor->persistent = bitmap->persistent;
268     bitmap->persistent = false;
269     successor->autoload = bitmap->autoload;
270     bitmap->autoload = false;
271     bdrv_release_dirty_bitmap(bs, bitmap);
272
273     return successor;
274 }
275
276 /**
277  * In cases of failure where we can no longer safely delete the parent,
278  * we may wish to re-join the parent and child/successor.
279  * The merged parent will be un-frozen, but not explicitly re-enabled.
280  * Called with BQL taken.
281  */
282 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
283                                            BdrvDirtyBitmap *parent,
284                                            Error **errp)
285 {
286     BdrvDirtyBitmap *successor = parent->successor;
287
288     if (!successor) {
289         error_setg(errp, "Cannot reclaim a successor when none is present");
290         return NULL;
291     }
292
293     if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
294         error_setg(errp, "Merging of parent and successor bitmap failed");
295         return NULL;
296     }
297     bdrv_release_dirty_bitmap(bs, successor);
298     parent->successor = NULL;
299
300     return parent;
301 }
302
303 /**
304  * Truncates _all_ bitmaps attached to a BDS.
305  * Called with BQL taken.
306  */
307 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
308 {
309     BdrvDirtyBitmap *bitmap;
310
311     bdrv_dirty_bitmaps_lock(bs);
312     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
313         assert(!bdrv_dirty_bitmap_frozen(bitmap));
314         assert(!bitmap->active_iterators);
315         hbitmap_truncate(bitmap->bitmap, DIV_ROUND_UP(bytes, BDRV_SECTOR_SIZE));
316         bitmap->size = bytes;
317     }
318     bdrv_dirty_bitmaps_unlock(bs);
319 }
320
321 static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
322 {
323     return !!bdrv_dirty_bitmap_name(bitmap);
324 }
325
326 /* Called with BQL taken.  */
327 static void bdrv_do_release_matching_dirty_bitmap(
328     BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
329     bool (*cond)(BdrvDirtyBitmap *bitmap))
330 {
331     BdrvDirtyBitmap *bm, *next;
332     bdrv_dirty_bitmaps_lock(bs);
333     QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
334         if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
335             assert(!bm->active_iterators);
336             assert(!bdrv_dirty_bitmap_frozen(bm));
337             assert(!bm->meta);
338             QLIST_REMOVE(bm, list);
339             hbitmap_free(bm->bitmap);
340             g_free(bm->name);
341             g_free(bm);
342
343             if (bitmap) {
344                 goto out;
345             }
346         }
347     }
348     if (bitmap) {
349         abort();
350     }
351
352 out:
353     bdrv_dirty_bitmaps_unlock(bs);
354 }
355
356 /* Called with BQL taken.  */
357 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
358 {
359     bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
360 }
361
362 /**
363  * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
364  * There must not be any frozen bitmaps attached.
365  * This function does not remove persistent bitmaps from the storage.
366  * Called with BQL taken.
367  */
368 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
369 {
370     bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
371 }
372
373 /**
374  * Release all persistent dirty bitmaps attached to a BDS (for use in
375  * bdrv_inactivate_recurse()).
376  * There must not be any frozen bitmaps attached.
377  * This function does not remove persistent bitmaps from the storage.
378  */
379 void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
380 {
381     bdrv_do_release_matching_dirty_bitmap(bs, NULL,
382                                           bdrv_dirty_bitmap_get_persistance);
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 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
394                                          const char *name,
395                                          Error **errp)
396 {
397     if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
398         bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
399     }
400 }
401
402 /* Called with BQL taken.  */
403 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
404 {
405     assert(!bdrv_dirty_bitmap_frozen(bitmap));
406     bitmap->disabled = true;
407 }
408
409 /* Called with BQL taken.  */
410 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
411 {
412     assert(!bdrv_dirty_bitmap_frozen(bitmap));
413     bitmap->disabled = false;
414 }
415
416 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
417 {
418     BdrvDirtyBitmap *bm;
419     BlockDirtyInfoList *list = NULL;
420     BlockDirtyInfoList **plist = &list;
421
422     bdrv_dirty_bitmaps_lock(bs);
423     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
424         BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
425         BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
426         info->count = bdrv_get_dirty_count(bm) << BDRV_SECTOR_BITS;
427         info->granularity = bdrv_dirty_bitmap_granularity(bm);
428         info->has_name = !!bm->name;
429         info->name = g_strdup(bm->name);
430         info->status = bdrv_dirty_bitmap_status(bm);
431         entry->value = info;
432         *plist = entry;
433         plist = &entry->next;
434     }
435     bdrv_dirty_bitmaps_unlock(bs);
436
437     return list;
438 }
439
440 /* Called within bdrv_dirty_bitmap_lock..unlock */
441 int bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
442                           int64_t sector)
443 {
444     if (bitmap) {
445         return hbitmap_get(bitmap->bitmap, sector);
446     } else {
447         return 0;
448     }
449 }
450
451 /**
452  * Chooses a default granularity based on the existing cluster size,
453  * but clamped between [4K, 64K]. Defaults to 64K in the case that there
454  * is no cluster size information available.
455  */
456 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
457 {
458     BlockDriverInfo bdi;
459     uint32_t granularity;
460
461     if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
462         granularity = MAX(4096, bdi.cluster_size);
463         granularity = MIN(65536, granularity);
464     } else {
465         granularity = 65536;
466     }
467
468     return granularity;
469 }
470
471 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
472 {
473     return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
474 }
475
476 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
477                                          uint64_t first_sector)
478 {
479     BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
480     hbitmap_iter_init(&iter->hbi, bitmap->bitmap, first_sector);
481     iter->bitmap = bitmap;
482     bitmap->active_iterators++;
483     return iter;
484 }
485
486 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
487 {
488     BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
489     hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
490     iter->bitmap = bitmap;
491     bitmap->active_iterators++;
492     return iter;
493 }
494
495 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
496 {
497     if (!iter) {
498         return;
499     }
500     assert(iter->bitmap->active_iterators > 0);
501     iter->bitmap->active_iterators--;
502     g_free(iter);
503 }
504
505 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
506 {
507     return hbitmap_iter_next(&iter->hbi);
508 }
509
510 /* Called within bdrv_dirty_bitmap_lock..unlock */
511 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
512                                   int64_t cur_sector, int64_t nr_sectors)
513 {
514     assert(bdrv_dirty_bitmap_enabled(bitmap));
515     assert(!bdrv_dirty_bitmap_readonly(bitmap));
516     hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
517 }
518
519 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
520                            int64_t cur_sector, int64_t nr_sectors)
521 {
522     bdrv_dirty_bitmap_lock(bitmap);
523     bdrv_set_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
524     bdrv_dirty_bitmap_unlock(bitmap);
525 }
526
527 /* Called within bdrv_dirty_bitmap_lock..unlock */
528 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
529                                     int64_t cur_sector, int64_t nr_sectors)
530 {
531     assert(bdrv_dirty_bitmap_enabled(bitmap));
532     assert(!bdrv_dirty_bitmap_readonly(bitmap));
533     hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
534 }
535
536 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
537                              int64_t cur_sector, int64_t nr_sectors)
538 {
539     bdrv_dirty_bitmap_lock(bitmap);
540     bdrv_reset_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
541     bdrv_dirty_bitmap_unlock(bitmap);
542 }
543
544 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
545 {
546     assert(bdrv_dirty_bitmap_enabled(bitmap));
547     assert(!bdrv_dirty_bitmap_readonly(bitmap));
548     bdrv_dirty_bitmap_lock(bitmap);
549     if (!out) {
550         hbitmap_reset_all(bitmap->bitmap);
551     } else {
552         HBitmap *backup = bitmap->bitmap;
553         bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap->size,
554                                                     BDRV_SECTOR_SIZE),
555                                        hbitmap_granularity(backup));
556         *out = backup;
557     }
558     bdrv_dirty_bitmap_unlock(bitmap);
559 }
560
561 void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
562 {
563     HBitmap *tmp = bitmap->bitmap;
564     assert(bdrv_dirty_bitmap_enabled(bitmap));
565     assert(!bdrv_dirty_bitmap_readonly(bitmap));
566     bitmap->bitmap = in;
567     hbitmap_free(tmp);
568 }
569
570 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
571                                               uint64_t offset, uint64_t bytes)
572 {
573     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
574     return hbitmap_serialization_size(bitmap->bitmap,
575                                       offset >> BDRV_SECTOR_BITS,
576                                       bytes >> BDRV_SECTOR_BITS);
577 }
578
579 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
580 {
581     return hbitmap_serialization_align(bitmap->bitmap) * BDRV_SECTOR_SIZE;
582 }
583
584 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
585                                       uint8_t *buf, uint64_t offset,
586                                       uint64_t bytes)
587 {
588     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
589     hbitmap_serialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
590                            bytes >> BDRV_SECTOR_BITS);
591 }
592
593 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
594                                         uint8_t *buf, uint64_t offset,
595                                         uint64_t bytes, bool finish)
596 {
597     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
598     hbitmap_deserialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
599                              bytes >> BDRV_SECTOR_BITS, finish);
600 }
601
602 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
603                                           uint64_t offset, uint64_t bytes,
604                                           bool finish)
605 {
606     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
607     hbitmap_deserialize_zeroes(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
608                                bytes >> BDRV_SECTOR_BITS, finish);
609 }
610
611 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
612                                         uint64_t offset, uint64_t bytes,
613                                         bool finish)
614 {
615     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
616     hbitmap_deserialize_ones(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
617                              bytes >> BDRV_SECTOR_BITS, finish);
618 }
619
620 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
621 {
622     hbitmap_deserialize_finish(bitmap->bitmap);
623 }
624
625 void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
626                     int64_t nr_sectors)
627 {
628     BdrvDirtyBitmap *bitmap;
629
630     if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
631         return;
632     }
633
634     bdrv_dirty_bitmaps_lock(bs);
635     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
636         if (!bdrv_dirty_bitmap_enabled(bitmap)) {
637             continue;
638         }
639         assert(!bdrv_dirty_bitmap_readonly(bitmap));
640         hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
641     }
642     bdrv_dirty_bitmaps_unlock(bs);
643 }
644
645 /**
646  * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
647  */
648 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
649 {
650     hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
651 }
652
653 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
654 {
655     return hbitmap_count(bitmap->bitmap);
656 }
657
658 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
659 {
660     return hbitmap_count(bitmap->meta);
661 }
662
663 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
664 {
665     return bitmap->readonly;
666 }
667
668 /* Called with BQL taken. */
669 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
670 {
671     qemu_mutex_lock(bitmap->mutex);
672     bitmap->readonly = value;
673     qemu_mutex_unlock(bitmap->mutex);
674 }
675
676 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
677 {
678     BdrvDirtyBitmap *bm;
679     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
680         if (bm->readonly) {
681             return true;
682         }
683     }
684
685     return false;
686 }
687
688 /* Called with BQL taken. */
689 void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload)
690 {
691     qemu_mutex_lock(bitmap->mutex);
692     bitmap->autoload = autoload;
693     qemu_mutex_unlock(bitmap->mutex);
694 }
695
696 bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
697 {
698     return bitmap->autoload;
699 }
700
701 /* Called with BQL taken. */
702 void 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
709 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
710 {
711     return bitmap->persistent;
712 }
713
714 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
715 {
716     BdrvDirtyBitmap *bm;
717     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
718         if (bm->persistent && !bm->readonly) {
719             return true;
720         }
721     }
722
723     return false;
724 }
725
726 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
727                                         BdrvDirtyBitmap *bitmap)
728 {
729     return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
730                             QLIST_NEXT(bitmap, list);
731 }
732
733 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
734 {
735     return hbitmap_sha256(bitmap->bitmap, errp);
736 }
This page took 0.063266 seconds and 4 git commands to generate.