From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:38325) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QWYCU-0005xM-4d for qemu-devel@nongnu.org; Tue, 14 Jun 2011 14:18:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QWYCR-00069z-Q7 for qemu-devel@nongnu.org; Tue, 14 Jun 2011 14:18:53 -0400 Received: from mtagate4.uk.ibm.com ([194.196.100.164]:53334) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QWYCQ-00068d-Qz for qemu-devel@nongnu.org; Tue, 14 Jun 2011 14:18:51 -0400 Received: from d06nrmr1307.portsmouth.uk.ibm.com (d06nrmr1307.portsmouth.uk.ibm.com [9.149.38.129]) by mtagate4.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p5EIIm1u014159 for ; Tue, 14 Jun 2011 18:18:48 GMT Received: from d06av12.portsmouth.uk.ibm.com (d06av12.portsmouth.uk.ibm.com [9.149.37.247]) by d06nrmr1307.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p5EIIltf2379842 for ; Tue, 14 Jun 2011 19:18:48 +0100 Received: from d06av12.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av12.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p5EIIlQ2015219 for ; Tue, 14 Jun 2011 12:18:47 -0600 From: Stefan Hajnoczi Date: Tue, 14 Jun 2011 19:18:27 +0100 Message-Id: <1308075511-4745-10-git-send-email-stefanha@linux.vnet.ibm.com> In-Reply-To: <1308075511-4745-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1308075511-4745-1-git-send-email-stefanha@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 09/13] block: add bdrv_aio_copy_backing() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , Adam Litke 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 --- 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 99068c9..4da35be 100644 --- a/block.c +++ b/block.c @@ -2221,6 +2221,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 deb19ec..b5de366 100644 --- a/block.h +++ b/block.h @@ -112,6 +112,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); @@ -120,6 +121,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 135625a..327efb3 100644 --- a/block_int.h +++ b/block_int.h @@ -73,6 +73,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.5.3