From patchwork Wed Jul 27 13:44:47 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 107098 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1B38BB6F62 for ; Thu, 28 Jul 2011 00:53:05 +1000 (EST) Received: from localhost ([::1]:37978 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm4RD-0002e6-NZ for incoming@patchwork.ozlabs.org; Wed, 27 Jul 2011 09:46:15 -0400 Received: from eggs.gnu.org ([140.186.70.92]:33507) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm4QE-0007X7-Jj for qemu-devel@nongnu.org; Wed, 27 Jul 2011 09:45:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qm4Q7-0004Y8-J9 for qemu-devel@nongnu.org; Wed, 27 Jul 2011 09:45:14 -0400 Received: from mtagate7.uk.ibm.com ([194.196.100.167]:39388) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qm4Q7-0004Wl-Bx for qemu-devel@nongnu.org; Wed, 27 Jul 2011 09:45:07 -0400 Received: from d06nrmr1507.portsmouth.uk.ibm.com (d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233]) by mtagate7.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p6RDj6ZB008619 for ; Wed, 27 Jul 2011 13:45:06 GMT Received: from d06av09.portsmouth.uk.ibm.com (d06av09.portsmouth.uk.ibm.com [9.149.37.250]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6RDj6Pu2543724 for ; Wed, 27 Jul 2011 14:45:06 +0100 Received: from d06av09.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6RDj5rI016203 for ; Wed, 27 Jul 2011 07:45:05 -0600 Received: from stefanha-thinkpad.ibm.com ([9.78.66.144]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p6RDj1DG016013; Wed, 27 Jul 2011 07:45:05 -0600 From: Stefan Hajnoczi To: Date: Wed, 27 Jul 2011 14:44:47 +0100 Message-Id: <1311774295-8696-8-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1311774295-8696-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1311774295-8696-1-git-send-email-stefanha@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 194.196.100.167 Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , Adam Litke Subject: [Qemu-devel] [PATCH 07/15] block: add bdrv_aio_copy_backing() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 3d074af..8225758 100644 --- a/block.c +++ b/block.c @@ -2240,6 +2240,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 f6ffa93..aee11e6 100644 --- a/block.h +++ b/block.h @@ -113,6 +113,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); @@ -121,6 +122,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 69dd5a7..8b10083 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);