From patchwork Tue Jun 14 21:30:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 9177007 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 822AE604DB for ; Tue, 14 Jun 2016 21:53:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 736AD28334 for ; Tue, 14 Jun 2016 21:53:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6851F28339; Tue, 14 Jun 2016 21:53:19 +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 D4B122833E for ; Tue, 14 Jun 2016 21:53:18 +0000 (UTC) Received: from localhost ([::1]:38419 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCwGr-0002qx-WE for patchwork-qemu-devel@patchwork.kernel.org; Tue, 14 Jun 2016 17:53:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58514) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCvvf-0007LM-9E for qemu-devel@nongnu.org; Tue, 14 Jun 2016 17:31:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCvvZ-0006x2-5l for qemu-devel@nongnu.org; Tue, 14 Jun 2016 17:31:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49739) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCvvM-0006r9-8C; Tue, 14 Jun 2016 17:31:04 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (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 CB5F680B20; Tue, 14 Jun 2016 21:31:03 +0000 (UTC) Received: from red.redhat.com (ovpn-116-106.phx2.redhat.com [10.3.116.106]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u5ELUl7O019211; Tue, 14 Jun 2016 17:31:03 -0400 From: Eric Blake To: qemu-devel@nongnu.org Date: Tue, 14 Jun 2016 15:30:38 -0600 Message-Id: <1465939839-30097-17-git-send-email-eblake@redhat.com> In-Reply-To: <1465939839-30097-1-git-send-email-eblake@redhat.com> References: <1465939839-30097-1-git-send-email-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 14 Jun 2016 21:31:03 +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] [PATCH v2 16/17] block: Split bdrv_merge_limits() from bdrv_refresh_limits() 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: kwolf@redhat.com, Fam Zheng , Stefan Hajnoczi , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The raw block driver was blindly copying all limits from bs->file, even though: 1. the main bdrv_refresh_limits() already does this for many of gthe limits, and 2. blindly copying from the children can weaken any stricter limits that were already inherited from the backing dhain during the main bdrv_refresh_limits(). Also, the next patch is about to move .request_alignment into BlockLimits, and that is a limit that should NOT be copied from other layers in the BDS chain. Solve the issue by factoring out a new bdrv_merge_limits(), and using that function to properly merge limits when comparing two BlockDriverState objects. Signed-off-by: Eric Blake Reviewed-by: Fam Zheng --- v2: new patch --- include/block/block.h | 1 + include/block/block_int.h | 4 ++-- include/qemu/typedefs.h | 1 + block/io.c | 31 +++++++++++++------------------ block/raw_bsd.c | 4 ++-- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 733a8ec..c1d4648 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -262,6 +262,7 @@ int64_t bdrv_nb_sectors(BlockDriverState *bs); int64_t bdrv_getlength(BlockDriverState *bs); int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); +void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src); void bdrv_refresh_limits(BlockDriverState *bs, Error **errp); int bdrv_commit(BlockDriverState *bs); int bdrv_change_backing_file(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index 0169019..88ef826 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -323,7 +323,7 @@ struct BlockDriver { QLIST_ENTRY(BlockDriver) list; }; -typedef struct BlockLimits { +struct BlockLimits { /* maximum number of bytes that can be discarded at once (since it * is signed, it must be < 2G, if set), should be multiple of * pdiscard_alignment, but need not be power of 2. May be 0 if no @@ -364,7 +364,7 @@ typedef struct BlockLimits { /* maximum number of iovec elements */ int max_iov; -} BlockLimits; +}; typedef struct BdrvOpBlocker BdrvOpBlocker; diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index b113fcf..e6f72c2 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -14,6 +14,7 @@ typedef struct BdrvDirtyBitmap BdrvDirtyBitmap; typedef struct BlockBackend BlockBackend; typedef struct BlockBackendRootState BlockBackendRootState; typedef struct BlockDriverState BlockDriverState; +typedef struct BlockLimits BlockLimits; typedef struct BusClass BusClass; typedef struct BusState BusState; typedef struct CharDriverState CharDriverState; diff --git a/block/io.c b/block/io.c index 0b5c40d..c6c1f7b 100644 --- a/block/io.c +++ b/block/io.c @@ -67,6 +67,17 @@ static void bdrv_parent_drained_end(BlockDriverState *bs) } } +void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src) +{ + dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer); + dst->max_transfer = MIN_NON_ZERO(dst->max_transfer, src->max_transfer); + dst->opt_mem_alignment = MAX(dst->opt_mem_alignment, + src->opt_mem_alignment); + dst->min_mem_alignment = MAX(dst->min_mem_alignment, + src->min_mem_alignment); + dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov); +} + void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; @@ -88,11 +99,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) error_propagate(errp, local_err); return; } - bs->bl.opt_transfer = bs->file->bs->bl.opt_transfer; - bs->bl.max_transfer = bs->file->bs->bl.max_transfer; - bs->bl.min_mem_alignment = bs->file->bs->bl.min_mem_alignment; - bs->bl.opt_mem_alignment = bs->file->bs->bl.opt_mem_alignment; - bs->bl.max_iov = bs->file->bs->bl.max_iov; + bdrv_merge_limits(&bs->bl, &bs->file->bs->bl); } else { bs->bl.min_mem_alignment = 512; bs->bl.opt_mem_alignment = getpagesize(); @@ -107,19 +114,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) error_propagate(errp, local_err); return; } - bs->bl.opt_transfer = MAX(bs->bl.opt_transfer, - bs->backing->bs->bl.opt_transfer); - bs->bl.max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, - bs->backing->bs->bl.max_transfer); - bs->bl.opt_mem_alignment = - MAX(bs->bl.opt_mem_alignment, - bs->backing->bs->bl.opt_mem_alignment); - bs->bl.min_mem_alignment = - MAX(bs->bl.min_mem_alignment, - bs->backing->bs->bl.min_mem_alignment); - bs->bl.max_iov = - MIN(bs->bl.max_iov, - bs->backing->bs->bl.max_iov); + bdrv_merge_limits(&bs->bl, &bs->backing->bs->bl); } /* Then let the driver override it */ diff --git a/block/raw_bsd.c b/block/raw_bsd.c index b1d5237..379ce8d 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -1,6 +1,6 @@ /* BlockDriver implementation for "raw" * - * Copyright (C) 2010, 2013, Red Hat, Inc. + * Copyright (C) 2010-2016 Red Hat, Inc. * Copyright (C) 2010, Blue Swirl * Copyright (C) 2009, Anthony Liguori * @@ -152,7 +152,7 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { - bs->bl = bs->file->bs->bl; + bdrv_merge_limits(&bs->bl, &bs->file->bs->bl); } static int raw_truncate(BlockDriverState *bs, int64_t offset)