]> Git Repo - qemu.git/blob - block/dirty-bitmap.c
dirty-bitmap: Switch bdrv_set_dirty() to 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);
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 bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
442                            int64_t offset)
443 {
444     if (bitmap) {
445         return hbitmap_get(bitmap->bitmap, offset >> BDRV_SECTOR_BITS);
446     } else {
447         return false;
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 {
478     BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
479     hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
480     iter->bitmap = bitmap;
481     bitmap->active_iterators++;
482     return iter;
483 }
484
485 BdrvDirtyBitmapIter *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
494 void 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
504 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
505 {
506     int64_t ret = hbitmap_iter_next(&iter->hbi);
507     return ret < 0 ? -1 : ret * BDRV_SECTOR_SIZE;
508 }
509
510 /* Called within bdrv_dirty_bitmap_lock..unlock */
511 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
512                                   int64_t offset, int64_t bytes)
513 {
514     int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
515
516     assert(bdrv_dirty_bitmap_enabled(bitmap));
517     assert(!bdrv_dirty_bitmap_readonly(bitmap));
518     hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
519                 end_sector - (offset >> BDRV_SECTOR_BITS));
520 }
521
522 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
523                            int64_t offset, int64_t bytes)
524 {
525     bdrv_dirty_bitmap_lock(bitmap);
526     bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
527     bdrv_dirty_bitmap_unlock(bitmap);
528 }
529
530 /* Called within bdrv_dirty_bitmap_lock..unlock */
531 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
532                                     int64_t offset, int64_t bytes)
533 {
534     int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
535
536     assert(bdrv_dirty_bitmap_enabled(bitmap));
537     assert(!bdrv_dirty_bitmap_readonly(bitmap));
538     hbitmap_reset(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
539                   end_sector - (offset >> BDRV_SECTOR_BITS));
540 }
541
542 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
543                              int64_t offset, int64_t bytes)
544 {
545     bdrv_dirty_bitmap_lock(bitmap);
546     bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
547     bdrv_dirty_bitmap_unlock(bitmap);
548 }
549
550 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
551 {
552     assert(bdrv_dirty_bitmap_enabled(bitmap));
553     assert(!bdrv_dirty_bitmap_readonly(bitmap));
554     bdrv_dirty_bitmap_lock(bitmap);
555     if (!out) {
556         hbitmap_reset_all(bitmap->bitmap);
557     } else {
558         HBitmap *backup = bitmap->bitmap;
559         bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap->size,
560                                                     BDRV_SECTOR_SIZE),
561                                        hbitmap_granularity(backup));
562         *out = backup;
563     }
564     bdrv_dirty_bitmap_unlock(bitmap);
565 }
566
567 void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
568 {
569     HBitmap *tmp = bitmap->bitmap;
570     assert(bdrv_dirty_bitmap_enabled(bitmap));
571     assert(!bdrv_dirty_bitmap_readonly(bitmap));
572     bitmap->bitmap = in;
573     hbitmap_free(tmp);
574 }
575
576 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
577                                               uint64_t offset, uint64_t bytes)
578 {
579     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
580     return hbitmap_serialization_size(bitmap->bitmap,
581                                       offset >> BDRV_SECTOR_BITS,
582                                       bytes >> BDRV_SECTOR_BITS);
583 }
584
585 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
586 {
587     return hbitmap_serialization_align(bitmap->bitmap) * BDRV_SECTOR_SIZE;
588 }
589
590 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
591                                       uint8_t *buf, uint64_t offset,
592                                       uint64_t bytes)
593 {
594     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
595     hbitmap_serialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
596                            bytes >> BDRV_SECTOR_BITS);
597 }
598
599 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
600                                         uint8_t *buf, uint64_t offset,
601                                         uint64_t bytes, bool finish)
602 {
603     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
604     hbitmap_deserialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
605                              bytes >> BDRV_SECTOR_BITS, finish);
606 }
607
608 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
609                                           uint64_t offset, uint64_t bytes,
610                                           bool finish)
611 {
612     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
613     hbitmap_deserialize_zeroes(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
614                                bytes >> BDRV_SECTOR_BITS, finish);
615 }
616
617 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
618                                         uint64_t offset, uint64_t bytes,
619                                         bool finish)
620 {
621     assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
622     hbitmap_deserialize_ones(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
623                              bytes >> BDRV_SECTOR_BITS, finish);
624 }
625
626 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
627 {
628     hbitmap_deserialize_finish(bitmap->bitmap);
629 }
630
631 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
632 {
633     BdrvDirtyBitmap *bitmap;
634     int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
635
636     if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
637         return;
638     }
639
640     bdrv_dirty_bitmaps_lock(bs);
641     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
642         if (!bdrv_dirty_bitmap_enabled(bitmap)) {
643             continue;
644         }
645         assert(!bdrv_dirty_bitmap_readonly(bitmap));
646         hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
647                     end_sector - (offset >> BDRV_SECTOR_BITS));
648     }
649     bdrv_dirty_bitmaps_unlock(bs);
650 }
651
652 /**
653  * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
654  */
655 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
656 {
657     hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset >> BDRV_SECTOR_BITS);
658 }
659
660 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
661 {
662     return hbitmap_count(bitmap->bitmap) << BDRV_SECTOR_BITS;
663 }
664
665 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
666 {
667     return hbitmap_count(bitmap->meta);
668 }
669
670 bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
671 {
672     return bitmap->readonly;
673 }
674
675 /* Called with BQL taken. */
676 void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
677 {
678     qemu_mutex_lock(bitmap->mutex);
679     bitmap->readonly = value;
680     qemu_mutex_unlock(bitmap->mutex);
681 }
682
683 bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
684 {
685     BdrvDirtyBitmap *bm;
686     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
687         if (bm->readonly) {
688             return true;
689         }
690     }
691
692     return false;
693 }
694
695 /* Called with BQL taken. */
696 void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload)
697 {
698     qemu_mutex_lock(bitmap->mutex);
699     bitmap->autoload = autoload;
700     qemu_mutex_unlock(bitmap->mutex);
701 }
702
703 bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
704 {
705     return bitmap->autoload;
706 }
707
708 /* Called with BQL taken. */
709 void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
710 {
711     qemu_mutex_lock(bitmap->mutex);
712     bitmap->persistent = persistent;
713     qemu_mutex_unlock(bitmap->mutex);
714 }
715
716 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
717 {
718     return bitmap->persistent;
719 }
720
721 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
722 {
723     BdrvDirtyBitmap *bm;
724     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
725         if (bm->persistent && !bm->readonly) {
726             return true;
727         }
728     }
729
730     return false;
731 }
732
733 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
734                                         BdrvDirtyBitmap *bitmap)
735 {
736     return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
737                             QLIST_NEXT(bitmap, list);
738 }
739
740 char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
741 {
742     return hbitmap_sha256(bitmap->bitmap, errp);
743 }
This page took 0.063586 seconds and 4 git commands to generate.