From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:46535) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXZNa-00015f-NR for qemu-devel@nongnu.org; Mon, 05 Dec 2011 09:18:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RXZNW-0000Ks-5m for qemu-devel@nongnu.org; Mon, 05 Dec 2011 09:18:50 -0500 Received: from mx1.redhat.com ([209.132.183.28]:11189) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXZNV-0000Kl-Tx for qemu-devel@nongnu.org; Mon, 05 Dec 2011 09:18:46 -0500 From: Kevin Wolf Date: Mon, 5 Dec 2011 15:21:08 +0100 Message-Id: <1323094878-7967-32-git-send-email-kwolf@redhat.com> In-Reply-To: <1323094878-7967-1-git-send-email-kwolf@redhat.com> References: <1323094878-7967-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 31/41] block: add request tracking List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: Stefan Hajnoczi The block layer does not know about pending requests. This information is necessary for copy-on-read since overlapping requests must be serialized to prevent races that corrupt the image. The BlockDriverState gets a new tracked_request list field which contains all pending requests. Each request is a BdrvTrackedRequest record with sector_num, nb_sectors, and is_write fields. Note that request tracking is always enabled but hopefully this extra work is so small that it doesn't justify adding an enable/disable flag. Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- block_int.h | 4 ++++ 2 files changed, 51 insertions(+), 1 deletions(-) diff --git a/block.c b/block.c index d82854a..1643667 100644 --- a/block.c +++ b/block.c @@ -1071,6 +1071,42 @@ void bdrv_commit_all(void) } } +struct BdrvTrackedRequest { + BlockDriverState *bs; + int64_t sector_num; + int nb_sectors; + bool is_write; + QLIST_ENTRY(BdrvTrackedRequest) list; +}; + +/** + * Remove an active request from the tracked requests list + * + * This function should be called when a tracked request is completing. + */ +static void tracked_request_end(BdrvTrackedRequest *req) +{ + QLIST_REMOVE(req, list); +} + +/** + * Add an active request to the tracked requests list + */ +static void tracked_request_begin(BdrvTrackedRequest *req, + BlockDriverState *bs, + int64_t sector_num, + int nb_sectors, bool is_write) +{ + *req = (BdrvTrackedRequest){ + .bs = bs, + .sector_num = sector_num, + .nb_sectors = nb_sectors, + .is_write = is_write, + }; + + QLIST_INSERT_HEAD(&bs->tracked_requests, req, list); +} + /* * Return values: * 0 - success @@ -1350,6 +1386,8 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { BlockDriver *drv = bs->drv; + BdrvTrackedRequest req; + int ret; if (!drv) { return -ENOMEDIUM; @@ -1363,7 +1401,10 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, bdrv_io_limits_intercept(bs, false, nb_sectors); } - return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + tracked_request_begin(&req, bs, sector_num, nb_sectors, false); + ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + tracked_request_end(&req); + return ret; } int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, @@ -1381,6 +1422,7 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { BlockDriver *drv = bs->drv; + BdrvTrackedRequest req; int ret; if (!bs->drv) { @@ -1398,6 +1440,8 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, bdrv_io_limits_intercept(bs, true, nb_sectors); } + tracked_request_begin(&req, bs, sector_num, nb_sectors, true); + ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); if (bs->dirty_bitmap) { @@ -1408,6 +1452,8 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, bs->wr_highest_sector = sector_num + nb_sectors - 1; } + tracked_request_end(&req); + return ret; } diff --git a/block_int.h b/block_int.h index a0b46d7..ea818e4 100644 --- a/block_int.h +++ b/block_int.h @@ -51,6 +51,8 @@ #define BLOCK_OPT_PREALLOC "preallocation" #define BLOCK_OPT_SUBFMT "subformat" +typedef struct BdrvTrackedRequest BdrvTrackedRequest; + typedef struct AIOPool { void (*cancel)(BlockDriverAIOCB *acb); int aiocb_size; @@ -255,6 +257,8 @@ struct BlockDriverState { int in_use; /* users other than guest access, eg. block migration */ QTAILQ_ENTRY(BlockDriverState) list; void *private; + + QLIST_HEAD(, BdrvTrackedRequest) tracked_requests; }; struct BlockDriverAIOCB { -- 1.7.6.4