diff options
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 127 |
1 files changed, 62 insertions, 65 deletions
@@ -41,10 +41,6 @@ #include <windows.h> #endif -#define SECTOR_BITS 9 -#define SECTOR_SIZE (1 << SECTOR_BITS) -#define SECTORS_PER_DIRTY_CHUNK 8 - static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); @@ -386,7 +382,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, bdrv_delete(bs1); return ret; } - total_size = bdrv_getlength(bs1) >> SECTOR_BITS; + total_size = bdrv_getlength(bs1) >> BDRV_SECTOR_BITS; if (bs1->drv && bs1->drv->protocol_name) is_protocol = 1; @@ -473,7 +469,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, return ret; } if (drv->bdrv_getlength) { - bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; + bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; } #ifndef _WIN32 if (bs->is_temporary) { @@ -576,7 +572,7 @@ int bdrv_commit(BlockDriverState *bs) return -ENOTSUP; } - total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; + total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; for (i = 0; i < total_sectors;) { if (drv->bdrv_is_allocated(bs, i, 65536, &n)) { for(j = 0; j < n; j++) { @@ -643,14 +639,24 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num, } 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; - start = sector_num / SECTORS_PER_DIRTY_CHUNK; - end = (sector_num + nb_sectors) / SECTORS_PER_DIRTY_CHUNK; - - for(; start <= end; start++) { - bs->dirty_bitmap[start] = dirty; + unsigned long val, idx, bit; + + start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK; + end = (sector_num + nb_sectors - 1) / BDRV_SECTORS_PER_DIRTY_CHUNK; + + for (; start <= end; start++) { + 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; } } @@ -670,31 +676,31 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, return -EACCES; if (bdrv_check_request(bs, sector_num, nb_sectors)) return -EIO; - - if(bs->dirty_tracking) { + + if (bs->dirty_bitmap) { set_dirty_bitmap(bs, sector_num, nb_sectors, 1); } - + return drv->bdrv_write(bs, sector_num, buf, nb_sectors); } int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf, int count1) { - uint8_t tmp_buf[SECTOR_SIZE]; + uint8_t tmp_buf[BDRV_SECTOR_SIZE]; int len, nb_sectors, count; int64_t sector_num; count = count1; /* first read to align to sector start */ - len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); + len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); if (len > count) len = count; - sector_num = offset >> SECTOR_BITS; + sector_num = offset >> BDRV_SECTOR_BITS; if (len > 0) { if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) return -EIO; - memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len); + memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len); count -= len; if (count == 0) return count1; @@ -703,12 +709,12 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset, } /* read the sectors "in place" */ - nb_sectors = count >> SECTOR_BITS; + nb_sectors = count >> BDRV_SECTOR_BITS; if (nb_sectors > 0) { if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0) return -EIO; sector_num += nb_sectors; - len = nb_sectors << SECTOR_BITS; + len = nb_sectors << BDRV_SECTOR_BITS; buf += len; count -= len; } @@ -725,20 +731,20 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset, int bdrv_pwrite(BlockDriverState *bs, int64_t offset, const void *buf, int count1) { - uint8_t tmp_buf[SECTOR_SIZE]; + uint8_t tmp_buf[BDRV_SECTOR_SIZE]; int len, nb_sectors, count; int64_t sector_num; count = count1; /* first write to align to sector start */ - len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); + len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1); if (len > count) len = count; - sector_num = offset >> SECTOR_BITS; + sector_num = offset >> BDRV_SECTOR_BITS; if (len > 0) { if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) return -EIO; - memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len); + memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len); if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) return -EIO; count -= len; @@ -749,12 +755,12 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset, } /* write the sectors "in place" */ - nb_sectors = count >> SECTOR_BITS; + nb_sectors = count >> BDRV_SECTOR_BITS; if (nb_sectors > 0) { if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0) return -EIO; sector_num += nb_sectors; - len = nb_sectors << SECTOR_BITS; + len = nb_sectors << BDRV_SECTOR_BITS; buf += len; count -= len; } @@ -795,7 +801,7 @@ int64_t bdrv_getlength(BlockDriverState *bs) return -ENOMEDIUM; if (!drv->bdrv_getlength) { /* legacy mode */ - return bs->total_sectors * SECTOR_SIZE; + return bs->total_sectors * BDRV_SECTOR_SIZE; } return drv->bdrv_getlength(bs); } @@ -808,7 +814,7 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) if (length < 0) length = 0; else - length = length >> SECTOR_BITS; + length = length >> BDRV_SECTOR_BITS; *nb_sectors_ptr = length; } @@ -1220,11 +1226,11 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, return -ENOTSUP; if (bdrv_check_request(bs, sector_num, nb_sectors)) return -EIO; - - if(bs->dirty_tracking) { + + if (bs->dirty_bitmap) { set_dirty_bitmap(bs, sector_num, nb_sectors, 1); } - + return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors); } @@ -1401,7 +1407,7 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, if (ret) { /* Update stats even though technically transfer has not happened. */ - bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE; + bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE; bs->rd_ops ++; } @@ -1422,16 +1428,16 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, if (bdrv_check_request(bs, sector_num, nb_sectors)) return NULL; - if(bs->dirty_tracking) { + if (bs->dirty_bitmap) { set_dirty_bitmap(bs, sector_num, nb_sectors, 1); } - + ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors, cb, opaque); if (ret) { /* Update stats even though technically transfer has not happened. */ - bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE; + bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE; bs->wr_ops ++; } @@ -1966,47 +1972,38 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size) void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) { int64_t bitmap_size; - if(enable) { - if(bs->dirty_tracking == 0) { - int64_t i; - uint8_t test; - bitmap_size = (bdrv_getlength(bs) >> SECTOR_BITS); - bitmap_size /= SECTORS_PER_DIRTY_CHUNK; - bitmap_size++; - + + if (enable) { + if (!bs->dirty_bitmap) { + bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS) + + BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; + bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; + bs->dirty_bitmap = qemu_mallocz(bitmap_size); - - bs->dirty_tracking = enable; - for(i = 0; i < bitmap_size; i++) test = bs->dirty_bitmap[i]; - } + } } else { - if(bs->dirty_tracking != 0) { + if (bs->dirty_bitmap) { qemu_free(bs->dirty_bitmap); - bs->dirty_tracking = enable; - } + bs->dirty_bitmap = NULL; + } } } int bdrv_get_dirty(BlockDriverState *bs, int64_t sector) { - int64_t chunk = sector / (int64_t)SECTORS_PER_DIRTY_CHUNK; - - if(bs->dirty_bitmap != NULL && - (sector << SECTOR_BITS) <= bdrv_getlength(bs)) { - return bs->dirty_bitmap[chunk]; + int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; + + if (bs->dirty_bitmap && + (sector << BDRV_SECTOR_BITS) < bdrv_getlength(bs)) { + return bs->dirty_bitmap[chunk / (sizeof(unsigned long) * 8)] & + (1 << (chunk % (sizeof(unsigned long) * 8))); } else { return 0; } } -void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, - int nr_sectors) +void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, + int nr_sectors) { set_dirty_bitmap(bs, cur_sector, nr_sectors, 0); } - -int bdrv_get_sectors_per_chunk(void) -{ - /* size must be 2^x */ - return SECTORS_PER_DIRTY_CHUNK; -} |