提交 c6d22830 编写于 作者: J Jan Kiszka 提交者: Anthony Liguori

block migration: Cleanup dirty tracking code

This switches the dirty bitmap to a true bitmap, reducing its footprint
(specifically in caches). It moreover fixes off-by-one bugs in
set_dirty_bitmap (nb_sectors+1 were marked) and bdrv_get_dirty (limit
check allowed one sector behind end of drive). And is drops redundant
dirty_tracking field from BlockDriverState.
Signed-off-by: NJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 6ea44308
...@@ -642,12 +642,21 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, ...@@ -642,12 +642,21 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int dirty) int nb_sectors, int dirty)
{ {
int64_t start, end; int64_t start, end;
unsigned long val, idx, bit;
start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK; start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;
end = (sector_num + nb_sectors) / BDRV_SECTORS_PER_DIRTY_CHUNK; end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK;
for (; start <= end; start++) { for (; start <= end; start++) {
bs->dirty_bitmap[start] = dirty; idx = start / (sizeof(unsigned long) * 8);
bit = start % (sizeof(unsigned long) * 8);
val = bs->dirty_bitmap[idx];
if (dirty) {
val |= 1 << bit;
} else {
val &= ~(1 << bit);
}
bs->dirty_bitmap[idx] = val;
} }
} }
...@@ -668,7 +677,7 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, ...@@ -668,7 +677,7 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors)) if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO; return -EIO;
if (bs->dirty_tracking) { if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1); set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
} }
...@@ -1218,7 +1227,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, ...@@ -1218,7 +1227,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors)) if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO; return -EIO;
if (bs->dirty_tracking) { if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1); set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
} }
...@@ -1419,7 +1428,7 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, ...@@ -1419,7 +1428,7 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors)) if (bdrv_check_request(bs, sector_num, nb_sectors))
return NULL; return NULL;
if (bs->dirty_tracking) { if (bs->dirty_bitmap) {
set_dirty_bitmap(bs, sector_num, nb_sectors, 1); set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
} }
...@@ -1965,23 +1974,17 @@ void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) ...@@ -1965,23 +1974,17 @@ void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
int64_t bitmap_size; int64_t bitmap_size;
if (enable) { if (enable) {
if (bs->dirty_tracking == 0) { if (!bs->dirty_bitmap) {
int64_t i; bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) +
uint8_t test; BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK;
bitmap_size++;
bs->dirty_bitmap = qemu_mallocz(bitmap_size); bs->dirty_bitmap = qemu_mallocz(bitmap_size);
bs->dirty_tracking = enable;
for(i = 0; i < bitmap_size; i++) test = bs->dirty_bitmap[i];
} }
} else { } else {
if (bs->dirty_tracking != 0) { if (bs->dirty_bitmap) {
qemu_free(bs->dirty_bitmap); qemu_free(bs->dirty_bitmap);
bs->dirty_tracking = enable; bs->dirty_bitmap = NULL;
} }
} }
} }
...@@ -1990,9 +1993,10 @@ int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) ...@@ -1990,9 +1993,10 @@ int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
{ {
int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
if (bs->dirty_bitmap != NULL && if (bs->dirty_bitmap &&
(sector << BDRV_SECTOR_BITS) <= bdrv_getlength(bs)) { (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
return bs->dirty_bitmap[chunk]; return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
(1 << (chunk % (sizeof(unsigned long) * 8)));
} else { } else {
return 0; return 0;
} }
......
...@@ -168,8 +168,7 @@ struct BlockDriverState { ...@@ -168,8 +168,7 @@ struct BlockDriverState {
int cyls, heads, secs, translation; int cyls, heads, secs, translation;
int type; int type;
char device_name[32]; char device_name[32];
int dirty_tracking; unsigned long *dirty_bitmap;
uint8_t *dirty_bitmap;
BlockDriverState *next; BlockDriverState *next;
void *private; void *private;
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册