mirror of https://github.com/xemu-project/xemu.git
block: Use BlockBackend for I/O in bdrv_commit()
Just like block jobs, the HMP commit command should use its own BlockBackend for doing I/O on BlockDriverStates. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
83fd6dd3e7
commit
f8e2bd538d
|
@ -289,6 +289,7 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
|
||||||
/* commit COW file into the raw image */
|
/* commit COW file into the raw image */
|
||||||
int bdrv_commit(BlockDriverState *bs)
|
int bdrv_commit(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
|
BlockBackend *src, *backing;
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int64_t sector, total_sectors, length, backing_length;
|
int64_t sector, total_sectors, length, backing_length;
|
||||||
int n, ro, open_flags;
|
int n, ro, open_flags;
|
||||||
|
@ -316,13 +317,19 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
length = bdrv_getlength(bs);
|
src = blk_new();
|
||||||
|
blk_insert_bs(src, bs);
|
||||||
|
|
||||||
|
backing = blk_new();
|
||||||
|
blk_insert_bs(backing, bs->backing->bs);
|
||||||
|
|
||||||
|
length = blk_getlength(src);
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
ret = length;
|
ret = length;
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
backing_length = bdrv_getlength(bs->backing->bs);
|
backing_length = blk_getlength(backing);
|
||||||
if (backing_length < 0) {
|
if (backing_length < 0) {
|
||||||
ret = backing_length;
|
ret = backing_length;
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
|
@ -332,7 +339,7 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
* grow the backing file image if possible. If not possible,
|
* grow the backing file image if possible. If not possible,
|
||||||
* we must return an error */
|
* we must return an error */
|
||||||
if (length > backing_length) {
|
if (length > backing_length) {
|
||||||
ret = bdrv_truncate(bs->backing->bs, length);
|
ret = blk_truncate(backing, length);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -340,9 +347,9 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
|
|
||||||
total_sectors = length >> BDRV_SECTOR_BITS;
|
total_sectors = length >> BDRV_SECTOR_BITS;
|
||||||
|
|
||||||
/* qemu_try_blockalign() for bs will choose an alignment that works for
|
/* blk_try_blockalign() for src will choose an alignment that works for
|
||||||
* bs->backing->bs as well, so no need to compare the alignment manually. */
|
* backing as well, so no need to compare the alignment manually. */
|
||||||
buf = qemu_try_blockalign(bs, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
|
buf = blk_try_blockalign(src, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
|
@ -354,12 +361,14 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
}
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = bdrv_read(bs, sector, buf, n);
|
ret = blk_pread(src, sector * BDRV_SECTOR_SIZE, buf,
|
||||||
|
n * BDRV_SECTOR_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_write(bs->backing->bs, sector, buf, n);
|
ret = blk_pwrite(backing, sector * BDRV_SECTOR_SIZE, buf,
|
||||||
|
n * BDRV_SECTOR_SIZE, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -371,21 +380,22 @@ int bdrv_commit(BlockDriverState *bs)
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto ro_cleanup;
|
goto ro_cleanup;
|
||||||
}
|
}
|
||||||
bdrv_flush(bs);
|
blk_flush(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure all data we wrote to the backing device is actually
|
* Make sure all data we wrote to the backing device is actually
|
||||||
* stable on disk.
|
* stable on disk.
|
||||||
*/
|
*/
|
||||||
if (bs->backing) {
|
blk_flush(backing);
|
||||||
bdrv_flush(bs->backing->bs);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
ro_cleanup:
|
ro_cleanup:
|
||||||
qemu_vfree(buf);
|
qemu_vfree(buf);
|
||||||
|
|
||||||
|
blk_unref(src);
|
||||||
|
blk_unref(backing);
|
||||||
|
|
||||||
if (ro) {
|
if (ro) {
|
||||||
/* ignoring error return here */
|
/* ignoring error return here */
|
||||||
bdrv_reopen(bs->backing->bs, open_flags & ~BDRV_O_RDWR, NULL);
|
bdrv_reopen(bs->backing->bs, open_flags & ~BDRV_O_RDWR, NULL);
|
||||||
|
|
Loading…
Reference in New Issue