mirror of https://github.com/xemu-project/xemu.git
vpc: Read/write multiple sectors at once
This changes the vpc block driver (for VHD) to read/write multiple sectors at once instead of doing a request for each single sector. Before this, running qemu-iotests for VPC took ages, now it's actually quite reasonable to run it always (down from ~1 hour to 40 seconds for me). Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
fd42deeb4c
commit
6c6ea921ff
47
block/vpc.c
47
block/vpc.c
|
@ -371,23 +371,33 @@ fail:
|
||||||
static int vpc_read(BlockDriverState *bs, int64_t sector_num,
|
static int vpc_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
uint8_t *buf, int nb_sectors)
|
uint8_t *buf, int nb_sectors)
|
||||||
{
|
{
|
||||||
|
BDRVVPCState *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
|
int64_t sectors, sectors_per_block;
|
||||||
|
|
||||||
while (nb_sectors > 0) {
|
while (nb_sectors > 0) {
|
||||||
offset = get_sector_offset(bs, sector_num, 0);
|
offset = get_sector_offset(bs, sector_num, 0);
|
||||||
|
|
||||||
if (offset == -1) {
|
sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
|
||||||
memset(buf, 0, 512);
|
sectors = sectors_per_block - (sector_num % sectors_per_block);
|
||||||
} else {
|
if (sectors > nb_sectors) {
|
||||||
ret = bdrv_pread(bs->file, offset, buf, 512);
|
sectors = nb_sectors;
|
||||||
if (ret != 512)
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nb_sectors--;
|
if (offset == -1) {
|
||||||
sector_num++;
|
memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
|
||||||
buf += 512;
|
} else {
|
||||||
|
ret = bdrv_pread(bs->file, offset, buf,
|
||||||
|
sectors * BDRV_SECTOR_SIZE);
|
||||||
|
if (ret != sectors * BDRV_SECTOR_SIZE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nb_sectors -= sectors;
|
||||||
|
sector_num += sectors;
|
||||||
|
buf += sectors * BDRV_SECTOR_SIZE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -395,25 +405,34 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
|
||||||
static int vpc_write(BlockDriverState *bs, int64_t sector_num,
|
static int vpc_write(BlockDriverState *bs, int64_t sector_num,
|
||||||
const uint8_t *buf, int nb_sectors)
|
const uint8_t *buf, int nb_sectors)
|
||||||
{
|
{
|
||||||
|
BDRVVPCState *s = bs->opaque;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
|
int64_t sectors, sectors_per_block;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while (nb_sectors > 0) {
|
while (nb_sectors > 0) {
|
||||||
offset = get_sector_offset(bs, sector_num, 1);
|
offset = get_sector_offset(bs, sector_num, 1);
|
||||||
|
|
||||||
|
sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
|
||||||
|
sectors = sectors_per_block - (sector_num % sectors_per_block);
|
||||||
|
if (sectors > nb_sectors) {
|
||||||
|
sectors = nb_sectors;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset == -1) {
|
if (offset == -1) {
|
||||||
offset = alloc_block(bs, sector_num);
|
offset = alloc_block(bs, sector_num);
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_pwrite(bs->file, offset, buf, 512);
|
ret = bdrv_pwrite(bs->file, offset, buf, sectors * BDRV_SECTOR_SIZE);
|
||||||
if (ret != 512)
|
if (ret != sectors * BDRV_SECTOR_SIZE) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
nb_sectors--;
|
nb_sectors -= sectors;
|
||||||
sector_num++;
|
sector_num += sectors;
|
||||||
buf += 512;
|
buf += sectors * BDRV_SECTOR_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue