From patchwork Fri Sep 16 14:25:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 114945 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 6C076B6F81 for ; Sat, 17 Sep 2011 01:04:56 +1000 (EST) Received: from localhost ([::1]:52357 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R4ZOQ-0007E3-6z for incoming@patchwork.ozlabs.org; Fri, 16 Sep 2011 10:27:50 -0400 Received: from eggs.gnu.org ([140.186.70.92]:58714) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R4ZN5-0003GT-80 for qemu-devel@nongnu.org; Fri, 16 Sep 2011 10:26:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R4ZMy-00051K-8A for qemu-devel@nongnu.org; Fri, 16 Sep 2011 10:26:22 -0400 Received: from mail-ww0-f53.google.com ([74.125.82.53]:48095) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R4ZMy-0004wc-0T for qemu-devel@nongnu.org; Fri, 16 Sep 2011 10:26:20 -0400 Received: by mail-ww0-f53.google.com with SMTP id 14so4633242wwg.10 for ; Fri, 16 Sep 2011 07:26:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; bh=QK/Ic2wIlCMQu8OK6/A6HKgKhRMtv3iHqL2fxnDrZFQ=; b=fAivUFQzO7wVLTQGRaTa9Yn7oeWTnO8hFmckTu2+nDd3LiEuijEUMpS6pm19Jg0SNm jtYyVJwrhxOig7vybOK9ZZINXOZS/+3++gsaeGe3+oUboN/GDtNTfvFI1l82UPThki9I D6HOylQ0cWsFWDdH3K4WVZx6Qb1ogRG8o2Lg4= Received: by 10.216.29.200 with SMTP id i50mr984521wea.91.1316183179588; Fri, 16 Sep 2011 07:26:19 -0700 (PDT) Received: from localhost.localdomain (93-34-199-31.ip51.fastwebnet.it. [93.34.199.31]) by mx.google.com with ESMTPS id ek13sm12701198wbb.23.2011.09.16.07.26.18 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 16 Sep 2011 07:26:19 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 16 Sep 2011 16:25:45 +0200 Message-Id: <1316183152-5481-9-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1316183152-5481-1-git-send-email-pbonzini@redhat.com> References: <1316183152-5481-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.53 Subject: [Qemu-devel] [PATCH v2 08/15] block: add bdrv_co_discard and bdrv_aio_discard support 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 Signed-off-by: Paolo Bonzini --- block.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- block.h | 3 + block_int.h | 9 +++- trace-events | 1 + 4 files changed, 148 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index f4b9089..7853982 100644 --- a/block.c +++ b/block.c @@ -53,6 +53,9 @@ static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); +static BlockDriverAIOCB *bdrv_aio_discard_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, @@ -60,6 +63,8 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); static int bdrv_flush_em(BlockDriverState *bs); +static int bdrv_discard_em(BlockDriverState *bs, int64_t sector_num, + int nb_sectors); static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); @@ -68,6 +73,9 @@ static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); static BlockDriverAIOCB *bdrv_co_aio_flush_em(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); +static BlockDriverAIOCB *bdrv_co_aio_discard_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *iov); @@ -75,6 +83,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *iov); static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs); +static int coroutine_fn bdrv_co_discard_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors); static QTAILQ_HEAD(, BlockDriverState) bdrv_states = QTAILQ_HEAD_INITIALIZER(bdrv_states); @@ -209,6 +219,14 @@ void bdrv_register(BlockDriver *bdrv) bdrv->bdrv_aio_flush = bdrv_aio_flush_em; } + if (bdrv->bdrv_co_discard) { + bdrv->bdrv_aio_discard = bdrv_co_aio_discard_em; + } else if (bdrv->bdrv_aio_discard) { + bdrv->bdrv_co_discard = bdrv_co_discard_em; + } else { + bdrv->bdrv_aio_discard = bdrv_aio_discard_em; + } + /* add synchronous IO emulation layer */ if (!bdrv->bdrv_read) { bdrv->bdrv_read = bdrv_read_em; @@ -217,6 +235,9 @@ void bdrv_register(BlockDriver *bdrv) if (!bdrv->bdrv_flush) { bdrv->bdrv_flush = bdrv_flush_em; } + if (!bdrv->bdrv_discard) { + bdrv->bdrv_discard = bdrv_discard_em; + } QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); } @@ -1791,10 +1812,18 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) if (!bs->drv) { return -ENOMEDIUM; } - if (!bs->drv->bdrv_discard) { - return 0; + if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return -EIO; + } + if (bs->drv->bdrv_co_discard && qemu_in_coroutine()) { + return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors); } - return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); + + if (bs->drv->bdrv_discard) { + return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); + } + + return 0; } /* @@ -2656,6 +2685,24 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, return drv->bdrv_aio_flush(bs, cb, opaque); } +BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque); + + if (!bs->drv) { + return NULL; + } + if (bs->read_only) { + return NULL; + } + if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return NULL; + } + return bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors, cb, opaque); +} + void bdrv_aio_cancel(BlockDriverAIOCB *acb) { acb->pool->cancel(acb); @@ -2873,6 +2920,52 @@ static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, return &acb->common; } +static void coroutine_fn bdrv_co_discard(void *opaque) +{ + BlockDriverAIOCBCoroutine *acb = opaque; + BlockDriverState *bs = acb->common.bs; + + acb->req.error = bs->drv->bdrv_co_discard(bs, acb->req.sector, + acb->req.nb_sectors); + acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); + qemu_bh_schedule(acb->bh); +} + +static BlockDriverAIOCB *bdrv_co_aio_discard_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + Coroutine *co; + BlockDriverAIOCBCoroutine *acb; + + acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); + acb->req.sector = sector_num; + acb->req.nb_sectors = nb_sectors; + co = qemu_coroutine_create(bdrv_co_discard); + qemu_coroutine_enter(co, acb); + + return &acb->common; +} + +static BlockDriverAIOCB *bdrv_aio_discard_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + BlockDriverAIOCBSync *acb; + + acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); + acb->is_write = 1; /* don't bounce in the completion hadler */ + acb->qiov = NULL; + acb->bounce = NULL; + + if (!acb->bh) { + acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); + } + acb->ret = bdrv_discard(bs, sector_num, nb_sectors); + qemu_bh_schedule(acb->bh); + return &acb->common; +} + static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) { @@ -2975,6 +3068,30 @@ fail: return async_ret; } +static int bdrv_discard_em(BlockDriverState *bs, int64_t sector_num, + int nb_sectors) + +{ + int async_ret; + BlockDriverAIOCB *acb; + + async_ret = NOT_DONE; + acb = bdrv_aio_discard(bs, sector_num, nb_sectors, + bdrv_em_cb, &async_ret); + if (acb == NULL) { + async_ret = -1; + goto fail; + } + + while (async_ret == NOT_DONE) { + qemu_aio_wait(); + } + + +fail: + return async_ret; +} + void bdrv_init(void) { module_call_init(MODULE_INIT_BLOCK); @@ -3083,6 +3200,23 @@ static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs) return co.ret; } +static int coroutine_fn bdrv_co_discard_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors) +{ + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + BlockDriverAIOCB *acb; + + acb = bdrv_aio_discard(bs, sector_num, nb_sectors, + bdrv_co_io_em_complete, &co); + if (!acb) { + return -EIO; + } + qemu_coroutine_yield(); + return co.ret; +} + /**************************************************************/ /* removable device support */ diff --git a/block.h b/block.h index 16bfa0a..94cd395 100644 --- a/block.h +++ b/block.h @@ -156,6 +156,9 @@ 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_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); void bdrv_aio_cancel(BlockDriverAIOCB *acb); typedef struct BlockRequest { diff --git a/block_int.h b/block_int.h index bb39b0b..4222bda 100644 --- a/block_int.h +++ b/block_int.h @@ -63,6 +63,8 @@ struct BlockDriver { void (*bdrv_close)(BlockDriverState *bs); int (*bdrv_create)(const char *filename, QEMUOptionParameter *options); int (*bdrv_flush)(BlockDriverState *bs); + int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num, + int nb_sectors); int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int (*bdrv_set_key)(BlockDriverState *bs, const char *key); @@ -76,14 +78,17 @@ struct BlockDriver { BlockDriverCompletionFunc *cb, void *opaque); BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); - int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num, - int nb_sectors); + BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs); + int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors); int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs, int num_reqs); diff --git a/trace-events b/trace-events index fe64684..2dcfb9c 100644 --- a/trace-events +++ b/trace-events @@ -59,6 +59,7 @@ multiwrite_cb(void *mcb, int ret) "mcb %p ret %d" bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d" bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p" bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d" +bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p" bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p" bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p" bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"