blob: da1b91166f48f9875be5819db516356442e78d2f [file] [log] [blame]
Fam Zhengebab2252016-03-08 12:44:55 +08001/*
2 * Block Dirty Bitmap
3 *
Eric Blake1b6cc572017-09-25 09:55:11 -05004 * Copyright (c) 2016-2017 Red Hat. Inc
Fam Zhengebab2252016-03-08 12:44:55 +08005 *
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"
Markus Armbrusterda34e652016-03-14 09:01:28 +010025#include "qapi/error.h"
Fam Zhengebab2252016-03-08 12:44:55 +080026#include "trace.h"
27#include "block/block_int.h"
28#include "block/blockjob.h"
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +030029#include "qemu/main-loop.h"
Fam Zhengebab2252016-03-08 12:44:55 +080030
Fam Zhengebab2252016-03-08 12:44:55 +080031struct BdrvDirtyBitmap {
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +030032 BlockDriverState *bs;
Eric Blakeca759622017-09-25 09:55:26 -050033 HBitmap *bitmap; /* Dirty bitmap implementation */
John Snow27a1b302019-03-12 12:05:48 -040034 bool busy; /* Bitmap is busy, it can't be used via QMP */
John Snow21d23762019-03-12 12:05:48 -040035 BdrvDirtyBitmap *successor; /* Anonymous child, if any. */
Fam Zhengebab2252016-03-08 12:44:55 +080036 char *name; /* Optional non-empty unique ID */
Eric Blake993e6522017-09-25 09:55:13 -050037 int64_t size; /* Size of the bitmap, in bytes */
Vladimir Sementsov-Ogievskiy8bfc9322017-06-28 15:05:09 +030038 bool disabled; /* Bitmap is disabled. It ignores all writes to
39 the device */
Fam Zhengdc162c82016-10-13 17:58:21 -040040 int active_iterators; /* How many iterators are active */
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +030041 bool readonly; /* Bitmap is read-only. This field also
42 prevents the respective image from being
43 modified (i.e. blocks writes and discards).
44 Such operations must fail and both the image
45 and this bitmap must remain unchanged while
46 this flag is set. */
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +030047 bool persistent; /* bitmap must be saved to owner disk image */
John Snowb0f45552019-03-12 12:05:49 -040048 bool inconsistent; /* bitmap is persistent, but inconsistent.
49 It cannot be used at all in any way, except
50 a QMP user can remove it. */
John Snowc4e4b0f2019-07-29 16:35:54 -040051 bool skip_store; /* We are either migrating or deleting this
52 * bitmap; it should not be stored on the next
53 * inactivation. */
Fam Zhengebab2252016-03-08 12:44:55 +080054 QLIST_ENTRY(BdrvDirtyBitmap) list;
55};
56
Fam Zhengdc162c82016-10-13 17:58:21 -040057struct BdrvDirtyBitmapIter {
58 HBitmapIter hbi;
59 BdrvDirtyBitmap *bitmap;
60};
61
Paolo Bonzini21198822017-06-05 14:39:03 +020062static inline void bdrv_dirty_bitmaps_lock(BlockDriverState *bs)
63{
64 qemu_mutex_lock(&bs->dirty_bitmap_mutex);
65}
66
67static inline void bdrv_dirty_bitmaps_unlock(BlockDriverState *bs)
68{
69 qemu_mutex_unlock(&bs->dirty_bitmap_mutex);
70}
71
Paolo Bonzinib64bd512017-06-05 14:39:05 +020072void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap)
73{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +030074 bdrv_dirty_bitmaps_lock(bitmap->bs);
Paolo Bonzinib64bd512017-06-05 14:39:05 +020075}
76
77void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap)
78{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +030079 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Paolo Bonzinib64bd512017-06-05 14:39:05 +020080}
81
Paolo Bonzini21198822017-06-05 14:39:03 +020082/* Called with BQL or dirty_bitmap lock taken. */
Fam Zhengebab2252016-03-08 12:44:55 +080083BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
84{
85 BdrvDirtyBitmap *bm;
86
87 assert(name);
88 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
89 if (bm->name && !strcmp(name, bm->name)) {
90 return bm;
91 }
92 }
93 return NULL;
94}
95
Paolo Bonzini21198822017-06-05 14:39:03 +020096/* Called with BQL taken. */
Fam Zhengebab2252016-03-08 12:44:55 +080097BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
98 uint32_t granularity,
99 const char *name,
100 Error **errp)
101{
102 int64_t bitmap_size;
103 BdrvDirtyBitmap *bitmap;
Fam Zhengebab2252016-03-08 12:44:55 +0800104
Eric Blake993e6522017-09-25 09:55:13 -0500105 assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);
Fam Zhengebab2252016-03-08 12:44:55 +0800106
Eric Blakecf7c49c2019-11-13 20:46:33 -0600107 if (name) {
108 if (bdrv_find_dirty_bitmap(bs, name)) {
109 error_setg(errp, "Bitmap already exists: %s", name);
110 return NULL;
111 }
112 if (strlen(name) > BDRV_BITMAP_MAX_NAME_SIZE) {
113 error_setg(errp, "Bitmap name too long: %s", name);
114 return NULL;
115 }
Fam Zhengebab2252016-03-08 12:44:55 +0800116 }
Eric Blake993e6522017-09-25 09:55:13 -0500117 bitmap_size = bdrv_getlength(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800118 if (bitmap_size < 0) {
119 error_setg_errno(errp, -bitmap_size, "could not get length of device");
120 errno = -bitmap_size;
121 return NULL;
122 }
123 bitmap = g_new0(BdrvDirtyBitmap, 1);
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300124 bitmap->bs = bs;
Eric Blakeca759622017-09-25 09:55:26 -0500125 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
Fam Zhengebab2252016-03-08 12:44:55 +0800126 bitmap->size = bitmap_size;
127 bitmap->name = g_strdup(name);
128 bitmap->disabled = false;
Paolo Bonzini21198822017-06-05 14:39:03 +0200129 bdrv_dirty_bitmaps_lock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800130 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
Paolo Bonzini21198822017-06-05 14:39:03 +0200131 bdrv_dirty_bitmaps_unlock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800132 return bitmap;
133}
134
Fam Zheng15891fa2016-10-13 17:58:25 -0400135int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
136{
Eric Blake993e6522017-09-25 09:55:13 -0500137 return bitmap->size;
Fam Zheng15891fa2016-10-13 17:58:25 -0400138}
139
140const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
141{
142 return bitmap->name;
143}
144
Paolo Bonzini21198822017-06-05 14:39:03 +0200145/* Called with BQL taken. */
John Snow50a47252019-03-12 12:05:48 -0400146bool bdrv_dirty_bitmap_has_successor(BdrvDirtyBitmap *bitmap)
Fam Zhengebab2252016-03-08 12:44:55 +0800147{
148 return bitmap->successor;
149}
150
John Snow3ae96d62019-03-12 12:05:49 -0400151static bool bdrv_dirty_bitmap_busy(const BdrvDirtyBitmap *bitmap)
John Snow27a1b302019-03-12 12:05:48 -0400152{
153 return bitmap->busy;
John Snow993edc02018-10-29 16:23:16 -0400154}
155
John Snow27a1b302019-03-12 12:05:48 -0400156void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy)
Vladimir Sementsov-Ogievskiy4f43e952018-03-13 15:34:00 -0400157{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300158 bdrv_dirty_bitmaps_lock(bitmap->bs);
John Snow27a1b302019-03-12 12:05:48 -0400159 bitmap->busy = busy;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300160 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Vladimir Sementsov-Ogievskiy4f43e952018-03-13 15:34:00 -0400161}
162
Paolo Bonzini21198822017-06-05 14:39:03 +0200163/* Called with BQL taken. */
Fam Zhengebab2252016-03-08 12:44:55 +0800164bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
165{
John Snow8b2e20f2019-03-12 12:05:48 -0400166 return !bitmap->disabled;
Fam Zhengebab2252016-03-08 12:44:55 +0800167}
168
John Snow4db6ceb2019-03-12 12:05:48 -0400169/* Called with BQL taken. */
170static bool bdrv_dirty_bitmap_recording(BdrvDirtyBitmap *bitmap)
171{
172 return !bitmap->disabled || (bitmap->successor &&
173 !bitmap->successor->disabled);
174}
175
John Snow3ae96d62019-03-12 12:05:49 -0400176int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags,
177 Error **errp)
178{
179 if ((flags & BDRV_BITMAP_BUSY) && bdrv_dirty_bitmap_busy(bitmap)) {
180 error_setg(errp, "Bitmap '%s' is currently in use by another"
181 " operation and cannot be used", bitmap->name);
182 return -1;
183 }
184
185 if ((flags & BDRV_BITMAP_RO) && bdrv_dirty_bitmap_readonly(bitmap)) {
186 error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
187 bitmap->name);
188 return -1;
189 }
190
191 if ((flags & BDRV_BITMAP_INCONSISTENT) &&
192 bdrv_dirty_bitmap_inconsistent(bitmap)) {
193 error_setg(errp, "Bitmap '%s' is inconsistent and cannot be used",
194 bitmap->name);
195 error_append_hint(errp, "Try block-dirty-bitmap-remove to delete"
Eric Blake94075c22021-07-09 10:39:49 -0500196 " this bitmap from disk\n");
John Snow3ae96d62019-03-12 12:05:49 -0400197 return -1;
198 }
199
200 return 0;
201}
202
Fam Zhengebab2252016-03-08 12:44:55 +0800203/**
204 * Create a successor bitmap destined to replace this bitmap after an operation.
John Snow27a1b302019-03-12 12:05:48 -0400205 * Requires that the bitmap is not marked busy and has no successor.
John Snow8b2e20f2019-03-12 12:05:48 -0400206 * The successor will be enabled if the parent bitmap was.
Paolo Bonzini21198822017-06-05 14:39:03 +0200207 * Called with BQL taken.
Fam Zhengebab2252016-03-08 12:44:55 +0800208 */
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300209int bdrv_dirty_bitmap_create_successor(BdrvDirtyBitmap *bitmap, Error **errp)
Fam Zhengebab2252016-03-08 12:44:55 +0800210{
211 uint64_t granularity;
212 BdrvDirtyBitmap *child;
213
John Snow3ae96d62019-03-12 12:05:49 -0400214 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY, errp)) {
Fam Zhengebab2252016-03-08 12:44:55 +0800215 return -1;
216 }
John Snow50a47252019-03-12 12:05:48 -0400217 if (bdrv_dirty_bitmap_has_successor(bitmap)) {
218 error_setg(errp, "Cannot create a successor for a bitmap that already "
219 "has one");
220 return -1;
221 }
Fam Zhengebab2252016-03-08 12:44:55 +0800222
223 /* Create an anonymous successor */
224 granularity = bdrv_dirty_bitmap_granularity(bitmap);
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300225 child = bdrv_create_dirty_bitmap(bitmap->bs, granularity, NULL, errp);
Fam Zhengebab2252016-03-08 12:44:55 +0800226 if (!child) {
227 return -1;
228 }
229
230 /* Successor will be on or off based on our current state. */
231 child->disabled = bitmap->disabled;
John Snow8b2e20f2019-03-12 12:05:48 -0400232 bitmap->disabled = true;
Fam Zhengebab2252016-03-08 12:44:55 +0800233
John Snow27a1b302019-03-12 12:05:48 -0400234 /* Install the successor and mark the parent as busy */
Fam Zhengebab2252016-03-08 12:44:55 +0800235 bitmap->successor = child;
John Snow27a1b302019-03-12 12:05:48 -0400236 bitmap->busy = true;
Fam Zhengebab2252016-03-08 12:44:55 +0800237 return 0;
238}
239
Vladimir Sementsov-Ogievskiy92bcea42018-07-04 02:12:49 -0400240void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
241{
Vladimir Sementsov-Ogievskiy92bcea42018-07-04 02:12:49 -0400242 bitmap->disabled = false;
243}
244
Vladimir Sementsov-Ogievskiye73a2652018-03-13 15:33:59 -0400245/* Called with BQL taken. */
246void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
247{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300248 assert(bitmap->bs == bitmap->successor->bs);
249 bdrv_dirty_bitmaps_lock(bitmap->bs);
Vladimir Sementsov-Ogievskiy58f72b92018-07-04 02:12:49 -0400250 bdrv_enable_dirty_bitmap_locked(bitmap->successor);
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300251 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Vladimir Sementsov-Ogievskiye73a2652018-03-13 15:33:59 -0400252}
253
Paolo Bonzinib133c272018-06-11 14:53:31 -0400254/* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */
255static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
Vladimir Sementsov-Ogievskiy604ab742018-03-13 15:34:00 -0400256{
Paolo Bonzinib133c272018-06-11 14:53:31 -0400257 assert(!bitmap->active_iterators);
John Snow27a1b302019-03-12 12:05:48 -0400258 assert(!bdrv_dirty_bitmap_busy(bitmap));
John Snow50a47252019-03-12 12:05:48 -0400259 assert(!bdrv_dirty_bitmap_has_successor(bitmap));
Paolo Bonzinib133c272018-06-11 14:53:31 -0400260 QLIST_REMOVE(bitmap, list);
261 hbitmap_free(bitmap->bitmap);
262 g_free(bitmap->name);
263 g_free(bitmap);
Vladimir Sementsov-Ogievskiy604ab742018-03-13 15:34:00 -0400264}
265
Fam Zhengebab2252016-03-08 12:44:55 +0800266/**
267 * For a bitmap with a successor, yield our name to the successor,
268 * delete the old bitmap, and return a handle to the new bitmap.
Paolo Bonzini21198822017-06-05 14:39:03 +0200269 * Called with BQL taken.
Fam Zhengebab2252016-03-08 12:44:55 +0800270 */
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300271BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BdrvDirtyBitmap *bitmap,
Fam Zhengebab2252016-03-08 12:44:55 +0800272 Error **errp)
273{
274 char *name;
275 BdrvDirtyBitmap *successor = bitmap->successor;
276
277 if (successor == NULL) {
278 error_setg(errp, "Cannot relinquish control if "
279 "there's no successor present");
280 return NULL;
281 }
282
283 name = bitmap->name;
284 bitmap->name = NULL;
285 successor->name = name;
286 bitmap->successor = NULL;
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +0300287 successor->persistent = bitmap->persistent;
288 bitmap->persistent = false;
John Snow27a1b302019-03-12 12:05:48 -0400289 bitmap->busy = false;
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300290 bdrv_release_dirty_bitmap(bitmap);
Fam Zhengebab2252016-03-08 12:44:55 +0800291
292 return successor;
293}
294
295/**
296 * In cases of failure where we can no longer safely delete the parent,
297 * we may wish to re-join the parent and child/successor.
John Snow27a1b302019-03-12 12:05:48 -0400298 * The merged parent will be marked as not busy.
John Snow8b2e20f2019-03-12 12:05:48 -0400299 * The marged parent will be enabled if and only if the successor was enabled.
Vladimir Sementsov-Ogievskiy044ee8e2018-03-13 15:34:00 -0400300 * Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken.
Fam Zhengebab2252016-03-08 12:44:55 +0800301 */
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300302BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BdrvDirtyBitmap *parent,
Vladimir Sementsov-Ogievskiy044ee8e2018-03-13 15:34:00 -0400303 Error **errp)
Fam Zhengebab2252016-03-08 12:44:55 +0800304{
Vladimir Sementsov-Ogievskiy044ee8e2018-03-13 15:34:00 -0400305 BdrvDirtyBitmap *successor = parent->successor;
Fam Zhengebab2252016-03-08 12:44:55 +0800306
307 if (!successor) {
308 error_setg(errp, "Cannot reclaim a successor when none is present");
309 return NULL;
310 }
311
Vladimir Sementsov-Ogievskiyfa000f22018-10-29 16:23:15 -0400312 if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) {
Fam Zhengebab2252016-03-08 12:44:55 +0800313 error_setg(errp, "Merging of parent and successor bitmap failed");
314 return NULL;
315 }
John Snow8b2e20f2019-03-12 12:05:48 -0400316
317 parent->disabled = successor->disabled;
John Snow27a1b302019-03-12 12:05:48 -0400318 parent->busy = false;
Paolo Bonzinib133c272018-06-11 14:53:31 -0400319 bdrv_release_dirty_bitmap_locked(successor);
Fam Zhengebab2252016-03-08 12:44:55 +0800320 parent->successor = NULL;
321
Vladimir Sementsov-Ogievskiy044ee8e2018-03-13 15:34:00 -0400322 return parent;
323}
324
325/* Called with BQL taken. */
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300326BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BdrvDirtyBitmap *parent,
Vladimir Sementsov-Ogievskiy044ee8e2018-03-13 15:34:00 -0400327 Error **errp)
328{
329 BdrvDirtyBitmap *ret;
330
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300331 bdrv_dirty_bitmaps_lock(parent->bs);
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300332 ret = bdrv_reclaim_dirty_bitmap_locked(parent, errp);
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300333 bdrv_dirty_bitmaps_unlock(parent->bs);
Vladimir Sementsov-Ogievskiy604ab742018-03-13 15:34:00 -0400334
Vladimir Sementsov-Ogievskiy044ee8e2018-03-13 15:34:00 -0400335 return ret;
Fam Zhengebab2252016-03-08 12:44:55 +0800336}
337
338/**
339 * Truncates _all_ bitmaps attached to a BDS.
Paolo Bonzini21198822017-06-05 14:39:03 +0200340 * Called with BQL taken.
Fam Zhengebab2252016-03-08 12:44:55 +0800341 */
Eric Blake1b6cc572017-09-25 09:55:11 -0500342void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
Fam Zhengebab2252016-03-08 12:44:55 +0800343{
344 BdrvDirtyBitmap *bitmap;
Fam Zhengebab2252016-03-08 12:44:55 +0800345
Paolo Bonzini21198822017-06-05 14:39:03 +0200346 bdrv_dirty_bitmaps_lock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800347 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
John Snow27a1b302019-03-12 12:05:48 -0400348 assert(!bdrv_dirty_bitmap_busy(bitmap));
John Snow50a47252019-03-12 12:05:48 -0400349 assert(!bdrv_dirty_bitmap_has_successor(bitmap));
Fam Zhengdc162c82016-10-13 17:58:21 -0400350 assert(!bitmap->active_iterators);
Eric Blakeca759622017-09-25 09:55:26 -0500351 hbitmap_truncate(bitmap->bitmap, bytes);
Eric Blake993e6522017-09-25 09:55:13 -0500352 bitmap->size = bytes;
Fam Zhengebab2252016-03-08 12:44:55 +0800353 }
Paolo Bonzini21198822017-06-05 14:39:03 +0200354 bdrv_dirty_bitmaps_unlock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800355}
356
Paolo Bonzini21198822017-06-05 14:39:03 +0200357/* Called with BQL taken. */
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300358void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap)
Fam Zhengebab2252016-03-08 12:44:55 +0800359{
Vladimir Sementsov-Ogievskiy5deb6cb2019-09-16 17:19:09 +0300360 BlockDriverState *bs = bitmap->bs;
361
Paolo Bonzinib133c272018-06-11 14:53:31 -0400362 bdrv_dirty_bitmaps_lock(bs);
363 bdrv_release_dirty_bitmap_locked(bitmap);
364 bdrv_dirty_bitmaps_unlock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800365}
366
367/**
368 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
John Snow27a1b302019-03-12 12:05:48 -0400369 * There must not be any busy bitmaps attached.
Vladimir Sementsov-Ogievskiy56f364e2017-06-28 15:05:27 +0300370 * This function does not remove persistent bitmaps from the storage.
Paolo Bonzini21198822017-06-05 14:39:03 +0200371 * Called with BQL taken.
Fam Zhengebab2252016-03-08 12:44:55 +0800372 */
373void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
374{
Paolo Bonzinib133c272018-06-11 14:53:31 -0400375 BdrvDirtyBitmap *bm, *next;
376
377 bdrv_dirty_bitmaps_lock(bs);
378 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
379 if (bdrv_dirty_bitmap_name(bm)) {
380 bdrv_release_dirty_bitmap_locked(bm);
381 }
382 }
383 bdrv_dirty_bitmaps_unlock(bs);
Vladimir Sementsov-Ogievskiy615b5dc2017-06-28 15:05:30 +0300384}
385
386/**
Vladimir Sementsov-Ogievskiy56f364e2017-06-28 15:05:27 +0300387 * Remove persistent dirty bitmap from the storage if it exists.
388 * Absence of bitmap is not an error, because we have the following scenario:
389 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
390 * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
391 * not fail.
392 * This function doesn't release corresponding BdrvDirtyBitmap.
393 */
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300394static int coroutine_fn
395bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
396 Error **errp)
Vladimir Sementsov-Ogievskiy56f364e2017-06-28 15:05:27 +0300397{
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300398 if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
399 return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
Vladimir Sementsov-Ogievskiy56f364e2017-06-28 15:05:27 +0300400 }
Vladimir Sementsov-Ogievskiyb56a1e32019-09-20 11:25:42 +0300401
402 return 0;
Vladimir Sementsov-Ogievskiy56f364e2017-06-28 15:05:27 +0300403}
404
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300405typedef struct BdrvRemovePersistentDirtyBitmapCo {
406 BlockDriverState *bs;
407 const char *name;
408 Error **errp;
409 int ret;
410} BdrvRemovePersistentDirtyBitmapCo;
411
412static void coroutine_fn
413bdrv_co_remove_persistent_dirty_bitmap_entry(void *opaque)
414{
415 BdrvRemovePersistentDirtyBitmapCo *s = opaque;
416
417 s->ret = bdrv_co_remove_persistent_dirty_bitmap(s->bs, s->name, s->errp);
418 aio_wait_kick();
419}
420
421int bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
422 Error **errp)
423{
424 if (qemu_in_coroutine()) {
425 return bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
426 } else {
427 Coroutine *co;
428 BdrvRemovePersistentDirtyBitmapCo s = {
429 .bs = bs,
430 .name = name,
431 .errp = errp,
432 .ret = -EINPROGRESS,
433 };
434
435 co = qemu_coroutine_create(bdrv_co_remove_persistent_dirty_bitmap_entry,
436 &s);
437 bdrv_coroutine_enter(bs, co);
438 BDRV_POLL_WHILE(bs, s.ret == -EINPROGRESS);
439
440 return s.ret;
441 }
442}
443
Eric Blakeef893b52020-05-12 20:16:42 -0500444bool
445bdrv_supports_persistent_dirty_bitmap(BlockDriverState *bs)
446{
447 if (bs->drv && bs->drv->bdrv_supports_persistent_dirty_bitmap) {
448 return bs->drv->bdrv_supports_persistent_dirty_bitmap(bs);
449 }
450 return false;
451}
452
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300453static bool coroutine_fn
454bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
455 uint32_t granularity, Error **errp)
Vladimir Sementsov-Ogievskiy85cc8a42019-09-20 11:25:41 +0300456{
457 BlockDriver *drv = bs->drv;
458
459 if (!drv) {
460 error_setg_errno(errp, ENOMEDIUM,
461 "Can't store persistent bitmaps to %s",
462 bdrv_get_device_or_node_name(bs));
463 return false;
464 }
465
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300466 if (!drv->bdrv_co_can_store_new_dirty_bitmap) {
Vladimir Sementsov-Ogievskiy85cc8a42019-09-20 11:25:41 +0300467 error_setg_errno(errp, ENOTSUP,
468 "Can't store persistent bitmaps to %s",
469 bdrv_get_device_or_node_name(bs));
470 return false;
471 }
472
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300473 return drv->bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
474}
475
476typedef struct BdrvCanStoreNewDirtyBitmapCo {
477 BlockDriverState *bs;
478 const char *name;
479 uint32_t granularity;
480 Error **errp;
481 bool ret;
482
483 bool in_progress;
484} BdrvCanStoreNewDirtyBitmapCo;
485
486static void coroutine_fn bdrv_co_can_store_new_dirty_bitmap_entry(void *opaque)
487{
488 BdrvCanStoreNewDirtyBitmapCo *s = opaque;
489
490 s->ret = bdrv_co_can_store_new_dirty_bitmap(s->bs, s->name, s->granularity,
491 s->errp);
492 s->in_progress = false;
493 aio_wait_kick();
494}
495
496bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
497 uint32_t granularity, Error **errp)
498{
Emanuele Giuseppe Esposito384a48f2022-03-03 10:15:50 -0500499 IO_CODE();
Vladimir Sementsov-Ogievskiyd2c30802019-09-20 11:25:43 +0300500 if (qemu_in_coroutine()) {
501 return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
502 } else {
503 Coroutine *co;
504 BdrvCanStoreNewDirtyBitmapCo s = {
505 .bs = bs,
506 .name = name,
507 .granularity = granularity,
508 .errp = errp,
509 .in_progress = true,
510 };
511
512 co = qemu_coroutine_create(bdrv_co_can_store_new_dirty_bitmap_entry,
513 &s);
514 bdrv_coroutine_enter(bs, co);
515 BDRV_POLL_WHILE(bs, s.in_progress);
516
517 return s.ret;
518 }
Vladimir Sementsov-Ogievskiy85cc8a42019-09-20 11:25:41 +0300519}
520
Fam Zhengebab2252016-03-08 12:44:55 +0800521void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
522{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300523 bdrv_dirty_bitmaps_lock(bitmap->bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800524 bitmap->disabled = true;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300525 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800526}
527
528void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
529{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300530 bdrv_dirty_bitmaps_lock(bitmap->bs);
Vladimir Sementsov-Ogievskiy92bcea42018-07-04 02:12:49 -0400531 bdrv_enable_dirty_bitmap_locked(bitmap);
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300532 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800533}
534
535BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
536{
537 BdrvDirtyBitmap *bm;
538 BlockDirtyInfoList *list = NULL;
Eric Blakec3033fd2021-01-13 16:10:12 -0600539 BlockDirtyInfoList **tail = &list;
Fam Zhengebab2252016-03-08 12:44:55 +0800540
Paolo Bonzini21198822017-06-05 14:39:03 +0200541 bdrv_dirty_bitmaps_lock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800542 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
543 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
Eric Blakec3033fd2021-01-13 16:10:12 -0600544
Eric Blake9a46dba2017-09-25 09:55:18 -0500545 info->count = bdrv_get_dirty_count(bm);
Fam Zhengebab2252016-03-08 12:44:55 +0800546 info->granularity = bdrv_dirty_bitmap_granularity(bm);
547 info->has_name = !!bm->name;
548 info->name = g_strdup(bm->name);
John Snow4db6ceb2019-03-12 12:05:48 -0400549 info->recording = bdrv_dirty_bitmap_recording(bm);
John Snow27a1b302019-03-12 12:05:48 -0400550 info->busy = bdrv_dirty_bitmap_busy(bm);
Eric Blakef67cf662019-02-19 17:49:43 -0500551 info->persistent = bm->persistent;
John Snowb0f45552019-03-12 12:05:49 -0400552 info->has_inconsistent = bm->inconsistent;
553 info->inconsistent = bm->inconsistent;
Eric Blakec3033fd2021-01-13 16:10:12 -0600554 QAPI_LIST_APPEND(tail, info);
Fam Zhengebab2252016-03-08 12:44:55 +0800555 }
Paolo Bonzini21198822017-06-05 14:39:03 +0200556 bdrv_dirty_bitmaps_unlock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800557
558 return list;
559}
560
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200561/* Called within bdrv_dirty_bitmap_lock..unlock */
John Snow28636b82019-07-29 16:35:53 -0400562bool bdrv_dirty_bitmap_get_locked(BdrvDirtyBitmap *bitmap, int64_t offset)
Fam Zhengebab2252016-03-08 12:44:55 +0800563{
John Snow28636b82019-07-29 16:35:53 -0400564 return hbitmap_get(bitmap->bitmap, offset);
565}
566
567bool bdrv_dirty_bitmap_get(BdrvDirtyBitmap *bitmap, int64_t offset)
568{
569 bool ret;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300570 bdrv_dirty_bitmaps_lock(bitmap->bs);
John Snow28636b82019-07-29 16:35:53 -0400571 ret = bdrv_dirty_bitmap_get_locked(bitmap, offset);
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300572 bdrv_dirty_bitmaps_unlock(bitmap->bs);
John Snow28636b82019-07-29 16:35:53 -0400573
574 return ret;
Fam Zhengebab2252016-03-08 12:44:55 +0800575}
576
577/**
578 * Chooses a default granularity based on the existing cluster size,
579 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
580 * is no cluster size information available.
581 */
582uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
583{
584 BlockDriverInfo bdi;
585 uint32_t granularity;
586
587 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
588 granularity = MAX(4096, bdi.cluster_size);
589 granularity = MIN(65536, granularity);
590 } else {
591 granularity = 65536;
592 }
593
594 return granularity;
595}
596
Vladimir Sementsov-Ogievskiyba06ff12017-06-28 15:05:05 +0300597uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
Fam Zhengebab2252016-03-08 12:44:55 +0800598{
Eric Blakeca759622017-09-25 09:55:26 -0500599 return 1U << hbitmap_granularity(bitmap->bitmap);
Fam Zhengebab2252016-03-08 12:44:55 +0800600}
601
Eric Blake715a74d2017-09-25 09:55:16 -0500602BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
Fam Zhengebab2252016-03-08 12:44:55 +0800603{
Fam Zhengdc162c82016-10-13 17:58:21 -0400604 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
Eric Blake715a74d2017-09-25 09:55:16 -0500605 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
Fam Zhengdc162c82016-10-13 17:58:21 -0400606 iter->bitmap = bitmap;
607 bitmap->active_iterators++;
608 return iter;
609}
610
611void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
612{
613 if (!iter) {
614 return;
615 }
616 assert(iter->bitmap->active_iterators > 0);
617 iter->bitmap->active_iterators--;
618 g_free(iter);
619}
620
621int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
622{
Vladimir Sementsov-Ogievskiy19c021e2019-01-15 18:26:50 -0500623 return hbitmap_iter_next(&iter->hbi);
Fam Zhengebab2252016-03-08 12:44:55 +0800624}
625
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200626/* Called within bdrv_dirty_bitmap_lock..unlock */
627void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
Eric Blakee0d7f732017-09-25 09:55:20 -0500628 int64_t offset, int64_t bytes)
Fam Zhengebab2252016-03-08 12:44:55 +0800629{
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300630 assert(!bdrv_dirty_bitmap_readonly(bitmap));
Eric Blakeca759622017-09-25 09:55:26 -0500631 hbitmap_set(bitmap->bitmap, offset, bytes);
Fam Zhengebab2252016-03-08 12:44:55 +0800632}
633
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200634void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
Eric Blakee0d7f732017-09-25 09:55:20 -0500635 int64_t offset, int64_t bytes)
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200636{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300637 bdrv_dirty_bitmaps_lock(bitmap->bs);
Eric Blakee0d7f732017-09-25 09:55:20 -0500638 bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300639 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200640}
641
642/* Called within bdrv_dirty_bitmap_lock..unlock */
643void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
Eric Blakee0d7f732017-09-25 09:55:20 -0500644 int64_t offset, int64_t bytes)
Fam Zhengebab2252016-03-08 12:44:55 +0800645{
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300646 assert(!bdrv_dirty_bitmap_readonly(bitmap));
Eric Blakeca759622017-09-25 09:55:26 -0500647 hbitmap_reset(bitmap->bitmap, offset, bytes);
Fam Zhengebab2252016-03-08 12:44:55 +0800648}
649
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200650void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
Eric Blakee0d7f732017-09-25 09:55:20 -0500651 int64_t offset, int64_t bytes)
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200652{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300653 bdrv_dirty_bitmaps_lock(bitmap->bs);
Eric Blakee0d7f732017-09-25 09:55:20 -0500654 bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300655 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Paolo Bonzinib64bd512017-06-05 14:39:05 +0200656}
657
Fam Zhengebab2252016-03-08 12:44:55 +0800658void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
659{
Emanuele Giuseppe Esposito967d7902022-03-03 10:15:58 -0500660 IO_CODE();
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300661 assert(!bdrv_dirty_bitmap_readonly(bitmap));
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300662 bdrv_dirty_bitmaps_lock(bitmap->bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800663 if (!out) {
664 hbitmap_reset_all(bitmap->bitmap);
665 } else {
666 HBitmap *backup = bitmap->bitmap;
Eric Blakeca759622017-09-25 09:55:26 -0500667 bitmap->bitmap = hbitmap_alloc(bitmap->size,
Fam Zhengebab2252016-03-08 12:44:55 +0800668 hbitmap_granularity(backup));
669 *out = backup;
670 }
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300671 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800672}
673
Vladimir Sementsov-Ogievskiy56bd6622018-10-29 16:23:14 -0400674void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
Fam Zhengebab2252016-03-08 12:44:55 +0800675{
676 HBitmap *tmp = bitmap->bitmap;
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300677 assert(!bdrv_dirty_bitmap_readonly(bitmap));
Emanuele Giuseppe Espositob4ad82a2022-03-03 10:15:57 -0500678 GLOBAL_STATE_CODE();
Vladimir Sementsov-Ogievskiy56bd6622018-10-29 16:23:14 -0400679 bitmap->bitmap = backup;
Fam Zhengebab2252016-03-08 12:44:55 +0800680 hbitmap_free(tmp);
681}
682
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400683uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
Eric Blake86f6ae62017-09-25 09:55:14 -0500684 uint64_t offset, uint64_t bytes)
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400685{
Eric Blakeca759622017-09-25 09:55:26 -0500686 return hbitmap_serialization_size(bitmap->bitmap, offset, bytes);
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400687}
688
689uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
690{
Eric Blakeca759622017-09-25 09:55:26 -0500691 return hbitmap_serialization_align(bitmap->bitmap);
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400692}
693
Vladimir Sementsov-Ogievskiy35f428b2021-02-24 13:47:02 +0300694/* Return the disk size covered by a chunk of serialized bitmap data. */
695uint64_t bdrv_dirty_bitmap_serialization_coverage(int serialized_chunk_size,
696 const BdrvDirtyBitmap *bitmap)
697{
698 uint64_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
699 uint64_t limit = granularity * (serialized_chunk_size << 3);
700
701 assert(QEMU_IS_ALIGNED(limit,
702 bdrv_dirty_bitmap_serialization_align(bitmap)));
703 return limit;
704}
705
706
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400707void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
Eric Blake86f6ae62017-09-25 09:55:14 -0500708 uint8_t *buf, uint64_t offset,
709 uint64_t bytes)
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400710{
Eric Blakeca759622017-09-25 09:55:26 -0500711 hbitmap_serialize_part(bitmap->bitmap, buf, offset, bytes);
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400712}
713
714void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
Eric Blake86f6ae62017-09-25 09:55:14 -0500715 uint8_t *buf, uint64_t offset,
716 uint64_t bytes, bool finish)
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400717{
Eric Blakeca759622017-09-25 09:55:26 -0500718 hbitmap_deserialize_part(bitmap->bitmap, buf, offset, bytes, finish);
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400719}
720
721void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
Eric Blake86f6ae62017-09-25 09:55:14 -0500722 uint64_t offset, uint64_t bytes,
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400723 bool finish)
724{
Eric Blakeca759622017-09-25 09:55:26 -0500725 hbitmap_deserialize_zeroes(bitmap->bitmap, offset, bytes, finish);
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400726}
727
Vladimir Sementsov-Ogievskiy6bdc8b72017-06-28 15:05:06 +0300728void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
Eric Blake86f6ae62017-09-25 09:55:14 -0500729 uint64_t offset, uint64_t bytes,
Vladimir Sementsov-Ogievskiy6bdc8b72017-06-28 15:05:06 +0300730 bool finish)
731{
Eric Blakeca759622017-09-25 09:55:26 -0500732 hbitmap_deserialize_ones(bitmap->bitmap, offset, bytes, finish);
Vladimir Sementsov-Ogievskiy6bdc8b72017-06-28 15:05:06 +0300733}
734
Vladimir Sementsov-Ogievskiy882c36f2016-10-13 17:58:28 -0400735void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
736{
737 hbitmap_deserialize_finish(bitmap->bitmap);
738}
739
Eric Blake0fdf1a42017-09-25 09:55:25 -0500740void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
Fam Zhengebab2252016-03-08 12:44:55 +0800741{
742 BdrvDirtyBitmap *bitmap;
Emanuele Giuseppe Esposito967d7902022-03-03 10:15:58 -0500743 IO_CODE();
Paolo Bonzini21198822017-06-05 14:39:03 +0200744
745 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
746 return;
747 }
748
749 bdrv_dirty_bitmaps_lock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800750 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
751 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
752 continue;
753 }
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300754 assert(!bdrv_dirty_bitmap_readonly(bitmap));
Eric Blakeca759622017-09-25 09:55:26 -0500755 hbitmap_set(bitmap->bitmap, offset, bytes);
Fam Zhengebab2252016-03-08 12:44:55 +0800756 }
Paolo Bonzini21198822017-06-05 14:39:03 +0200757 bdrv_dirty_bitmaps_unlock(bs);
Fam Zhengebab2252016-03-08 12:44:55 +0800758}
759
760/**
Fam Zhengdc162c82016-10-13 17:58:21 -0400761 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
Fam Zhengebab2252016-03-08 12:44:55 +0800762 */
Eric Blake715a74d2017-09-25 09:55:16 -0500763void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
Fam Zhengebab2252016-03-08 12:44:55 +0800764{
Eric Blakeca759622017-09-25 09:55:26 -0500765 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset);
Fam Zhengebab2252016-03-08 12:44:55 +0800766}
767
768int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
769{
Eric Blakeca759622017-09-25 09:55:26 -0500770 return hbitmap_count(bitmap->bitmap);
Fam Zhengebab2252016-03-08 12:44:55 +0800771}
Fam Zheng6d3f4042016-10-13 17:58:30 -0400772
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300773bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
774{
775 return bitmap->readonly;
776}
777
778/* Called with BQL taken. */
779void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
780{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300781 bdrv_dirty_bitmaps_lock(bitmap->bs);
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300782 bitmap->readonly = value;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300783 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Vladimir Sementsov-Ogievskiyd6883bc2017-06-28 15:05:10 +0300784}
785
786bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
787{
788 BdrvDirtyBitmap *bm;
789 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
790 if (bm->readonly) {
791 return true;
792 }
793 }
794
795 return false;
796}
Vladimir Sementsov-Ogievskiya0319aa2017-06-28 15:05:15 +0300797
Vladimir Sementsov-Ogievskiy7ae89a02020-05-22 01:06:44 +0300798bool bdrv_has_named_bitmaps(BlockDriverState *bs)
799{
800 BdrvDirtyBitmap *bm;
801
802 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
803 if (bdrv_dirty_bitmap_name(bm)) {
804 return true;
805 }
806 }
807
808 return false;
809}
810
Vladimir Sementsov-Ogievskiya0319aa2017-06-28 15:05:15 +0300811/* Called with BQL taken. */
Eric Blake796a3792019-03-12 12:05:49 -0400812void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap, bool persistent)
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +0300813{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300814 bdrv_dirty_bitmaps_lock(bitmap->bs);
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +0300815 bitmap->persistent = persistent;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300816 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +0300817}
818
Vladimir Sementsov-Ogievskiy9c98f142018-10-29 16:23:17 -0400819/* Called with BQL taken. */
John Snowb0f45552019-03-12 12:05:49 -0400820void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
821{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300822 bdrv_dirty_bitmaps_lock(bitmap->bs);
John Snowb0f45552019-03-12 12:05:49 -0400823 assert(bitmap->persistent == true);
824 bitmap->inconsistent = true;
825 bitmap->disabled = true;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300826 bdrv_dirty_bitmaps_unlock(bitmap->bs);
John Snowb0f45552019-03-12 12:05:49 -0400827}
828
829/* Called with BQL taken. */
John Snowc4e4b0f2019-07-29 16:35:54 -0400830void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip)
Vladimir Sementsov-Ogievskiy9c98f142018-10-29 16:23:17 -0400831{
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300832 bdrv_dirty_bitmaps_lock(bitmap->bs);
John Snowc4e4b0f2019-07-29 16:35:54 -0400833 bitmap->skip_store = skip;
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300834 bdrv_dirty_bitmaps_unlock(bitmap->bs);
Vladimir Sementsov-Ogievskiy9c98f142018-10-29 16:23:17 -0400835}
836
Eric Blake796a3792019-03-12 12:05:49 -0400837bool bdrv_dirty_bitmap_get_persistence(BdrvDirtyBitmap *bitmap)
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +0300838{
John Snowc4e4b0f2019-07-29 16:35:54 -0400839 return bitmap->persistent && !bitmap->skip_store;
Vladimir Sementsov-Ogievskiya88b1792017-06-28 15:05:17 +0300840}
841
John Snowb0f45552019-03-12 12:05:49 -0400842bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
843{
844 return bitmap->inconsistent;
845}
846
Vladimir Sementsov-Ogievskiyef9041a2019-09-16 17:19:11 +0300847BdrvDirtyBitmap *bdrv_dirty_bitmap_first(BlockDriverState *bs)
Vladimir Sementsov-Ogievskiy3dd10a02017-06-28 15:05:18 +0300848{
Vladimir Sementsov-Ogievskiyef9041a2019-09-16 17:19:11 +0300849 return QLIST_FIRST(&bs->dirty_bitmaps);
850}
851
852BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BdrvDirtyBitmap *bitmap)
853{
854 return QLIST_NEXT(bitmap, list);
Vladimir Sementsov-Ogievskiy3dd10a02017-06-28 15:05:18 +0300855}
Vladimir Sementsov-Ogievskiya3b52532017-06-28 15:05:25 +0300856
857char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
858{
859 return hbitmap_sha256(bitmap->bitmap, errp);
860}
Vladimir Sementsov-Ogievskiy56207df2017-10-12 16:53:09 +0300861
Vladimir Sementsov-Ogievskiy9399c542020-02-05 14:20:37 +0300862int64_t bdrv_dirty_bitmap_next_dirty(BdrvDirtyBitmap *bitmap, int64_t offset,
863 int64_t bytes)
864{
865 return hbitmap_next_dirty(bitmap->bitmap, offset, bytes);
866}
867
Vladimir Sementsov-Ogievskiy642700f2020-02-05 14:20:36 +0300868int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, int64_t offset,
869 int64_t bytes)
Vladimir Sementsov-Ogievskiy56207df2017-10-12 16:53:09 +0300870{
Vladimir Sementsov-Ogievskiy76d570d2019-01-15 18:26:49 -0500871 return hbitmap_next_zero(bitmap->bitmap, offset, bytes);
Vladimir Sementsov-Ogievskiy56207df2017-10-12 16:53:09 +0300872}
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400873
Vladimir Sementsov-Ogievskiya78a1a42019-01-15 18:26:50 -0500874bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
Vladimir Sementsov-Ogievskiy299ea9f2020-02-05 14:20:38 +0300875 int64_t start, int64_t end, int64_t max_dirty_count,
876 int64_t *dirty_start, int64_t *dirty_count)
Vladimir Sementsov-Ogievskiya78a1a42019-01-15 18:26:50 -0500877{
Vladimir Sementsov-Ogievskiy299ea9f2020-02-05 14:20:38 +0300878 return hbitmap_next_dirty_area(bitmap->bitmap, start, end, max_dirty_count,
879 dirty_start, dirty_count);
Vladimir Sementsov-Ogievskiya78a1a42019-01-15 18:26:50 -0500880}
881
Vladimir Sementsov-Ogievskiya6426472022-03-03 20:43:41 +0100882bool bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap, int64_t offset,
883 int64_t bytes, int64_t *count)
884{
885 return hbitmap_status(bitmap->bitmap, offset, bytes, count);
886}
887
John Snowb7661ca2019-07-29 16:35:53 -0400888/**
889 * bdrv_merge_dirty_bitmap: merge src into dest.
890 * Ensures permissions on bitmaps are reasonable; use for public API.
891 *
892 * @backup: If provided, make a copy of dest here prior to merge.
Vladimir Sementsov-Ogievskiy34ffacb2022-03-03 20:43:35 +0100893 *
894 * Returns true on success, false on failure. In case of failure bitmaps are
895 * untouched.
John Snowb7661ca2019-07-29 16:35:53 -0400896 */
Vladimir Sementsov-Ogievskiy34ffacb2022-03-03 20:43:35 +0100897bool bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
Vladimir Sementsov-Ogievskiyfa000f22018-10-29 16:23:15 -0400898 HBitmap **backup, Error **errp)
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400899{
Vladimir Sementsov-Ogievskiy34ffacb2022-03-03 20:43:35 +0100900 bool ret = false;
Vladimir Sementsov-Ogievskiyfa000f22018-10-29 16:23:15 -0400901
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300902 bdrv_dirty_bitmaps_lock(dest->bs);
903 if (src->bs != dest->bs) {
904 bdrv_dirty_bitmaps_lock(src->bs);
Vladimir Sementsov-Ogievskiyeff08292019-05-28 19:33:31 -0400905 }
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400906
John Snow3ae96d62019-03-12 12:05:49 -0400907 if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) {
Vladimir Sementsov-Ogievskiy06bf5002018-10-29 16:23:14 -0400908 goto out;
909 }
910
John Snowcb8e58e2019-03-12 12:05:49 -0400911 if (bdrv_dirty_bitmap_check(src, BDRV_BITMAP_ALLOW_RO, errp)) {
912 goto out;
913 }
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400914
Vladimir Sementsov-Ogievskiyfa000f22018-10-29 16:23:15 -0400915 if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) {
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400916 error_setg(errp, "Bitmaps are incompatible and can't be merged");
Vladimir Sementsov-Ogievskiy06bf5002018-10-29 16:23:14 -0400917 goto out;
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400918 }
919
John Snowb7661ca2019-07-29 16:35:53 -0400920 ret = bdrv_dirty_bitmap_merge_internal(dest, src, backup, false);
Vladimir Sementsov-Ogievskiyfa000f22018-10-29 16:23:15 -0400921 assert(ret);
922
Vladimir Sementsov-Ogievskiy06bf5002018-10-29 16:23:14 -0400923out:
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300924 bdrv_dirty_bitmaps_unlock(dest->bs);
925 if (src->bs != dest->bs) {
926 bdrv_dirty_bitmaps_unlock(src->bs);
Vladimir Sementsov-Ogievskiyeff08292019-05-28 19:33:31 -0400927 }
Vladimir Sementsov-Ogievskiy34ffacb2022-03-03 20:43:35 +0100928
929 return ret;
Vladimir Sementsov-Ogievskiyb598e532018-06-11 14:53:32 -0400930}
John Snowb7661ca2019-07-29 16:35:53 -0400931
932/**
933 * bdrv_dirty_bitmap_merge_internal: merge src into dest.
934 * Does NOT check bitmap permissions; not suitable for use as public API.
935 *
936 * @backup: If provided, make a copy of dest here prior to merge.
937 * @lock: If true, lock and unlock bitmaps on the way in/out.
938 * returns true if the merge succeeded; false if unattempted.
939 */
940bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
941 const BdrvDirtyBitmap *src,
942 HBitmap **backup,
943 bool lock)
944{
945 bool ret;
Emanuele Giuseppe Esposito967d7902022-03-03 10:15:58 -0500946 IO_CODE();
John Snowb7661ca2019-07-29 16:35:53 -0400947
948 assert(!bdrv_dirty_bitmap_readonly(dest));
949 assert(!bdrv_dirty_bitmap_inconsistent(dest));
950 assert(!bdrv_dirty_bitmap_inconsistent(src));
951
952 if (lock) {
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300953 bdrv_dirty_bitmaps_lock(dest->bs);
954 if (src->bs != dest->bs) {
955 bdrv_dirty_bitmaps_lock(src->bs);
John Snowb7661ca2019-07-29 16:35:53 -0400956 }
957 }
958
959 if (backup) {
960 *backup = dest->bitmap;
961 dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup));
962 ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap);
963 } else {
964 ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap);
965 }
966
967 if (lock) {
Vladimir Sementsov-Ogievskiy1e638302019-09-16 17:19:10 +0300968 bdrv_dirty_bitmaps_unlock(dest->bs);
969 if (src->bs != dest->bs) {
970 bdrv_dirty_bitmaps_unlock(src->bs);
John Snowb7661ca2019-07-29 16:35:53 -0400971 }
972 }
973
974 return ret;
975}