From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:40799) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTx4V-0006iU-0H for qemu-devel@nongnu.org; Tue, 07 Jun 2011 10:15:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QTx4L-0006n9-3E for qemu-devel@nongnu.org; Tue, 07 Jun 2011 10:15:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39702) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTx4K-0006mo-FV for qemu-devel@nongnu.org; Tue, 07 Jun 2011 10:15:44 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p57EFhMr024407 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 7 Jun 2011 10:15:43 -0400 From: Kevin Wolf Date: Tue, 7 Jun 2011 16:18:31 +0200 Message-Id: <1307456313-9884-2-git-send-email-kwolf@redhat.com> In-Reply-To: <1307456313-9884-1-git-send-email-kwolf@redhat.com> References: <1307456313-9884-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 1/3] qcow2: Avoid direct AIO callback List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, lcapitulino@redhat.com 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 30b6692..890cf2c 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; } -- 1.7.5.2