From 30ea65d67ad658f775ba51f64caf62a9ac13fb1e Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 12 Aug 2011 15:38:17 +0200 Subject: [PATCH 09/15] block: add bdrv_aio_copy_backing() RH-Author: Anthony Liguori Message-id: <1313163503-2523-10-git-send-email-aliguori@redhat.com> Patchwork-id: 31329 O-Subject: [RHEL6.2 qemu PATCH 09/15] block: add bdrv_aio_copy_backing() Bugzilla: 633370 RH-Acked-by: Marcelo Tosatti RH-Acked-by: Kevin Wolf RH-Acked-by: Orit Wasserman RH-Acked-by: Christoph Hellwig From: Anthony Liguori Add the bdrv_aio_copy_backing() function to the BlockDriver interface. This function copies unallocated sectors from the backing file and can be used to implement image streaming. Signed-off-by: Anthony Liguori Signed-off-by: Stefan Hajnoczi Signed-off-by: Anthony Liguori Bugzilla: 633370 --- block.c | 37 +++++++++++++++++++++++++++++++++++++ block.h | 5 +++++ block_int.h | 2 ++ 3 files changed, 44 insertions(+), 0 deletions(-) Signed-off-by: Michal Novotny --- block.c | 37 +++++++++++++++++++++++++++++++++++++ block.h | 5 +++++ block_int.h | 2 ++ 3 files changed, 44 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 383b62d..622ccd1 100644 --- a/block.c +++ b/block.c @@ -2038,6 +2038,43 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, return ret; } +/** + * Attempt to copy unallocated sectors from backing file. + * + * @sector_num - the first sector to start from + * @cb - completion callback + * @opaque - data to pass completion callback + * + * Returns NULL if the image format not support the operation, the image is + * read-only, or no image is open. + * + * The intention of this function is for a user to execute it once with a + * sector_num of 0 and then upon receiving a completion callback, to remember + * the number of sectors copied, and then to call this function again with + * an offset adjusted by the number of sectors previously copied. + * + * This allows a user to progressive stream in an image at a pace that makes + * sense. In general, this function tries to do the smallest amount of I/O + * possible to do some useful work. + * + * This function only really makes sense in combination with a block format + * that supports copy on read and has it enabled. If copy on read is not + * enabled, a block format driver may return NULL. + * + * If an I/O error occurs the completion callback is invoked with -errno in the + * nb_sectors argument. + */ +BlockDriverAIOCB *bdrv_aio_copy_backing(BlockDriverState *bs, + int64_t sector_num, + BlockDriverCopyBackingCB *cb, + void *opaque) +{ + if (!bs->drv || bs->read_only || !bs->drv->bdrv_aio_copy_backing) { + return NULL; + } + + return bs->drv->bdrv_aio_copy_backing(bs, sector_num, cb, opaque); +} typedef struct MultiwriteCB { int error; diff --git a/block.h b/block.h index b47c450..be3d63e 100644 --- a/block.h +++ b/block.h @@ -115,6 +115,7 @@ typedef struct BlockDriverAIOCB BlockDriverAIOCB; typedef void BlockDriverCompletionFunc(void *opaque, int ret); typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector, int sector_num); +typedef void BlockDriverCopyBackingCB(void *opaque, int nb_sectors); BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); @@ -123,6 +124,10 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, BlockDriverCompletionFunc *cb, void *opaque); BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); +BlockDriverAIOCB *bdrv_aio_copy_backing(BlockDriverState *bs, + int64_t sector_num, + BlockDriverCopyBackingCB *cb, + void *opaque); void bdrv_aio_cancel(BlockDriverAIOCB *acb); typedef struct BlockRequest { diff --git a/block_int.h b/block_int.h index 3c36aa4..9c709cf 100644 --- a/block_int.h +++ b/block_int.h @@ -74,6 +74,8 @@ struct BlockDriver { BlockDriverCompletionFunc *cb, void *opaque); BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); + BlockDriverAIOCB *(*bdrv_aio_copy_backing)(BlockDriverState *bs, + int64_t sector_num, BlockDriverCopyBackingCB *cb, void *opaque); int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num, int nb_sectors); -- 1.7.4.4