From patchwork Wed Jun 15 14:03:01 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 100527 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 62244B6F9F for ; Thu, 16 Jun 2011 00:29:26 +1000 (EST) Received: from localhost ([::1]:32940 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QWr5v-0001so-0j for incoming@patchwork.ozlabs.org; Wed, 15 Jun 2011 10:29:23 -0400 Received: from eggs.gnu.org ([140.186.70.92]:35009) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QWqe0-0003i0-Me for qemu-devel@nongnu.org; Wed, 15 Jun 2011 10:00:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QWqdv-0005qK-0a for qemu-devel@nongnu.org; Wed, 15 Jun 2011 10:00:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:21633) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QWqdu-0005pv-Cn for qemu-devel@nongnu.org; Wed, 15 Jun 2011 10:00:26 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5FE0OKm020164 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 15 Jun 2011 10:00:24 -0400 Received: from dhcp-5-188.str.redhat.com (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5FE0Kra024634; Wed, 15 Jun 2011 10:00:23 -0400 From: Kevin Wolf To: anthony@codemonkey.ws Date: Wed, 15 Jun 2011 16:03:01 +0200 Message-Id: <1308146593-19842-3-git-send-email-kwolf@redhat.com> In-Reply-To: <1308146593-19842-1-git-send-email-kwolf@redhat.com> References: <1308146593-19842-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 02/14] qcow2: Avoid direct AIO callback 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 bdrv_aio_* must not call the callback before returning to its caller. In qcow2, this could happen in some error cases. This starts the real requests processing in a BH to avoid this situation. Signed-off-by: Kevin Wolf --- block/qcow2.c | 39 ++++++++++++++++++++++++++++++--------- 1 files changed, 30 insertions(+), 9 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 8451ded..2c51e7c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -378,6 +378,7 @@ typedef struct QCowAIOCB { uint64_t bytes_done; uint64_t cluster_offset; uint8_t *cluster_data; + bool is_write; BlockDriverAIOCB *hd_aiocb; QEMUIOVector hd_qiov; QEMUBH *bh; @@ -399,12 +400,19 @@ static AIOPool qcow2_aio_pool = { }; static void qcow2_aio_read_cb(void *opaque, int ret); -static void qcow2_aio_read_bh(void *opaque) +static void qcow2_aio_write_cb(void *opaque, int ret); + +static void qcow2_aio_rw_bh(void *opaque) { QCowAIOCB *acb = opaque; qemu_bh_delete(acb->bh); acb->bh = NULL; - qcow2_aio_read_cb(opaque, 0); + + if (acb->is_write) { + qcow2_aio_write_cb(opaque, 0); + } else { + qcow2_aio_read_cb(opaque, 0); + } } static int qcow2_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb) @@ -493,14 +501,14 @@ static void qcow2_aio_read_cb(void *opaque, int ret) goto done; } } else { - ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb); + ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb); if (ret < 0) goto done; } } else { /* Note: in this case, no need to wait */ qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors); - ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb); + ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb); if (ret < 0) goto done; } @@ -515,7 +523,7 @@ static void qcow2_aio_read_cb(void *opaque, int ret) s->cluster_cache + index_in_cluster * 512, 512 * acb->cur_nr_sectors); - ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb); + ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb); if (ret < 0) goto done; } else { @@ -572,6 +580,7 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, acb->hd_aiocb = NULL; acb->sector_num = sector_num; acb->qiov = qiov; + acb->is_write = is_write; qemu_iovec_init(&acb->hd_qiov, qiov->niov); @@ -591,17 +600,22 @@ static BlockDriverAIOCB *qcow2_aio_readv(BlockDriverState *bs, void *opaque) { QCowAIOCB *acb; + int ret; acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); if (!acb) return NULL; - qcow2_aio_read_cb(acb, 0); + ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb); + if (ret < 0) { + qemu_iovec_destroy(&acb->hd_qiov); + qemu_aio_release(acb); + return NULL; + } + return &acb->common; } -static void qcow2_aio_write_cb(void *opaque, int ret); - static void run_dependent_requests(QCowL2Meta *m) { QCowAIOCB *req; @@ -724,6 +738,7 @@ static BlockDriverAIOCB *qcow2_aio_writev(BlockDriverState *bs, { BDRVQcowState *s = bs->opaque; QCowAIOCB *acb; + int ret; s->cluster_cache_offset = -1; /* disable compressed cache */ @@ -731,7 +746,13 @@ static BlockDriverAIOCB *qcow2_aio_writev(BlockDriverState *bs, if (!acb) return NULL; - qcow2_aio_write_cb(acb, 0); + ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb); + if (ret < 0) { + qemu_iovec_destroy(&acb->hd_qiov); + qemu_aio_release(acb); + return NULL; + } + return &acb->common; }