]> git.proxmox.com Git - mirror_qemu.git/blame - block/dirty-bitmap.c
tests: Add test code for meta bitmap
[mirror_qemu.git] / block / dirty-bitmap.c
CommitLineData
ebab2259
FZ
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"
da34e65c 25#include "qapi/error.h"
ebab2259
FZ
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 */
39struct 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 */
dc162c8e 45 int active_iterators; /* How many iterators are active */
ebab2259
FZ
46 QLIST_ENTRY(BdrvDirtyBitmap) list;
47};
48
dc162c8e
FZ
49struct BdrvDirtyBitmapIter {
50 HBitmapIter hbi;
51 BdrvDirtyBitmap *bitmap;
52};
53
ebab2259
FZ
54BdrvDirtyBitmap *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
67void 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
74BdrvDirtyBitmap *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
106bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
107{
108 return bitmap->successor;
109}
110
111bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
112{
113 return !(bitmap->disabled || bitmap->successor);
114}
115
116DirtyBitmapStatus 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 */
131int 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 */
163BdrvDirtyBitmap *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 */
190BdrvDirtyBitmap *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 */
214void 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));
dc162c8e 221 assert(!bitmap->active_iterators);
ebab2259
FZ
222 hbitmap_truncate(bitmap->bitmap, size);
223 bitmap->size = size;
224 }
225}
226
227static 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)) {
dc162c8e 234 assert(!bm->active_iterators);
ebab2259
FZ
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
248void 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 */
257void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
258{
259 bdrv_do_release_matching_dirty_bitmap(bs, NULL, true);
260}
261
262void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
263{
264 assert(!bdrv_dirty_bitmap_frozen(bitmap));
265 bitmap->disabled = true;
266}
267
268void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
269{
270 assert(!bdrv_dirty_bitmap_frozen(bitmap));
271 bitmap->disabled = false;
272}
273
274BlockDirtyInfoList *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
296int 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 */
311uint32_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
326uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap)
327{
328 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
329}
330
dc162c8e
FZ
331BdrvDirtyBitmapIter *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
341void 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
351int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
ebab2259 352{
dc162c8e 353 return hbitmap_iter_next(&iter->hbi);
ebab2259
FZ
354}
355
356void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
6d078599 357 int64_t cur_sector, int64_t nr_sectors)
ebab2259
FZ
358{
359 assert(bdrv_dirty_bitmap_enabled(bitmap));
360 hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
361}
362
363void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
6d078599 364 int64_t cur_sector, int64_t nr_sectors)
ebab2259
FZ
365{
366 assert(bdrv_dirty_bitmap_enabled(bitmap));
367 hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
368}
369
370void 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
383void 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
391void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
6d078599 392 int64_t nr_sectors)
ebab2259
FZ
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/**
dc162c8e 404 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
ebab2259 405 */
dc162c8e 406void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
ebab2259 407{
dc162c8e 408 hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
ebab2259
FZ
409}
410
411int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
412{
413 return hbitmap_count(bitmap->bitmap);
414}