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