xref: /openbmc/qemu/block/dirty-bitmap.c (revision f67cf661f8b88afe8a5ea2f120583924cba9087f)
1ebab2259SFam Zheng /*
2ebab2259SFam Zheng  * Block Dirty Bitmap
3ebab2259SFam Zheng  *
41b6cc579SEric Blake  * Copyright (c) 2016-2017 Red Hat. Inc
5ebab2259SFam Zheng  *
6ebab2259SFam Zheng  * Permission is hereby granted, free of charge, to any person obtaining a copy
7ebab2259SFam Zheng  * of this software and associated documentation files (the "Software"), to deal
8ebab2259SFam Zheng  * in the Software without restriction, including without limitation the rights
9ebab2259SFam Zheng  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10ebab2259SFam Zheng  * copies of the Software, and to permit persons to whom the Software is
11ebab2259SFam Zheng  * furnished to do so, subject to the following conditions:
12ebab2259SFam Zheng  *
13ebab2259SFam Zheng  * The above copyright notice and this permission notice shall be included in
14ebab2259SFam Zheng  * all copies or substantial portions of the Software.
15ebab2259SFam Zheng  *
16ebab2259SFam Zheng  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17ebab2259SFam Zheng  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18ebab2259SFam Zheng  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19ebab2259SFam Zheng  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20ebab2259SFam Zheng  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ebab2259SFam Zheng  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22ebab2259SFam Zheng  * THE SOFTWARE.
23ebab2259SFam Zheng  */
24ebab2259SFam Zheng #include "qemu/osdep.h"
25da34e65cSMarkus Armbruster #include "qapi/error.h"
26ebab2259SFam Zheng #include "qemu-common.h"
27ebab2259SFam Zheng #include "trace.h"
28ebab2259SFam Zheng #include "block/block_int.h"
29ebab2259SFam Zheng #include "block/blockjob.h"
30ebab2259SFam Zheng 
31ebab2259SFam Zheng /**
32ebab2259SFam Zheng  * A BdrvDirtyBitmap can be in three possible states:
33ebab2259SFam Zheng  * (1) successor is NULL and disabled is false: full r/w mode
34ebab2259SFam Zheng  * (2) successor is NULL and disabled is true: read only mode ("disabled")
35ebab2259SFam Zheng  * (3) successor is set: frozen mode.
36ebab2259SFam Zheng  *     A frozen bitmap cannot be renamed, deleted, anonymized, cleared, set,
37ebab2259SFam Zheng  *     or enabled. A frozen bitmap can only abdicate() or reclaim().
38ebab2259SFam Zheng  */
39ebab2259SFam Zheng struct BdrvDirtyBitmap {
40b64bd51eSPaolo Bonzini     QemuMutex *mutex;
41ca759622SEric Blake     HBitmap *bitmap;            /* Dirty bitmap implementation */
42fb933437SFam Zheng     HBitmap *meta;              /* Meta dirty bitmap */
434f43e953SVladimir Sementsov-Ogievskiy     bool qmp_locked;            /* Bitmap is locked, it can't be modified
444f43e953SVladimir Sementsov-Ogievskiy                                    through QMP */
45ebab2259SFam Zheng     BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
46ebab2259SFam Zheng     char *name;                 /* Optional non-empty unique ID */
47993e6525SEric Blake     int64_t size;               /* Size of the bitmap, in bytes */
488bfc932eSVladimir Sementsov-Ogievskiy     bool disabled;              /* Bitmap is disabled. It ignores all writes to
498bfc932eSVladimir Sementsov-Ogievskiy                                    the device */
50dc162c8eSFam Zheng     int active_iterators;       /* How many iterators are active */
51d6883bc9SVladimir Sementsov-Ogievskiy     bool readonly;              /* Bitmap is read-only. This field also
52d6883bc9SVladimir Sementsov-Ogievskiy                                    prevents the respective image from being
53d6883bc9SVladimir Sementsov-Ogievskiy                                    modified (i.e. blocks writes and discards).
54d6883bc9SVladimir Sementsov-Ogievskiy                                    Such operations must fail and both the image
55d6883bc9SVladimir Sementsov-Ogievskiy                                    and this bitmap must remain unchanged while
56d6883bc9SVladimir Sementsov-Ogievskiy                                    this flag is set. */
57a88b179fSVladimir Sementsov-Ogievskiy     bool persistent;            /* bitmap must be saved to owner disk image */
589c98f145SVladimir Sementsov-Ogievskiy     bool migration;             /* Bitmap is selected for migration, it should
599c98f145SVladimir Sementsov-Ogievskiy                                    not be stored on the next inactivation
609c98f145SVladimir Sementsov-Ogievskiy                                    (persistent flag doesn't matter until next
619c98f145SVladimir Sementsov-Ogievskiy                                    invalidation).*/
62ebab2259SFam Zheng     QLIST_ENTRY(BdrvDirtyBitmap) list;
63ebab2259SFam Zheng };
64ebab2259SFam Zheng 
65dc162c8eSFam Zheng struct BdrvDirtyBitmapIter {
66dc162c8eSFam Zheng     HBitmapIter hbi;
67dc162c8eSFam Zheng     BdrvDirtyBitmap *bitmap;
68dc162c8eSFam Zheng };
69dc162c8eSFam Zheng 
702119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
712119882cSPaolo Bonzini {
722119882cSPaolo Bonzini     qemu_mutex_lock(&bs->dirty_bitmap_mutex);
732119882cSPaolo Bonzini }
742119882cSPaolo Bonzini 
752119882cSPaolo Bonzini static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
762119882cSPaolo Bonzini {
772119882cSPaolo Bonzini     qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
782119882cSPaolo Bonzini }
792119882cSPaolo Bonzini 
80b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
81b64bd51eSPaolo Bonzini {
82b64bd51eSPaolo Bonzini     qemu_mutex_lock(bitmap->mutex);
83b64bd51eSPaolo Bonzini }
84b64bd51eSPaolo Bonzini 
85b64bd51eSPaolo Bonzini void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
86b64bd51eSPaolo Bonzini {
87b64bd51eSPaolo Bonzini     qemu_mutex_unlock(bitmap->mutex);
88b64bd51eSPaolo Bonzini }
89b64bd51eSPaolo Bonzini 
902119882cSPaolo Bonzini /* Called with BQL or dirty_bitmap lock taken.  */
91ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
92ebab2259SFam Zheng {
93ebab2259SFam Zheng     BdrvDirtyBitmap *bm;
94ebab2259SFam Zheng 
95ebab2259SFam Zheng     assert(name);
96ebab2259SFam Zheng     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
97ebab2259SFam Zheng         if (bm->name && !strcmp(name, bm->name)) {
98ebab2259SFam Zheng             return bm;
99ebab2259SFam Zheng         }
100ebab2259SFam Zheng     }
101ebab2259SFam Zheng     return NULL;
102ebab2259SFam Zheng }
103ebab2259SFam Zheng 
1042119882cSPaolo Bonzini /* Called with BQL taken.  */
105ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
106ebab2259SFam Zheng                                           uint32_t granularity,
107ebab2259SFam Zheng                                           const char *name,
108ebab2259SFam Zheng                                           Error **errp)
109ebab2259SFam Zheng {
110ebab2259SFam Zheng     int64_t bitmap_size;
111ebab2259SFam Zheng     BdrvDirtyBitmap *bitmap;
112ebab2259SFam Zheng 
113993e6525SEric Blake     assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
114ebab2259SFam Zheng 
115ebab2259SFam Zheng     if (name && bdrv_find_dirty_bitmap(bs, name)) {
116ebab2259SFam Zheng         error_setg(errp, "Bitmap already exists: %s", name);
117ebab2259SFam Zheng         return NULL;
118ebab2259SFam Zheng     }
119993e6525SEric Blake     bitmap_size = bdrv_getlength(bs);
120ebab2259SFam Zheng     if (bitmap_size < 0) {
121ebab2259SFam Zheng         error_setg_errno(errp, -bitmap_size, "could not get length of device");
122ebab2259SFam Zheng         errno = -bitmap_size;
123ebab2259SFam Zheng         return NULL;
124ebab2259SFam Zheng     }
125ebab2259SFam Zheng     bitmap = g_new0(BdrvDirtyBitmap, 1);
126b64bd51eSPaolo Bonzini     bitmap->mutex = &bs->dirty_bitmap_mutex;
127ca759622SEric Blake     bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
128ebab2259SFam Zheng     bitmap->size = bitmap_size;
129ebab2259SFam Zheng     bitmap->name = g_strdup(name);
130ebab2259SFam Zheng     bitmap->disabled = false;
1312119882cSPaolo Bonzini     bdrv_dirty_bitmaps_lock(bs);
132ebab2259SFam Zheng     QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
1332119882cSPaolo Bonzini     bdrv_dirty_bitmaps_unlock(bs);
134ebab2259SFam Zheng     return bitmap;
135ebab2259SFam Zheng }
136ebab2259SFam Zheng 
137fb933437SFam Zheng /* bdrv_create_meta_dirty_bitmap
138fb933437SFam Zheng  *
139fb933437SFam Zheng  * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
140fb933437SFam Zheng  * when a dirty status bit in @bitmap is changed (either from reset to set or
141fb933437SFam Zheng  * the other way around), its respective meta dirty bitmap bit will be marked
142fb933437SFam Zheng  * dirty as well.
143fb933437SFam Zheng  *
144fb933437SFam Zheng  * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
145fb933437SFam Zheng  * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
146fb933437SFam Zheng  * track.
147fb933437SFam Zheng  */
148fb933437SFam Zheng void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
149fb933437SFam Zheng                                    int chunk_size)
150fb933437SFam Zheng {
151fb933437SFam Zheng     assert(!bitmap->meta);
152b64bd51eSPaolo Bonzini     qemu_mutex_lock(bitmap->mutex);
153fb933437SFam Zheng     bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
154fb933437SFam Zheng                                        chunk_size * BITS_PER_BYTE);
155b64bd51eSPaolo Bonzini     qemu_mutex_unlock(bitmap->mutex);
156fb933437SFam Zheng }
157fb933437SFam Zheng 
158fb933437SFam Zheng void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
159fb933437SFam Zheng {
160fb933437SFam Zheng     assert(bitmap->meta);
161b64bd51eSPaolo Bonzini     qemu_mutex_lock(bitmap->mutex);
162fb933437SFam Zheng     hbitmap_free_meta(bitmap->bitmap);
163fb933437SFam Zheng     bitmap->meta = NULL;
164b64bd51eSPaolo Bonzini     qemu_mutex_unlock(bitmap->mutex);
165fb933437SFam Zheng }
166fb933437SFam Zheng 
16715891facSFam Zheng int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
16815891facSFam Zheng {
169993e6525SEric Blake     return bitmap->size;
17015891facSFam Zheng }
17115891facSFam Zheng 
17215891facSFam Zheng const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
17315891facSFam Zheng {
17415891facSFam Zheng     return bitmap->name;
17515891facSFam Zheng }
17615891facSFam Zheng 
1772119882cSPaolo Bonzini /* Called with BQL taken.  */
178ebab2259SFam Zheng bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
179ebab2259SFam Zheng {
180ebab2259SFam Zheng     return bitmap->successor;
181ebab2259SFam Zheng }
182ebab2259SFam Zheng 
183993edc0cSJohn Snow /* Both conditions disallow user-modification via QMP. */
184993edc0cSJohn Snow bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap) {
185993edc0cSJohn Snow     return bdrv_dirty_bitmap_frozen(bitmap) ||
186993edc0cSJohn Snow            bdrv_dirty_bitmap_qmp_locked(bitmap);
187993edc0cSJohn Snow }
188993edc0cSJohn Snow 
1894f43e953SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked)
1904f43e953SVladimir Sementsov-Ogievskiy {
1914f43e953SVladimir Sementsov-Ogievskiy     qemu_mutex_lock(bitmap->mutex);
1924f43e953SVladimir Sementsov-Ogievskiy     bitmap->qmp_locked = qmp_locked;
1934f43e953SVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(bitmap->mutex);
1944f43e953SVladimir Sementsov-Ogievskiy }
1954f43e953SVladimir Sementsov-Ogievskiy 
1964f43e953SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap)
1974f43e953SVladimir Sementsov-Ogievskiy {
1984f43e953SVladimir Sementsov-Ogievskiy     return bitmap->qmp_locked;
1994f43e953SVladimir Sementsov-Ogievskiy }
2004f43e953SVladimir Sementsov-Ogievskiy 
2012119882cSPaolo Bonzini /* Called with BQL taken.  */
202ebab2259SFam Zheng bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
203ebab2259SFam Zheng {
204ebab2259SFam Zheng     return !(bitmap->disabled || bitmap->successor);
205ebab2259SFam Zheng }
206ebab2259SFam Zheng 
2072119882cSPaolo Bonzini /* Called with BQL taken.  */
208ebab2259SFam Zheng DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
209ebab2259SFam Zheng {
210ebab2259SFam Zheng     if (bdrv_dirty_bitmap_frozen(bitmap)) {
211ebab2259SFam Zheng         return DIRTY_BITMAP_STATUS_FROZEN;
2124f43e953SVladimir Sementsov-Ogievskiy     } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) {
2134f43e953SVladimir Sementsov-Ogievskiy         return DIRTY_BITMAP_STATUS_LOCKED;
214ebab2259SFam Zheng     } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
215ebab2259SFam Zheng         return DIRTY_BITMAP_STATUS_DISABLED;
216ebab2259SFam Zheng     } else {
217ebab2259SFam Zheng         return DIRTY_BITMAP_STATUS_ACTIVE;
218ebab2259SFam Zheng     }
219ebab2259SFam Zheng }
220ebab2259SFam Zheng 
221ebab2259SFam Zheng /**
222ebab2259SFam Zheng  * Create a successor bitmap destined to replace this bitmap after an operation.
223ebab2259SFam Zheng  * Requires that the bitmap is not frozen and has no successor.
2242119882cSPaolo Bonzini  * Called with BQL taken.
225ebab2259SFam Zheng  */
226ebab2259SFam Zheng int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
227ebab2259SFam Zheng                                        BdrvDirtyBitmap *bitmap, Error **errp)
228ebab2259SFam Zheng {
229ebab2259SFam Zheng     uint64_t granularity;
230ebab2259SFam Zheng     BdrvDirtyBitmap *child;
231ebab2259SFam Zheng 
232ebab2259SFam Zheng     if (bdrv_dirty_bitmap_frozen(bitmap)) {
233ebab2259SFam Zheng         error_setg(errp, "Cannot create a successor for a bitmap that is "
234ebab2259SFam Zheng                    "currently frozen");
235ebab2259SFam Zheng         return -1;
236ebab2259SFam Zheng     }
237ebab2259SFam Zheng     assert(!bitmap->successor);
238ebab2259SFam Zheng 
239ebab2259SFam Zheng     /* Create an anonymous successor */
240ebab2259SFam Zheng     granularity = bdrv_dirty_bitmap_granularity(bitmap);
241ebab2259SFam Zheng     child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
242ebab2259SFam Zheng     if (!child) {
243ebab2259SFam Zheng         return -1;
244ebab2259SFam Zheng     }
245ebab2259SFam Zheng 
246ebab2259SFam Zheng     /* Successor will be on or off based on our current state. */
247ebab2259SFam Zheng     child->disabled = bitmap->disabled;
248ebab2259SFam Zheng 
249ebab2259SFam Zheng     /* Install the successor and freeze the parent */
250ebab2259SFam Zheng     bitmap->successor = child;
251ebab2259SFam Zheng     return 0;
252ebab2259SFam Zheng }
253ebab2259SFam Zheng 
25492bcea40SVladimir Sementsov-Ogievskiy void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
25592bcea40SVladimir Sementsov-Ogievskiy {
25692bcea40SVladimir Sementsov-Ogievskiy     assert(!bdrv_dirty_bitmap_frozen(bitmap));
25792bcea40SVladimir Sementsov-Ogievskiy     bitmap->disabled = false;
25892bcea40SVladimir Sementsov-Ogievskiy }
25992bcea40SVladimir Sementsov-Ogievskiy 
260e73a265eSVladimir Sementsov-Ogievskiy /* Called with BQL taken. */
261e73a265eSVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
262e73a265eSVladimir Sementsov-Ogievskiy {
26358f72b96SVladimir Sementsov-Ogievskiy     assert(bitmap->mutex == bitmap->successor->mutex);
264e73a265eSVladimir Sementsov-Ogievskiy     qemu_mutex_lock(bitmap->mutex);
26558f72b96SVladimir Sementsov-Ogievskiy     bdrv_enable_dirty_bitmap_locked(bitmap->successor);
266e73a265eSVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(bitmap->mutex);
267e73a265eSVladimir Sementsov-Ogievskiy }
268e73a265eSVladimir Sementsov-Ogievskiy 
269b133c27fSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.  */
270b133c27fSPaolo Bonzini static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
271604ab74bSVladimir Sementsov-Ogievskiy {
272b133c27fSPaolo Bonzini     assert(!bitmap->active_iterators);
273b133c27fSPaolo Bonzini     assert(!bdrv_dirty_bitmap_frozen(bitmap));
274b133c27fSPaolo Bonzini     assert(!bitmap->meta);
275b133c27fSPaolo Bonzini     QLIST_REMOVE(bitmap, list);
276b133c27fSPaolo Bonzini     hbitmap_free(bitmap->bitmap);
277b133c27fSPaolo Bonzini     g_free(bitmap->name);
278b133c27fSPaolo Bonzini     g_free(bitmap);
279604ab74bSVladimir Sementsov-Ogievskiy }
280604ab74bSVladimir Sementsov-Ogievskiy 
281ebab2259SFam Zheng /**
282ebab2259SFam Zheng  * For a bitmap with a successor, yield our name to the successor,
283ebab2259SFam Zheng  * delete the old bitmap, and return a handle to the new bitmap.
2842119882cSPaolo Bonzini  * Called with BQL taken.
285ebab2259SFam Zheng  */
286ebab2259SFam Zheng BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
287ebab2259SFam Zheng                                             BdrvDirtyBitmap *bitmap,
288ebab2259SFam Zheng                                             Error **errp)
289ebab2259SFam Zheng {
290ebab2259SFam Zheng     char *name;
291ebab2259SFam Zheng     BdrvDirtyBitmap *successor = bitmap->successor;
292ebab2259SFam Zheng 
293ebab2259SFam Zheng     if (successor == NULL) {
294ebab2259SFam Zheng         error_setg(errp, "Cannot relinquish control if "
295ebab2259SFam Zheng                    "there's no successor present");
296ebab2259SFam Zheng         return NULL;
297ebab2259SFam Zheng     }
298ebab2259SFam Zheng 
299ebab2259SFam Zheng     name = bitmap->name;
300ebab2259SFam Zheng     bitmap->name = NULL;
301ebab2259SFam Zheng     successor->name = name;
302ebab2259SFam Zheng     bitmap->successor = NULL;
303a88b179fSVladimir Sementsov-Ogievskiy     successor->persistent = bitmap->persistent;
304a88b179fSVladimir Sementsov-Ogievskiy     bitmap->persistent = false;
305ebab2259SFam Zheng     bdrv_release_dirty_bitmap(bs, bitmap);
306ebab2259SFam Zheng 
307ebab2259SFam Zheng     return successor;
308ebab2259SFam Zheng }
309ebab2259SFam Zheng 
310ebab2259SFam Zheng /**
311ebab2259SFam Zheng  * In cases of failure where we can no longer safely delete the parent,
312ebab2259SFam Zheng  * we may wish to re-join the parent and child/successor.
313ebab2259SFam Zheng  * The merged parent will be un-frozen, but not explicitly re-enabled.
314044ee8e1SVladimir Sementsov-Ogievskiy  * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
315ebab2259SFam Zheng  */
316044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
317ebab2259SFam Zheng                                                   BdrvDirtyBitmap *parent,
318ebab2259SFam Zheng                                                   Error **errp)
319ebab2259SFam Zheng {
320044ee8e1SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *successor = parent->successor;
321ebab2259SFam Zheng 
322ebab2259SFam Zheng     if (!successor) {
323ebab2259SFam Zheng         error_setg(errp, "Cannot reclaim a successor when none is present");
324ebab2259SFam Zheng         return NULL;
325ebab2259SFam Zheng     }
326ebab2259SFam Zheng 
327fa000f2fSVladimir Sementsov-Ogievskiy     if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
328ebab2259SFam Zheng         error_setg(errp, "Merging of parent and successor bitmap failed");
329ebab2259SFam Zheng         return NULL;
330ebab2259SFam Zheng     }
331b133c27fSPaolo Bonzini     bdrv_release_dirty_bitmap_locked(successor);
332ebab2259SFam Zheng     parent->successor = NULL;
333ebab2259SFam Zheng 
334044ee8e1SVladimir Sementsov-Ogievskiy     return parent;
335044ee8e1SVladimir Sementsov-Ogievskiy }
336044ee8e1SVladimir Sementsov-Ogievskiy 
337044ee8e1SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */
338044ee8e1SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
339044ee8e1SVladimir Sementsov-Ogievskiy                                            BdrvDirtyBitmap *parent,
340044ee8e1SVladimir Sementsov-Ogievskiy                                            Error **errp)
341044ee8e1SVladimir Sementsov-Ogievskiy {
342044ee8e1SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *ret;
343044ee8e1SVladimir Sementsov-Ogievskiy 
344044ee8e1SVladimir Sementsov-Ogievskiy     qemu_mutex_lock(parent->mutex);
345044ee8e1SVladimir Sementsov-Ogievskiy     ret = bdrv_reclaim_dirty_bitmap_locked(bs, parent, errp);
346604ab74bSVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(parent->mutex);
347604ab74bSVladimir Sementsov-Ogievskiy 
348044ee8e1SVladimir Sementsov-Ogievskiy     return ret;
349ebab2259SFam Zheng }
350ebab2259SFam Zheng 
351ebab2259SFam Zheng /**
352ebab2259SFam Zheng  * Truncates _all_ bitmaps attached to a BDS.
3532119882cSPaolo Bonzini  * Called with BQL taken.
354ebab2259SFam Zheng  */
3551b6cc579SEric Blake void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
356ebab2259SFam Zheng {
357ebab2259SFam Zheng     BdrvDirtyBitmap *bitmap;
358ebab2259SFam Zheng 
3592119882cSPaolo Bonzini     bdrv_dirty_bitmaps_lock(bs);
360ebab2259SFam Zheng     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
361ebab2259SFam Zheng         assert(!bdrv_dirty_bitmap_frozen(bitmap));
362dc162c8eSFam Zheng         assert(!bitmap->active_iterators);
363ca759622SEric Blake         hbitmap_truncate(bitmap->bitmap, bytes);
364993e6525SEric Blake         bitmap->size = bytes;
365ebab2259SFam Zheng     }
3662119882cSPaolo Bonzini     bdrv_dirty_bitmaps_unlock(bs);
367ebab2259SFam Zheng }
368ebab2259SFam Zheng 
3692119882cSPaolo Bonzini /* Called with BQL taken.  */
370ebab2259SFam Zheng void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
371ebab2259SFam Zheng {
372b133c27fSPaolo Bonzini     bdrv_dirty_bitmaps_lock(bs);
373b133c27fSPaolo Bonzini     bdrv_release_dirty_bitmap_locked(bitmap);
374b133c27fSPaolo Bonzini     bdrv_dirty_bitmaps_unlock(bs);
375ebab2259SFam Zheng }
376ebab2259SFam Zheng 
377ebab2259SFam Zheng /**
378ebab2259SFam Zheng  * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
379ebab2259SFam Zheng  * There must not be any frozen bitmaps attached.
38056f364e6SVladimir Sementsov-Ogievskiy  * This function does not remove persistent bitmaps from the storage.
3812119882cSPaolo Bonzini  * Called with BQL taken.
382ebab2259SFam Zheng  */
383ebab2259SFam Zheng void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
384ebab2259SFam Zheng {
385b133c27fSPaolo Bonzini     BdrvDirtyBitmap *bm, *next;
386b133c27fSPaolo Bonzini 
387b133c27fSPaolo Bonzini     bdrv_dirty_bitmaps_lock(bs);
388b133c27fSPaolo Bonzini     QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
389b133c27fSPaolo Bonzini         if (bdrv_dirty_bitmap_name(bm)) {
390b133c27fSPaolo Bonzini             bdrv_release_dirty_bitmap_locked(bm);
391b133c27fSPaolo Bonzini         }
392b133c27fSPaolo Bonzini     }
393b133c27fSPaolo Bonzini     bdrv_dirty_bitmaps_unlock(bs);
394615b5dcfSVladimir Sementsov-Ogievskiy }
395615b5dcfSVladimir Sementsov-Ogievskiy 
396615b5dcfSVladimir Sementsov-Ogievskiy /**
39756f364e6SVladimir Sementsov-Ogievskiy  * Remove persistent dirty bitmap from the storage if it exists.
39856f364e6SVladimir Sementsov-Ogievskiy  * Absence of bitmap is not an error, because we have the following scenario:
39956f364e6SVladimir Sementsov-Ogievskiy  * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
40056f364e6SVladimir Sementsov-Ogievskiy  * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
40156f364e6SVladimir Sementsov-Ogievskiy  * not fail.
40256f364e6SVladimir Sementsov-Ogievskiy  * This function doesn't release corresponding BdrvDirtyBitmap.
40356f364e6SVladimir Sementsov-Ogievskiy  */
40456f364e6SVladimir Sementsov-Ogievskiy void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
40556f364e6SVladimir Sementsov-Ogievskiy                                          const char *name,
40656f364e6SVladimir Sementsov-Ogievskiy                                          Error **errp)
40756f364e6SVladimir Sementsov-Ogievskiy {
40856f364e6SVladimir Sementsov-Ogievskiy     if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
40956f364e6SVladimir Sementsov-Ogievskiy         bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
41056f364e6SVladimir Sementsov-Ogievskiy     }
41156f364e6SVladimir Sementsov-Ogievskiy }
41256f364e6SVladimir Sementsov-Ogievskiy 
413ebab2259SFam Zheng void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
414ebab2259SFam Zheng {
4158b1402ceSVladimir Sementsov-Ogievskiy     bdrv_dirty_bitmap_lock(bitmap);
416ebab2259SFam Zheng     assert(!bdrv_dirty_bitmap_frozen(bitmap));
417ebab2259SFam Zheng     bitmap->disabled = true;
4188b1402ceSVladimir Sementsov-Ogievskiy     bdrv_dirty_bitmap_unlock(bitmap);
419ebab2259SFam Zheng }
420ebab2259SFam Zheng 
421ebab2259SFam Zheng void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
422ebab2259SFam Zheng {
4238b1402ceSVladimir Sementsov-Ogievskiy     bdrv_dirty_bitmap_lock(bitmap);
42492bcea40SVladimir Sementsov-Ogievskiy     bdrv_enable_dirty_bitmap_locked(bitmap);
4258b1402ceSVladimir Sementsov-Ogievskiy     bdrv_dirty_bitmap_unlock(bitmap);
426ebab2259SFam Zheng }
427ebab2259SFam Zheng 
428ebab2259SFam Zheng BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
429ebab2259SFam Zheng {
430ebab2259SFam Zheng     BdrvDirtyBitmap *bm;
431ebab2259SFam Zheng     BlockDirtyInfoList *list = NULL;
432ebab2259SFam Zheng     BlockDirtyInfoList **plist = &list;
433ebab2259SFam Zheng 
4342119882cSPaolo Bonzini     bdrv_dirty_bitmaps_lock(bs);
435ebab2259SFam Zheng     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
436ebab2259SFam Zheng         BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
437ebab2259SFam Zheng         BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
4389a46dba7SEric Blake         info->count = bdrv_get_dirty_count(bm);
439ebab2259SFam Zheng         info->granularity = bdrv_dirty_bitmap_granularity(bm);
440ebab2259SFam Zheng         info->has_name = !!bm->name;
441ebab2259SFam Zheng         info->name = g_strdup(bm->name);
442ebab2259SFam Zheng         info->status = bdrv_dirty_bitmap_status(bm);
443*f67cf661SEric Blake         info->persistent = bm->persistent;
444ebab2259SFam Zheng         entry->value = info;
445ebab2259SFam Zheng         *plist = entry;
446ebab2259SFam Zheng         plist = &entry->next;
447ebab2259SFam Zheng     }
4482119882cSPaolo Bonzini     bdrv_dirty_bitmaps_unlock(bs);
449ebab2259SFam Zheng 
450ebab2259SFam Zheng     return list;
451ebab2259SFam Zheng }
452ebab2259SFam Zheng 
453b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */
4543b5d4df0SEric Blake bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
4553b5d4df0SEric Blake                            int64_t offset)
456ebab2259SFam Zheng {
457ebab2259SFam Zheng     if (bitmap) {
458ca759622SEric Blake         return hbitmap_get(bitmap->bitmap, offset);
459ebab2259SFam Zheng     } else {
4603b5d4df0SEric Blake         return false;
461ebab2259SFam Zheng     }
462ebab2259SFam Zheng }
463ebab2259SFam Zheng 
464ebab2259SFam Zheng /**
465ebab2259SFam Zheng  * Chooses a default granularity based on the existing cluster size,
466ebab2259SFam Zheng  * but clamped between [4K, 64K]. Defaults to 64K in the case that there
467ebab2259SFam Zheng  * is no cluster size information available.
468ebab2259SFam Zheng  */
469ebab2259SFam Zheng uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
470ebab2259SFam Zheng {
471ebab2259SFam Zheng     BlockDriverInfo bdi;
472ebab2259SFam Zheng     uint32_t granularity;
473ebab2259SFam Zheng 
474ebab2259SFam Zheng     if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
475ebab2259SFam Zheng         granularity = MAX(4096, bdi.cluster_size);
476ebab2259SFam Zheng         granularity = MIN(65536, granularity);
477ebab2259SFam Zheng     } else {
478ebab2259SFam Zheng         granularity = 65536;
479ebab2259SFam Zheng     }
480ebab2259SFam Zheng 
481ebab2259SFam Zheng     return granularity;
482ebab2259SFam Zheng }
483ebab2259SFam Zheng 
484ba06ff1aSVladimir Sementsov-Ogievskiy uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
485ebab2259SFam Zheng {
486ca759622SEric Blake     return 1U << hbitmap_granularity(bitmap->bitmap);
487ebab2259SFam Zheng }
488ebab2259SFam Zheng 
489715a74d8SEric Blake BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
490ebab2259SFam Zheng {
491dc162c8eSFam Zheng     BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
492715a74d8SEric Blake     hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
493dc162c8eSFam Zheng     iter->bitmap = bitmap;
494dc162c8eSFam Zheng     bitmap->active_iterators++;
495dc162c8eSFam Zheng     return iter;
496dc162c8eSFam Zheng }
497dc162c8eSFam Zheng 
4986d3f4049SFam Zheng BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
4996d3f4049SFam Zheng {
5006d3f4049SFam Zheng     BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
5016d3f4049SFam Zheng     hbitmap_iter_init(&iter->hbi, bitmap->meta, 0);
5026d3f4049SFam Zheng     iter->bitmap = bitmap;
5036d3f4049SFam Zheng     bitmap->active_iterators++;
5046d3f4049SFam Zheng     return iter;
5056d3f4049SFam Zheng }
5066d3f4049SFam Zheng 
507dc162c8eSFam Zheng void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
508dc162c8eSFam Zheng {
509dc162c8eSFam Zheng     if (!iter) {
510dc162c8eSFam Zheng         return;
511dc162c8eSFam Zheng     }
512dc162c8eSFam Zheng     assert(iter->bitmap->active_iterators > 0);
513dc162c8eSFam Zheng     iter->bitmap->active_iterators--;
514dc162c8eSFam Zheng     g_free(iter);
515dc162c8eSFam Zheng }
516dc162c8eSFam Zheng 
517dc162c8eSFam Zheng int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
518dc162c8eSFam Zheng {
51919c021e1SVladimir Sementsov-Ogievskiy     return hbitmap_iter_next(&iter->hbi);
520ebab2259SFam Zheng }
521ebab2259SFam Zheng 
522b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */
523b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
524e0d7f73eSEric Blake                                   int64_t offset, int64_t bytes)
525ebab2259SFam Zheng {
526ebab2259SFam Zheng     assert(bdrv_dirty_bitmap_enabled(bitmap));
527d6883bc9SVladimir Sementsov-Ogievskiy     assert(!bdrv_dirty_bitmap_readonly(bitmap));
528ca759622SEric Blake     hbitmap_set(bitmap->bitmap, offset, bytes);
529ebab2259SFam Zheng }
530ebab2259SFam Zheng 
531b64bd51eSPaolo Bonzini void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
532e0d7f73eSEric Blake                            int64_t offset, int64_t bytes)
533b64bd51eSPaolo Bonzini {
534b64bd51eSPaolo Bonzini     bdrv_dirty_bitmap_lock(bitmap);
535e0d7f73eSEric Blake     bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
536b64bd51eSPaolo Bonzini     bdrv_dirty_bitmap_unlock(bitmap);
537b64bd51eSPaolo Bonzini }
538b64bd51eSPaolo Bonzini 
539b64bd51eSPaolo Bonzini /* Called within bdrv_dirty_bitmap_lock..unlock */
540b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
541e0d7f73eSEric Blake                                     int64_t offset, int64_t bytes)
542ebab2259SFam Zheng {
543ebab2259SFam Zheng     assert(bdrv_dirty_bitmap_enabled(bitmap));
544d6883bc9SVladimir Sementsov-Ogievskiy     assert(!bdrv_dirty_bitmap_readonly(bitmap));
545ca759622SEric Blake     hbitmap_reset(bitmap->bitmap, offset, bytes);
546ebab2259SFam Zheng }
547ebab2259SFam Zheng 
548b64bd51eSPaolo Bonzini void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
549e0d7f73eSEric Blake                              int64_t offset, int64_t bytes)
550b64bd51eSPaolo Bonzini {
551b64bd51eSPaolo Bonzini     bdrv_dirty_bitmap_lock(bitmap);
552e0d7f73eSEric Blake     bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
553b64bd51eSPaolo Bonzini     bdrv_dirty_bitmap_unlock(bitmap);
554b64bd51eSPaolo Bonzini }
555b64bd51eSPaolo Bonzini 
556ebab2259SFam Zheng void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
557ebab2259SFam Zheng {
558d6883bc9SVladimir Sementsov-Ogievskiy     assert(!bdrv_dirty_bitmap_readonly(bitmap));
559b64bd51eSPaolo Bonzini     bdrv_dirty_bitmap_lock(bitmap);
560ebab2259SFam Zheng     if (!out) {
561ebab2259SFam Zheng         hbitmap_reset_all(bitmap->bitmap);
562ebab2259SFam Zheng     } else {
563ebab2259SFam Zheng         HBitmap *backup = bitmap->bitmap;
564ca759622SEric Blake         bitmap->bitmap = hbitmap_alloc(bitmap->size,
565ebab2259SFam Zheng                                        hbitmap_granularity(backup));
566ebab2259SFam Zheng         *out = backup;
567ebab2259SFam Zheng     }
568b64bd51eSPaolo Bonzini     bdrv_dirty_bitmap_unlock(bitmap);
569ebab2259SFam Zheng }
570ebab2259SFam Zheng 
57156bd6624SVladimir Sementsov-Ogievskiy void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
572ebab2259SFam Zheng {
573ebab2259SFam Zheng     HBitmap *tmp = bitmap->bitmap;
574d6883bc9SVladimir Sementsov-Ogievskiy     assert(!bdrv_dirty_bitmap_readonly(bitmap));
57556bd6624SVladimir Sementsov-Ogievskiy     bitmap->bitmap = backup;
576ebab2259SFam Zheng     hbitmap_free(tmp);
577ebab2259SFam Zheng }
578ebab2259SFam Zheng 
579882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
58086f6ae67SEric Blake                                               uint64_t offset, uint64_t bytes)
581882c36f5SVladimir Sementsov-Ogievskiy {
582ca759622SEric Blake     return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
583882c36f5SVladimir Sementsov-Ogievskiy }
584882c36f5SVladimir Sementsov-Ogievskiy 
585882c36f5SVladimir Sementsov-Ogievskiy uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
586882c36f5SVladimir Sementsov-Ogievskiy {
587ca759622SEric Blake     return hbitmap_serialization_align(bitmap->bitmap);
588882c36f5SVladimir Sementsov-Ogievskiy }
589882c36f5SVladimir Sementsov-Ogievskiy 
590882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
59186f6ae67SEric Blake                                       uint8_t *buf, uint64_t offset,
59286f6ae67SEric Blake                                       uint64_t bytes)
593882c36f5SVladimir Sementsov-Ogievskiy {
594ca759622SEric Blake     hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
595882c36f5SVladimir Sementsov-Ogievskiy }
596882c36f5SVladimir Sementsov-Ogievskiy 
597882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
59886f6ae67SEric Blake                                         uint8_t *buf, uint64_t offset,
59986f6ae67SEric Blake                                         uint64_t bytes, bool finish)
600882c36f5SVladimir Sementsov-Ogievskiy {
601ca759622SEric Blake     hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
602882c36f5SVladimir Sementsov-Ogievskiy }
603882c36f5SVladimir Sementsov-Ogievskiy 
604882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
60586f6ae67SEric Blake                                           uint64_t offset, uint64_t bytes,
606882c36f5SVladimir Sementsov-Ogievskiy                                           bool finish)
607882c36f5SVladimir Sementsov-Ogievskiy {
608ca759622SEric Blake     hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
609882c36f5SVladimir Sementsov-Ogievskiy }
610882c36f5SVladimir Sementsov-Ogievskiy 
6116bdc8b71SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
61286f6ae67SEric Blake                                         uint64_t offset, uint64_t bytes,
6136bdc8b71SVladimir Sementsov-Ogievskiy                                         bool finish)
6146bdc8b71SVladimir Sementsov-Ogievskiy {
615ca759622SEric Blake     hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
6166bdc8b71SVladimir Sementsov-Ogievskiy }
6176bdc8b71SVladimir Sementsov-Ogievskiy 
618882c36f5SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
619882c36f5SVladimir Sementsov-Ogievskiy {
620882c36f5SVladimir Sementsov-Ogievskiy     hbitmap_deserialize_finish(bitmap->bitmap);
621882c36f5SVladimir Sementsov-Ogievskiy }
622882c36f5SVladimir Sementsov-Ogievskiy 
6230fdf1a4fSEric Blake void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
624ebab2259SFam Zheng {
625ebab2259SFam Zheng     BdrvDirtyBitmap *bitmap;
6262119882cSPaolo Bonzini 
6272119882cSPaolo Bonzini     if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
6282119882cSPaolo Bonzini         return;
6292119882cSPaolo Bonzini     }
6302119882cSPaolo Bonzini 
6312119882cSPaolo Bonzini     bdrv_dirty_bitmaps_lock(bs);
632ebab2259SFam Zheng     QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
633ebab2259SFam Zheng         if (!bdrv_dirty_bitmap_enabled(bitmap)) {
634ebab2259SFam Zheng             continue;
635ebab2259SFam Zheng         }
636d6883bc9SVladimir Sementsov-Ogievskiy         assert(!bdrv_dirty_bitmap_readonly(bitmap));
637ca759622SEric Blake         hbitmap_set(bitmap->bitmap, offset, bytes);
638ebab2259SFam Zheng     }
6392119882cSPaolo Bonzini     bdrv_dirty_bitmaps_unlock(bs);
640ebab2259SFam Zheng }
641ebab2259SFam Zheng 
642ebab2259SFam Zheng /**
643dc162c8eSFam Zheng  * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
644ebab2259SFam Zheng  */
645715a74d8SEric Blake void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
646ebab2259SFam Zheng {
647ca759622SEric Blake     hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
648ebab2259SFam Zheng }
649ebab2259SFam Zheng 
650ebab2259SFam Zheng int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
651ebab2259SFam Zheng {
652ca759622SEric Blake     return hbitmap_count(bitmap->bitmap);
653ebab2259SFam Zheng }
6546d3f4049SFam Zheng 
6556d3f4049SFam Zheng int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
6566d3f4049SFam Zheng {
6576d3f4049SFam Zheng     return hbitmap_count(bitmap->meta);
6586d3f4049SFam Zheng }
659d6883bc9SVladimir Sementsov-Ogievskiy 
660d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
661d6883bc9SVladimir Sementsov-Ogievskiy {
662d6883bc9SVladimir Sementsov-Ogievskiy     return bitmap->readonly;
663d6883bc9SVladimir Sementsov-Ogievskiy }
664d6883bc9SVladimir Sementsov-Ogievskiy 
665d6883bc9SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */
666d6883bc9SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
667d6883bc9SVladimir Sementsov-Ogievskiy {
668d6883bc9SVladimir Sementsov-Ogievskiy     qemu_mutex_lock(bitmap->mutex);
669d6883bc9SVladimir Sementsov-Ogievskiy     bitmap->readonly = value;
670d6883bc9SVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(bitmap->mutex);
671d6883bc9SVladimir Sementsov-Ogievskiy }
672d6883bc9SVladimir Sementsov-Ogievskiy 
673d6883bc9SVladimir Sementsov-Ogievskiy bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
674d6883bc9SVladimir Sementsov-Ogievskiy {
675d6883bc9SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bm;
676d6883bc9SVladimir Sementsov-Ogievskiy     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
677d6883bc9SVladimir Sementsov-Ogievskiy         if (bm->readonly) {
678d6883bc9SVladimir Sementsov-Ogievskiy             return true;
679d6883bc9SVladimir Sementsov-Ogievskiy         }
680d6883bc9SVladimir Sementsov-Ogievskiy     }
681d6883bc9SVladimir Sementsov-Ogievskiy 
682d6883bc9SVladimir Sementsov-Ogievskiy     return false;
683d6883bc9SVladimir Sementsov-Ogievskiy }
684a0319aacSVladimir Sementsov-Ogievskiy 
685a0319aacSVladimir Sementsov-Ogievskiy /* Called with BQL taken. */
686a88b179fSVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
687a88b179fSVladimir Sementsov-Ogievskiy {
688a88b179fSVladimir Sementsov-Ogievskiy     qemu_mutex_lock(bitmap->mutex);
689a88b179fSVladimir Sementsov-Ogievskiy     bitmap->persistent = persistent;
690a88b179fSVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(bitmap->mutex);
691a88b179fSVladimir Sementsov-Ogievskiy }
692a88b179fSVladimir Sementsov-Ogievskiy 
6939c98f145SVladimir Sementsov-Ogievskiy /* Called with BQL taken. */
6949c98f145SVladimir Sementsov-Ogievskiy void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration)
6959c98f145SVladimir Sementsov-Ogievskiy {
6969c98f145SVladimir Sementsov-Ogievskiy     qemu_mutex_lock(bitmap->mutex);
6979c98f145SVladimir Sementsov-Ogievskiy     bitmap->migration = migration;
6989c98f145SVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(bitmap->mutex);
6999c98f145SVladimir Sementsov-Ogievskiy }
7009c98f145SVladimir Sementsov-Ogievskiy 
701a88b179fSVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
702a88b179fSVladimir Sementsov-Ogievskiy {
7039c98f145SVladimir Sementsov-Ogievskiy     return bitmap->persistent && !bitmap->migration;
704a88b179fSVladimir Sementsov-Ogievskiy }
705a88b179fSVladimir Sementsov-Ogievskiy 
706a88b179fSVladimir Sementsov-Ogievskiy bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
707a88b179fSVladimir Sementsov-Ogievskiy {
708a88b179fSVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bm;
709a88b179fSVladimir Sementsov-Ogievskiy     QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
7109c98f145SVladimir Sementsov-Ogievskiy         if (bm->persistent && !bm->readonly && !bm->migration) {
711a88b179fSVladimir Sementsov-Ogievskiy             return true;
712a88b179fSVladimir Sementsov-Ogievskiy         }
713a88b179fSVladimir Sementsov-Ogievskiy     }
714a88b179fSVladimir Sementsov-Ogievskiy 
715a88b179fSVladimir Sementsov-Ogievskiy     return false;
716a88b179fSVladimir Sementsov-Ogievskiy }
7173dd10a06SVladimir Sementsov-Ogievskiy 
7183dd10a06SVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
7193dd10a06SVladimir Sementsov-Ogievskiy                                         BdrvDirtyBitmap *bitmap)
7203dd10a06SVladimir Sementsov-Ogievskiy {
7213dd10a06SVladimir Sementsov-Ogievskiy     return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
7223dd10a06SVladimir Sementsov-Ogievskiy                             QLIST_NEXT(bitmap, list);
7233dd10a06SVladimir Sementsov-Ogievskiy }
724a3b52535SVladimir Sementsov-Ogievskiy 
725a3b52535SVladimir Sementsov-Ogievskiy char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
726a3b52535SVladimir Sementsov-Ogievskiy {
727a3b52535SVladimir Sementsov-Ogievskiy     return hbitmap_sha256(bitmap->bitmap, errp);
728a3b52535SVladimir Sementsov-Ogievskiy }
72956207df5SVladimir Sementsov-Ogievskiy 
73076d570dcSVladimir Sementsov-Ogievskiy int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset,
73176d570dcSVladimir Sementsov-Ogievskiy                                     uint64_t bytes)
73256207df5SVladimir Sementsov-Ogievskiy {
73376d570dcSVladimir Sementsov-Ogievskiy     return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
73456207df5SVladimir Sementsov-Ogievskiy }
735b598e531SVladimir Sementsov-Ogievskiy 
736a78a1a48SVladimir Sementsov-Ogievskiy bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
737a78a1a48SVladimir Sementsov-Ogievskiy                                        uint64_t *offset, uint64_t *bytes)
738a78a1a48SVladimir Sementsov-Ogievskiy {
739a78a1a48SVladimir Sementsov-Ogievskiy     return hbitmap_next_dirty_area(bitmap->bitmap, offset, bytes);
740a78a1a48SVladimir Sementsov-Ogievskiy }
741a78a1a48SVladimir Sementsov-Ogievskiy 
742b598e531SVladimir Sementsov-Ogievskiy void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
743fa000f2fSVladimir Sementsov-Ogievskiy                              HBitmap **backup, Error **errp)
744b598e531SVladimir Sementsov-Ogievskiy {
745fa000f2fSVladimir Sementsov-Ogievskiy     bool ret;
746fa000f2fSVladimir Sementsov-Ogievskiy 
747b598e531SVladimir Sementsov-Ogievskiy     /* only bitmaps from one bds are supported */
748b598e531SVladimir Sementsov-Ogievskiy     assert(dest->mutex == src->mutex);
749b598e531SVladimir Sementsov-Ogievskiy 
750b598e531SVladimir Sementsov-Ogievskiy     qemu_mutex_lock(dest->mutex);
751b598e531SVladimir Sementsov-Ogievskiy 
752283d7a04SJohn Snow     if (bdrv_dirty_bitmap_user_locked(dest)) {
753283d7a04SJohn Snow         error_setg(errp, "Bitmap '%s' is currently in use by another"
754283d7a04SJohn Snow         " operation and cannot be modified", dest->name);
75506bf5006SVladimir Sementsov-Ogievskiy         goto out;
75606bf5006SVladimir Sementsov-Ogievskiy     }
75706bf5006SVladimir Sementsov-Ogievskiy 
75806bf5006SVladimir Sementsov-Ogievskiy     if (bdrv_dirty_bitmap_readonly(dest)) {
75906bf5006SVladimir Sementsov-Ogievskiy         error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
76006bf5006SVladimir Sementsov-Ogievskiy                    dest->name);
76106bf5006SVladimir Sementsov-Ogievskiy         goto out;
76206bf5006SVladimir Sementsov-Ogievskiy     }
763b598e531SVladimir Sementsov-Ogievskiy 
764fa000f2fSVladimir Sementsov-Ogievskiy     if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
765b598e531SVladimir Sementsov-Ogievskiy         error_setg(errp, "Bitmaps are incompatible and can't be merged");
76606bf5006SVladimir Sementsov-Ogievskiy         goto out;
767b598e531SVladimir Sementsov-Ogievskiy     }
768b598e531SVladimir Sementsov-Ogievskiy 
769fa000f2fSVladimir Sementsov-Ogievskiy     if (backup) {
770fa000f2fSVladimir Sementsov-Ogievskiy         *backup = dest->bitmap;
771fa000f2fSVladimir Sementsov-Ogievskiy         dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
772fa000f2fSVladimir Sementsov-Ogievskiy         ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
773fa000f2fSVladimir Sementsov-Ogievskiy     } else {
774fa000f2fSVladimir Sementsov-Ogievskiy         ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
775fa000f2fSVladimir Sementsov-Ogievskiy     }
776fa000f2fSVladimir Sementsov-Ogievskiy     assert(ret);
777fa000f2fSVladimir Sementsov-Ogievskiy 
77806bf5006SVladimir Sementsov-Ogievskiy out:
779b598e531SVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(dest->mutex);
780b598e531SVladimir Sementsov-Ogievskiy }
781