mirror of https://github.com/xemu-project/xemu.git
block: Change bdrv_commit to handle multiple sectors at once
bdrv_commit copies the image to its backing file sector by sector, which is (surprise!) relatively slow. Let's take a larger buffer and handle more sectors at once if possible. With a 1G qcow2 file, this brought the time bdrv_commit takes down from 5:06 min to 1:14 min for me. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
5933e8a96a
commit
8a4266144e
37
block.c
37
block.c
|
@ -739,14 +739,16 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
|
||||||
return bs->drv->bdrv_check(bs, res);
|
return bs->drv->bdrv_check(bs, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COMMIT_BUF_SECTORS 2048
|
||||||
|
|
||||||
/* commit COW file into the raw image */
|
/* commit COW file into the raw image */
|
||||||
int bdrv_commit(BlockDriverState *bs)
|
int bdrv_commit(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int64_t i, total_sectors;
|
int64_t sector, total_sectors;
|
||||||
int n, j, ro, open_flags;
|
int n, ro, open_flags;
|
||||||
int ret = 0, rw_ret = 0;
|
int ret = 0, rw_ret = 0;
|
||||||
unsigned char sector[BDRV_SECTOR_SIZE];
|
uint8_t *buf;
|
||||||
char filename[1024];
|
char filename[1024];
|
||||||
BlockDriverState *bs_rw, *bs_ro;
|
BlockDriverState *bs_rw, *bs_ro;
|
||||||
|
|
||||||
|
@ -789,22 +791,20 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
|
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
|
||||||
for (i = 0; i < total_sectors;) {
|
buf = qemu_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
|
||||||
if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
|
|
||||||
for(j = 0; j < n; j++) {
|
|
||||||
if (bdrv_read(bs, i, sector, 1) != 0) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto ro_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
|
for (sector = 0; sector < total_sectors; sector += n) {
|
||||||
ret = -EIO;
|
if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
|
||||||
goto ro_cleanup;
|
|
||||||
}
|
if (bdrv_read(bs, sector, buf, n) != 0) {
|
||||||
i++;
|
ret = -EIO;
|
||||||
}
|
goto ro_cleanup;
|
||||||
} else {
|
}
|
||||||
i += n;
|
|
||||||
|
if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
|
||||||
|
ret = -EIO;
|
||||||
|
goto ro_cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,6 +821,7 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
bdrv_flush(bs->backing_hd);
|
bdrv_flush(bs->backing_hd);
|
||||||
|
|
||||||
ro_cleanup:
|
ro_cleanup:
|
||||||
|
qemu_free(buf);
|
||||||
|
|
||||||
if (ro) {
|
if (ro) {
|
||||||
/* re-open as RO */
|
/* re-open as RO */
|
||||||
|
|
Loading…
Reference in New Issue