From patchwork Tue Jul 19 18:47:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 9238257 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 80B33602F0 for ; Tue, 19 Jul 2016 20:15:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 71B3520499 for ; Tue, 19 Jul 2016 20:15:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6648E275A2; Tue, 19 Jul 2016 20:15:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C69B220499 for ; Tue, 19 Jul 2016 20:15:26 +0000 (UTC) Received: from localhost ([::1]:58335 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bPb1c-0005TH-F5 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 19 Jul 2016 15:49:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45754) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bPa4K-0002ZE-M3 for qemu-devel@nongnu.org; Tue, 19 Jul 2016 14:48:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bPa4J-0005Yk-CG for qemu-devel@nongnu.org; Tue, 19 Jul 2016 14:48:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36574) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bPa4J-0005YO-3g for qemu-devel@nongnu.org; Tue, 19 Jul 2016 14:48:35 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A40E5883AB; Tue, 19 Jul 2016 18:48:34 +0000 (UTC) Received: from localhost (ovpn-112-17.ams2.redhat.com [10.36.112.17]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u6JImXmt026647; Tue, 19 Jul 2016 14:48:34 -0400 From: Stefan Hajnoczi To: Date: Tue, 19 Jul 2016 19:47:57 +0100 Message-Id: <1468954095-5159-8-git-send-email-stefanha@redhat.com> In-Reply-To: <1468954095-5159-1-git-send-email-stefanha@redhat.com> References: <1468954095-5159-1-git-send-email-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 19 Jul 2016 18:48:34 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL for-2.7 07/25] block: Convert bdrv_co_discard() to byte-based X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Stefan Hajnoczi Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Blake Another step towards byte-based interfaces everywhere. Replace the sector-based bdrv_co_discard() with a new byte-based bdrv_co_pdiscard(), which silently ignores any unaligned head or tail. Driver callbacks will be converted in followup patches. By calculating the alignment outside of the loop, and clamping the max discard to an aligned value, we can simplify the actions done within the loop. Signed-off-by: Eric Blake Reviewed-by: Stefan Hajnoczi Message-id: 1468624988-423-2-git-send-email-eblake@redhat.com Signed-off-by: Stefan Hajnoczi --- block/blkreplay.c | 3 ++- block/block-backend.c | 3 ++- block/io.c | 67 +++++++++++++++++++++++++++------------------------ block/raw_bsd.c | 3 ++- include/block/block.h | 2 +- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/block/blkreplay.c b/block/blkreplay.c index 3368c8c..c69e5a5 100755 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -118,7 +118,8 @@ static int coroutine_fn blkreplay_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { uint64_t reqid = request_id++; - int ret = bdrv_co_discard(bs->file->bs, sector_num, nb_sectors); + int ret = bdrv_co_pdiscard(bs->file->bs, sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS); block_request_create(reqid, bs, qemu_coroutine_self()); qemu_coroutine_yield(); diff --git a/block/block-backend.c b/block/block-backend.c index f9cea1b..d982cf9 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1113,7 +1113,8 @@ int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors) return ret; } - return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors); + return bdrv_co_pdiscard(blk_bs(blk), sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS); } int blk_co_flush(BlockBackend *blk) diff --git a/block/io.c b/block/io.c index 410394d..14d448d 100644 --- a/block/io.c +++ b/block/io.c @@ -2199,7 +2199,8 @@ static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque) BlockAIOCBCoroutine *acb = opaque; BlockDriverState *bs = acb->common.bs; - acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors); + acb->req.error = bdrv_co_pdiscard(bs, acb->req.sector << BDRV_SECTOR_BITS, + acb->req.nb_sectors << BDRV_SECTOR_BITS); bdrv_co_complete(acb); } @@ -2398,20 +2399,22 @@ static void coroutine_fn bdrv_discard_co_entry(void *opaque) { DiscardCo *rwco = opaque; - rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors); + rwco->ret = bdrv_co_pdiscard(rwco->bs, rwco->sector_num << BDRV_SECTOR_BITS, + rwco->nb_sectors << BDRV_SECTOR_BITS); } -int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, - int nb_sectors) +int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, + int count) { BdrvTrackedRequest req; - int max_discard, ret; + int max_pdiscard, ret; + int head, align; if (!bs->drv) { return -ENOMEDIUM; } - ret = bdrv_check_request(bs, sector_num, nb_sectors); + ret = bdrv_check_byte_request(bs, offset, count); if (ret < 0) { return ret; } else if (bs->read_only) { @@ -2428,45 +2431,45 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, return 0; } - tracked_request_begin(&req, bs, sector_num << BDRV_SECTOR_BITS, - nb_sectors << BDRV_SECTOR_BITS, BDRV_TRACKED_DISCARD); + /* Discard is advisory, so ignore any unaligned head or tail */ + align = MAX(BDRV_SECTOR_SIZE, + MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment)); + assert(is_power_of_2(align)); + head = MIN(count, -offset & (align - 1)); + if (head) { + count -= head; + offset += head; + } + count = QEMU_ALIGN_DOWN(count, align); + if (!count) { + return 0; + } + + tracked_request_begin(&req, bs, offset, count, BDRV_TRACKED_DISCARD); ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req); if (ret < 0) { goto out; } - max_discard = MIN_NON_ZERO(bs->bl.max_pdiscard >> BDRV_SECTOR_BITS, - BDRV_REQUEST_MAX_SECTORS); - while (nb_sectors > 0) { + max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX), + align); + + while (count > 0) { int ret; - int num = nb_sectors; - int discard_alignment = bs->bl.pdiscard_alignment >> BDRV_SECTOR_BITS; - - /* align request */ - if (discard_alignment && - num >= discard_alignment && - sector_num % discard_alignment) { - if (num > discard_alignment) { - num = discard_alignment; - } - num -= sector_num % discard_alignment; - } - - /* limit request size */ - if (num > max_discard) { - num = max_discard; - } + int num = MIN(count, max_pdiscard); if (bs->drv->bdrv_co_discard) { - ret = bs->drv->bdrv_co_discard(bs, sector_num, num); + ret = bs->drv->bdrv_co_discard(bs, offset >> BDRV_SECTOR_BITS, + num >> BDRV_SECTOR_BITS); } else { BlockAIOCB *acb; CoroutineIOCompletion co = { .coroutine = qemu_coroutine_self(), }; - acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors, + acb = bs->drv->bdrv_aio_discard(bs, offset >> BDRV_SECTOR_BITS, + num >> BDRV_SECTOR_BITS, bdrv_co_io_em_complete, &co); if (acb == NULL) { ret = -EIO; @@ -2480,8 +2483,8 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, goto out; } - sector_num += num; - nb_sectors -= num; + offset += num; + count -= num; } ret = 0; out: diff --git a/block/raw_bsd.c b/block/raw_bsd.c index d767413..68f0a91 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -137,7 +137,8 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn raw_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { - return bdrv_co_discard(bs->file->bs, sector_num, nb_sectors); + return bdrv_co_pdiscard(bs->file->bs, sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS); } static int64_t raw_getlength(BlockDriverState *bs) diff --git a/include/block/block.h b/include/block/block.h index 616d8b9..4f5cebf 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -342,7 +342,7 @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs); void bdrv_drain_all(void); int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); -int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); +int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int count); int bdrv_has_zero_init_1(BlockDriverState *bs); int bdrv_has_zero_init(BlockDriverState *bs); bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);