]> git.proxmox.com Git - mirror_qemu.git/blob - block/dirty-bitmap.c
block: Hide HBitmap in block dirty bitmap interface
[mirror_qemu.git] / block / dirty-bitmap.c
1 /*
2 * Block Dirty Bitmap
3 *
4 * Copyright (c) 2016 Red Hat. Inc
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include "qemu/osdep.h"
25 #include "qapi/error.h"
26 #include "qemu-common.h"
27 #include "trace.h"
28 #include "block/block_int.h"
29 #include "block/blockjob.h"
30
31 /**
32 * A BdrvDirtyBitmap can be in three possible states:
33 * (1) successor is NULL and disabled is false: full r/w mode
34 * (2) successor is NULL and disabled is true: read only mode ("disabled")
35 * (3) successor is set: frozen mode.
36 * A frozen bitmap cannot be renamed, deleted, anonymized, cleared, set,
37 * or enabled. A frozen bitmap can only abdicate() or reclaim().
38 */
39 struct BdrvDirtyBitmap {
40 HBitmap *bitmap; /* Dirty sector bitmap implementation */
41 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
42 char *name; /* Optional non-empty unique ID */
43 int64_t size; /* Size of the bitmap (Number of sectors) */
44 bool disabled; /* Bitmap is read-only */
45 int active_iterators; /* How many iterators are active */
46 QLIST_ENTRY(BdrvDirtyBitmap) list;
47 };
48
49 struct BdrvDirtyBitmapIter {
50 HBitmapIter hbi;
51 BdrvDirtyBitmap *bitmap;
52 };
53
54 BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
55 {
56 BdrvDirtyBitmap *bm;
57
58 assert(name);
59 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
60 if (bm->name && !strcmp(name, bm->name)) {
61 return bm;
62 }
63 }
64 return NULL;
65 }
66
67 void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
68 {
69 assert(!bdrv_dirty_bitmap_frozen(bitmap));
70 g_free(bitmap->name);
71 bitmap->name = NULL;
72 }
73
74 BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
75 uint32_t granularity,
76 const char *name,
77 Error **errp)
78 {
79 int64_t bitmap_size;
80 BdrvDirtyBitmap *bitmap;
81 uint32_t sector_granularity;
82
83 assert((granularity & (granularity - 1)) == 0);
84
85 if (name && bdrv_find_dirty_bitmap(bs, name)) {
86 error_setg(errp, "Bitmap already exists: %s", name);
87 return NULL;
88 }
89 sector_granularity = granularity >> BDRV_SECTOR_BITS;
90 assert(sector_granularity);
91 bitmap_size = bdrv_nb_sectors(bs);
92 if (bitmap_size < 0) {
93 error_setg_errno(errp, -bitmap_size, "could not get length of device");
94 errno = -bitmap_size;
95 return NULL;
96 }
97 bitmap = g_new0(BdrvDirtyBitmap, 1);
98 bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
99 bitmap->size = bitmap_size;
100 bitmap->name = g_strdup(name);
101 bitmap->disabled = false;
102 QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
103 return bitmap;
104 }
105
106 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
107 {
108 return bitmap->successor;
109 }
110
111 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
112 {
113 return !(bitmap->disabled || bitmap->successor);
114 }
115
116 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
117 {
118 if (bdrv_dirty_bitmap_frozen(bitmap)) {
119 return DIRTY_BITMAP_STATUS_FROZEN;
120 } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
121 return DIRTY_BITMAP_STATUS_DISABLED;
122 } else {
123 return DIRTY_BITMAP_STATUS_ACTIVE;
124 }
125 }
126
127 /**
128 * Create a successor bitmap destined to replace this bitmap after an operation.
129 * Requires that the bitmap is not frozen and has no successor.
130 */
131 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
132 BdrvDirtyBitmap *bitmap, Error **errp)
133 {
134 uint64_t granularity;
135 BdrvDirtyBitmap *child;
136
137 if (bdrv_dirty_bitmap_frozen(bitmap)) {
138 error_setg(errp, "Cannot create a successor for a bitmap that is "
139 "currently frozen");
140 return -1;
141 }
142 assert(!bitmap->successor);
143
144 /* Create an anonymous successor */
145 granularity = bdrv_dirty_bitmap_granularity(bitmap);
146 child = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
147 if (!child) {
148 return -1;
149 }
150
151 /* Successor will be on or off based on our current state. */
152 child->disabled = bitmap->disabled;
153
154 /* Install the successor and freeze the parent */
155 bitmap->successor = child;
156 return 0;
157 }
158
159 /**
160 * For a bitmap with a successor, yield our name to the successor,
161 * delete the old bitmap, and return a handle to the new bitmap.
162 */
163 BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
164 BdrvDirtyBitmap *bitmap,
165 Error **errp)
166 {
167 char *name;
168 BdrvDirtyBitmap *successor = bitmap->successor;
169
170 if (successor == NULL) {
171 error_setg(errp, "Cannot relinquish control if "
172 "there's no successor present");
173 return NULL;
174 }
175
176 name = bitmap->name;
177 bitmap->name = NULL;
178 successor->name = name;
179 bitmap->successor = NULL;
180 bdrv_release_dirty_bitmap(bs, bitmap);
181
182 return successor;
183 }
184
185 /**
186 * In cases of failure where we can no longer safely delete the parent,
187 * we may wish to re-join the parent and child/successor.
188 * The merged parent will be un-frozen, but not explicitly re-enabled.
189 */
190 BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs,
191 BdrvDirtyBitmap *parent,
192 Error **errp)
193 {
194 BdrvDirtyBitmap *successor = parent->successor;
195
196 if (!successor) {
197 error_setg(errp, "Cannot reclaim a successor when none is present");
198 return NULL;
199 }
200
201 if (!hbitmap_merge(parent->bitmap, successor->bitmap)) {
202 error_setg(errp, "Merging of parent and successor bitmap failed");
203 return NULL;
204 }
205 bdrv_release_dirty_bitmap(bs, successor);
206 parent->successor = NULL;
207
208 return parent;
209 }
210
211 /**
212 * Truncates _all_ bitmaps attached to a BDS.
213 */
214 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
215 {
216 BdrvDirtyBitmap *bitmap;
217 uint64_t size = bdrv_nb_sectors(bs);
218
219 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
220 assert(!bdrv_dirty_bitmap_frozen(bitmap));
221 assert(!bitmap->active_iterators);
222 hbitmap_truncate(bitmap->bitmap, size);
223 bitmap->size = size;
224 }
225 }
226
227 static void bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs,
228 BdrvDirtyBitmap *bitmap,
229 bool only_named)
230 {
231 BdrvDirtyBitmap *bm, *next;
232 QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
233 if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) {
234 assert(!bm->active_iterators);
235 assert(!bdrv_dirty_bitmap_frozen(bm));
236 QLIST_REMOVE(bm, list);
237 hbitmap_free(bm->bitmap);
238 g_free(bm->name);
239 g_free(bm);
240
241 if (bitmap) {
242 return;
243 }
244 }
245 }
246 }
247
248 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
249 {
250 bdrv_do_release_matching_dirty_bitmap(bs, bitmap, false);
251 }
252
253 /**
254 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
255 * There must not be any frozen bitmaps attached.
256 */
257 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
258 {
259 bdrv_do_release_matching_dirty_bitmap(bs, NULL, true);
260 }
261
262 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
263 {
264 assert(!bdrv_dirty_bitmap_frozen(bitmap));
265 bitmap->disabled = true;
266 }
267
268 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
269 {
270 assert(!bdrv_dirty_bitmap_frozen(bitmap));
271 bitmap->disabled = false;
272 }
273
274 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
275 {
276 BdrvDirtyBitmap *bm;
277 BlockDirtyInfoList *list = NULL;
278 BlockDirtyInfoList **plist = &list;
279
280 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
281 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
282 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
283 info->count = bdrv_get_dirty_count(bm);
284 info->granularity = bdrv_dirty_bitmap_granularity(bm);
285 info->has_name = !!bm->name;
286 info->name = g_strdup(bm->name);
287 info->status = bdrv_dirty_bitmap_status(bm);
288 entry->value = info;
289 *plist = entry;
290 plist = &entry->next;
291 }
292
293 return list;
294 }
295
296 int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
297 int64_t sector)
298 {
299 if (bitmap) {
300 return hbitmap_get(bitmap->bitmap, sector);
301 } else {
302 return 0;
303 }
304 }
305
306 /**
307 * Chooses a default granularity based on the existing cluster size,
308 * but clamped between [4K, 64K]. Defaults to 64K in the case that there
309 * is no cluster size information available.
310 */
311 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
312 {
313 BlockDriverInfo bdi;
314 uint32_t granularity;
315
316 if (bdrv_get_info(bs, &bdi) >= 0 && bdi.cluster_size > 0) {
317 granularity = MAX(4096, bdi.cluster_size);
318 granularity = MIN(65536, granularity);
319 } else {
320 granularity = 65536;
321 }
322
323 return granularity;
324 }
325
326 uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap)
327 {
328 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
329 }
330
331 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
332 uint64_t first_sector)
333 {
334 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
335 hbitmap_iter_init(&iter->hbi, bitmap->bitmap, first_sector);
336 iter->bitmap = bitmap;
337 bitmap->active_iterators++;
338 return iter;
339 }
340
341 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
342 {
343 if (!iter) {
344 return;
345 }
346 assert(iter->bitmap->active_iterators > 0);
347 iter->bitmap->active_iterators--;
348 g_free(iter);
349 }
350
351 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
352 {
353 return hbitmap_iter_next(&iter->hbi);
354 }
355
356 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
357 int64_t cur_sector, int64_t nr_sectors)
358 {
359 assert(bdrv_dirty_bitmap_enabled(bitmap));
360 hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
361 }
362
363 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
364 int64_t cur_sector, int64_t nr_sectors)
365 {
366 assert(bdrv_dirty_bitmap_enabled(bitmap));
367 hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
368 }
369
370 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
371 {
372 assert(bdrv_dirty_bitmap_enabled(bitmap));
373 if (!out) {
374 hbitmap_reset_all(bitmap->bitmap);
375 } else {
376 HBitmap *backup = bitmap->bitmap;
377 bitmap->bitmap = hbitmap_alloc(bitmap->size,
378 hbitmap_granularity(backup));
379 *out = backup;
380 }
381 }
382
383 void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
384 {
385 HBitmap *tmp = bitmap->bitmap;
386 assert(bdrv_dirty_bitmap_enabled(bitmap));
387 bitmap->bitmap = in;
388 hbitmap_free(tmp);
389 }
390
391 void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
392 int64_t nr_sectors)
393 {
394 BdrvDirtyBitmap *bitmap;
395 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
396 if (!bdrv_dirty_bitmap_enabled(bitmap)) {
397 continue;
398 }
399 hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
400 }
401 }
402
403 /**
404 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
405 */
406 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
407 {
408 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
409 }
410
411 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
412 {
413 return hbitmap_count(bitmap->bitmap);
414 }