[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 04/16] block: introduce new dirty bitmap function
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH v3 04/16] block: introduce new dirty bitmap functionality |
Date: |
Thu, 18 Oct 2012 16:49:18 +0200 |
Assert that write_compressed is never used with the dirty bitmap.
Setting the bits early is wrong, because a coroutine might concurrently
examine them and copy incomplete data from the source.
Signed-off-by: Paolo Bonzini <address@hidden>
---
block.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
block.h | 5 +++--
2 file modificati, 48 inserzioni(+), 8 rimozioni(-)
diff --git a/block.c b/block.c
index 4787312..057b2b2 100644
--- a/block.c
+++ b/block.c
@@ -2389,7 +2389,7 @@ static int coroutine_fn
bdrv_co_do_writev(BlockDriverState *bs,
}
if (bs->dirty_bitmap) {
- set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
+ bdrv_set_dirty(bs, sector_num, nb_sectors);
}
if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
@@ -2958,9 +2958,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t
sector_num,
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
- if (bs->dirty_bitmap) {
- set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
- }
+ assert(!bs->dirty_bitmap);
return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
}
@@ -4219,13 +4217,54 @@ int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
if (bs->dirty_bitmap &&
(sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) {
- return !!(bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] &
- (1UL << (chunk % (sizeof(unsigned long) * 8))));
+ return !!(bs->dirty_bitmap[chunk / BITS_PER_LONG] &
+ (1UL << (chunk % BITS_PER_LONG)));
} else {
return 0;
}
}
+int64_t bdrv_get_next_dirty(BlockDriverState *bs, int64_t sector)
+{
+ int64_t chunk;
+ int bit, elem;
+
+ /* Avoid an infinite loop. */
+ assert(bs->dirty_count > 0);
+
+ sector = (sector | (BDRV_SECTORS_PER_DIRTY_CHUNK - 1)) + 1;
+ chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
+
+ QEMU_BUILD_BUG_ON(sizeof(bs->dirty_bitmap[0]) * 8 != BITS_PER_LONG);
+ elem = chunk / BITS_PER_LONG;
+ bit = chunk % BITS_PER_LONG;
+ for (;;) {
+ if (sector >= bs->total_sectors) {
+ sector = 0;
+ bit = elem = 0;
+ }
+ if (bit == 0 && bs->dirty_bitmap[elem] == 0) {
+ sector += BDRV_SECTORS_PER_DIRTY_CHUNK * BITS_PER_LONG;
+ elem++;
+ } else {
+ if (bs->dirty_bitmap[elem] & (1UL << bit)) {
+ return sector;
+ }
+ sector += BDRV_SECTORS_PER_DIRTY_CHUNK;
+ if (++bit == BITS_PER_LONG) {
+ bit = 0;
+ elem++;
+ }
+ }
+ }
+}
+
+void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
+ int nr_sectors)
+{
+ set_dirty_bitmap(bs, cur_sector, nr_sectors, 1);
+}
+
void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
int nr_sectors)
{
diff --git a/block.h b/block.h
index 096fa09..27b8f80 100644
--- a/block.h
+++ b/block.h
@@ -353,8 +353,9 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size);
void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable);
int bdrv_get_dirty(BlockDriverState *bs, int64_t sector);
-void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
- int nr_sectors);
+void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
+void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int
nr_sectors);
+int64_t bdrv_get_next_dirty(BlockDriverState *bs, int64_t sector);
int64_t bdrv_get_dirty_count(BlockDriverState *bs);
void bdrv_enable_copy_on_read(BlockDriverState *bs);
--
1.7.12.1
- [Qemu-devel] [PULL for Kevin 00/16] Block job improvements part 2, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 01/16] block: add bdrv_query_info, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 02/16] block: add bdrv_query_stats, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 03/16] block: add bdrv_open_backing_file, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 04/16] block: introduce new dirty bitmap functionality,
Paolo Bonzini <=
- [Qemu-devel] [PATCH v3 05/16] block: export dirty bitmap information in query-block, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 06/16] block: rename block_job_complete to block_job_completed, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 07/16] block: add block-job-complete, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 08/16] block: introduce BLOCK_JOB_READY event, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 09/16] mirror: introduce mirror job, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 13/16] iostatus: forward block_job_iostatus_reset to block job, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 14/16] mirror: add support for on-source-error/on-target-error, Paolo Bonzini, 2012/10/18
- [Qemu-devel] [PATCH v3 15/16] qmp: add pull_event function, Paolo Bonzini, 2012/10/18