4 * Copyright (c) 2016 Red Hat. Inc
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 #include "qemu/osdep.h"
25 #include "qapi/error.h"
26 #include "qemu-common.h"
28 #include "block/block_int.h"
29 #include "block/blockjob.h"
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().
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
;
49 struct BdrvDirtyBitmapIter
{
51 BdrvDirtyBitmap
*bitmap
;
54 BdrvDirtyBitmap
*bdrv_find_dirty_bitmap(BlockDriverState
*bs
, const char *name
)
59 QLIST_FOREACH(bm
, &bs
->dirty_bitmaps
, list
) {
60 if (bm
->name
&& !strcmp(name
, bm
->name
)) {
67 void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap
*bitmap
)
69 assert(!bdrv_dirty_bitmap_frozen(bitmap
));
74 BdrvDirtyBitmap
*bdrv_create_dirty_bitmap(BlockDriverState
*bs
,
80 BdrvDirtyBitmap
*bitmap
;
81 uint32_t sector_granularity
;
83 assert((granularity
& (granularity
- 1)) == 0);
85 if (name
&& bdrv_find_dirty_bitmap(bs
, name
)) {
86 error_setg(errp
, "Bitmap already exists: %s", name
);
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");
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
);
106 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap
*bitmap
)
108 return bitmap
->successor
;
111 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap
*bitmap
)
113 return !(bitmap
->disabled
|| bitmap
->successor
);
116 DirtyBitmapStatus
bdrv_dirty_bitmap_status(BdrvDirtyBitmap
*bitmap
)
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
;
123 return DIRTY_BITMAP_STATUS_ACTIVE
;
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.
131 int bdrv_dirty_bitmap_create_successor(BlockDriverState
*bs
,
132 BdrvDirtyBitmap
*bitmap
, Error
**errp
)
134 uint64_t granularity
;
135 BdrvDirtyBitmap
*child
;
137 if (bdrv_dirty_bitmap_frozen(bitmap
)) {
138 error_setg(errp
, "Cannot create a successor for a bitmap that is "
142 assert(!bitmap
->successor
);
144 /* Create an anonymous successor */
145 granularity
= bdrv_dirty_bitmap_granularity(bitmap
);
146 child
= bdrv_create_dirty_bitmap(bs
, granularity
, NULL
, errp
);
151 /* Successor will be on or off based on our current state. */
152 child
->disabled
= bitmap
->disabled
;
154 /* Install the successor and freeze the parent */
155 bitmap
->successor
= child
;
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.
163 BdrvDirtyBitmap
*bdrv_dirty_bitmap_abdicate(BlockDriverState
*bs
,
164 BdrvDirtyBitmap
*bitmap
,
168 BdrvDirtyBitmap
*successor
= bitmap
->successor
;
170 if (successor
== NULL
) {
171 error_setg(errp
, "Cannot relinquish control if "
172 "there's no successor present");
178 successor
->name
= name
;
179 bitmap
->successor
= NULL
;
180 bdrv_release_dirty_bitmap(bs
, bitmap
);
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.
190 BdrvDirtyBitmap
*bdrv_reclaim_dirty_bitmap(BlockDriverState
*bs
,
191 BdrvDirtyBitmap
*parent
,
194 BdrvDirtyBitmap
*successor
= parent
->successor
;
197 error_setg(errp
, "Cannot reclaim a successor when none is present");
201 if (!hbitmap_merge(parent
->bitmap
, successor
->bitmap
)) {
202 error_setg(errp
, "Merging of parent and successor bitmap failed");
205 bdrv_release_dirty_bitmap(bs
, successor
);
206 parent
->successor
= NULL
;
212 * Truncates _all_ bitmaps attached to a BDS.
214 void bdrv_dirty_bitmap_truncate(BlockDriverState
*bs
)
216 BdrvDirtyBitmap
*bitmap
;
217 uint64_t size
= bdrv_nb_sectors(bs
);
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
);
227 static void bdrv_do_release_matching_dirty_bitmap(BlockDriverState
*bs
,
228 BdrvDirtyBitmap
*bitmap
,
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
);
248 void bdrv_release_dirty_bitmap(BlockDriverState
*bs
, BdrvDirtyBitmap
*bitmap
)
250 bdrv_do_release_matching_dirty_bitmap(bs
, bitmap
, false);
254 * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
255 * There must not be any frozen bitmaps attached.
257 void bdrv_release_named_dirty_bitmaps(BlockDriverState
*bs
)
259 bdrv_do_release_matching_dirty_bitmap(bs
, NULL
, true);
262 void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap
*bitmap
)
264 assert(!bdrv_dirty_bitmap_frozen(bitmap
));
265 bitmap
->disabled
= true;
268 void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap
*bitmap
)
270 assert(!bdrv_dirty_bitmap_frozen(bitmap
));
271 bitmap
->disabled
= false;
274 BlockDirtyInfoList
*bdrv_query_dirty_bitmaps(BlockDriverState
*bs
)
277 BlockDirtyInfoList
*list
= NULL
;
278 BlockDirtyInfoList
**plist
= &list
;
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
);
290 plist
= &entry
->next
;
296 int bdrv_get_dirty(BlockDriverState
*bs
, BdrvDirtyBitmap
*bitmap
,
300 return hbitmap_get(bitmap
->bitmap
, sector
);
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.
311 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState
*bs
)
314 uint32_t granularity
;
316 if (bdrv_get_info(bs
, &bdi
) >= 0 && bdi
.cluster_size
> 0) {
317 granularity
= MAX(4096, bdi
.cluster_size
);
318 granularity
= MIN(65536, granularity
);
326 uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap
*bitmap
)
328 return BDRV_SECTOR_SIZE
<< hbitmap_granularity(bitmap
->bitmap
);
331 BdrvDirtyBitmapIter
*bdrv_dirty_iter_new(BdrvDirtyBitmap
*bitmap
,
332 uint64_t first_sector
)
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
++;
341 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter
*iter
)
346 assert(iter
->bitmap
->active_iterators
> 0);
347 iter
->bitmap
->active_iterators
--;
351 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter
*iter
)
353 return hbitmap_iter_next(&iter
->hbi
);
356 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap
*bitmap
,
357 int64_t cur_sector
, int64_t nr_sectors
)
359 assert(bdrv_dirty_bitmap_enabled(bitmap
));
360 hbitmap_set(bitmap
->bitmap
, cur_sector
, nr_sectors
);
363 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap
*bitmap
,
364 int64_t cur_sector
, int64_t nr_sectors
)
366 assert(bdrv_dirty_bitmap_enabled(bitmap
));
367 hbitmap_reset(bitmap
->bitmap
, cur_sector
, nr_sectors
);
370 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap
*bitmap
, HBitmap
**out
)
372 assert(bdrv_dirty_bitmap_enabled(bitmap
));
374 hbitmap_reset_all(bitmap
->bitmap
);
376 HBitmap
*backup
= bitmap
->bitmap
;
377 bitmap
->bitmap
= hbitmap_alloc(bitmap
->size
,
378 hbitmap_granularity(backup
));
383 void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap
*bitmap
, HBitmap
*in
)
385 HBitmap
*tmp
= bitmap
->bitmap
;
386 assert(bdrv_dirty_bitmap_enabled(bitmap
));
391 void bdrv_set_dirty(BlockDriverState
*bs
, int64_t cur_sector
,
394 BdrvDirtyBitmap
*bitmap
;
395 QLIST_FOREACH(bitmap
, &bs
->dirty_bitmaps
, list
) {
396 if (!bdrv_dirty_bitmap_enabled(bitmap
)) {
399 hbitmap_set(bitmap
->bitmap
, cur_sector
, nr_sectors
);
404 * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
406 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter
*iter
, int64_t sector_num
)
408 hbitmap_iter_init(&iter
->hbi
, iter
->hbi
.hb
, sector_num
);
411 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap
*bitmap
)
413 return hbitmap_count(bitmap
->bitmap
);