From nobody Sat Nov 15 04:14:56 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1593098699; cv=none; d=zohomail.com; s=zohoarc; b=SuoLgf5hcpiZJBQ0I98JN1FnuV0ZfL7wpGERTc5SiZudyob0Bght5diA8GQf1WX2eyrc8yR+tph/joUGL168btpB8T4lEMbKl0bb+0urVqVtzP7Q0LLBKw/m7Ue4XGQe930+TR3wiiF6Mse38x0OzPH1ZVGnxECLCBnL6tg/5EM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1593098699; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=/PfEqA0UCfJfYnevUk13q8CgID2wiYihyO7qiY72z1Q=; b=h2uVos6IIjQyJ/2d+z8O0Fi3yQBY/+yqx/KAvoKgdjBvGjo2cRiphQ5PwEIc16Uf3VIpjdB1xcvCh0u73TS+w5iVAXGZcSoTv+D+/SZ4xJkhz15PwvM5nnS5RdtVo4KV/H4H+ByFOyhXrZt7igjKdXaNDiwLOJqnHgqnDpE+jzg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1593098699039421.86665817437483; Thu, 25 Jun 2020 08:24:59 -0700 (PDT) Received: from localhost ([::1]:58618 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1joTkH-0007UP-KF for importer@patchew.org; Thu, 25 Jun 2020 11:24:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36842) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1joThu-00056p-Qs for qemu-devel@nongnu.org; Thu, 25 Jun 2020 11:22:30 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:43148 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1joThs-0000Sj-Vx for qemu-devel@nongnu.org; Thu, 25 Jun 2020 11:22:30 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-215-0OrKLpWtNJizozD8XGHENw-1; Thu, 25 Jun 2020 11:22:20 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D944C1800D4A; Thu, 25 Jun 2020 15:22:19 +0000 (UTC) Received: from localhost (ovpn-113-182.ams2.redhat.com [10.36.113.182]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7BF22612BA; Thu, 25 Jun 2020 15:22:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593098544; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/PfEqA0UCfJfYnevUk13q8CgID2wiYihyO7qiY72z1Q=; b=PTRk2JyQw+O9xGgmtiVIu8gpwLWE/caVcOomcgnVHgachcA7QMpNRY9A9HrEoNVa+aMeuK vYSsyRD/LUVsf/ATfUrtEsiX3ANoIT3iQtKWebzVODS9w6RnUtcf1LIPbGtgQWHQo9qODm ystSZnEZDoBFk3lv3mH5/0wJRe8uGWw= X-MC-Unique: 0OrKLpWtNJizozD8XGHENw-1 From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v7 01/47] block: Add child access functions Date: Thu, 25 Jun 2020 17:21:29 +0200 Message-Id: <20200625152215.941773-2-mreitz@redhat.com> In-Reply-To: <20200625152215.941773-1-mreitz@redhat.com> References: <20200625152215.941773-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=207.211.31.81; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/25 02:30:11 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" There are BDS children that the general block layer code can access, namely bs->file and bs->backing. Since the introduction of filters and external data files, their meaning is not quite clear. bs->backing can be a COW source, or it can be a filtered child; bs->file can be a filtered child, it can be data and metadata storage, or it can be just metadata storage. This overloading really is not helpful. This patch adds functions that retrieve the correct child for each exact purpose. Later patches in this series will make use of them. Doing so will allow us to handle filter nodes in a meaningful way. Signed-off-by: Max Reitz Reviewed-by: Andrey Shinkevich Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block_int.h | 44 +++++++++++++++++-- block.c | 90 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 3 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 1b86b59af1..bb3457c5e8 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -90,9 +90,17 @@ struct BlockDriver { int instance_size; =20 /* set to true if the BlockDriver is a block filter. Block filters pass - * certain callbacks that refer to data (see block.c) to their bs->fil= e if - * the driver doesn't implement them. Drivers that do not wish to forw= ard - * must implement them and return -ENOTSUP. + * certain callbacks that refer to data (see block.c) to their bs->file + * or bs->backing (whichever one exists) if the driver doesn't impleme= nt + * them. Drivers that do not wish to forward must implement them and r= eturn + * -ENOTSUP. + * Note that filters are not allowed to modify data. + * + * Filters generally cannot have more than a single filtered child, + * because the data they present must at all times be the same as + * that on their filtered child. That would be impossible to + * achieve for multiple filtered children. + * (And this filtered child must then be bs->file or bs->backing.) */ bool is_filter; /* @@ -1370,4 +1378,34 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const cha= r *node, const char *name, BlockDriverState **bitmap_bs, Error **errp); =20 +BdrvChild *bdrv_cow_child(BlockDriverState *bs); +BdrvChild *bdrv_filter_child(BlockDriverState *bs); +BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs); +BdrvChild *bdrv_primary_child(BlockDriverState *bs); + +static inline BlockDriverState *child_bs(BdrvChild *child) +{ + return child ? child->bs : NULL; +} + +static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_cow_child(bs)); +} + +static inline BlockDriverState *bdrv_filter_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_filter_child(bs)); +} + +static inline BlockDriverState *bdrv_filter_or_cow_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_filter_or_cow_child(bs)); +} + +static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_primary_child(bs)); +} + #endif /* BLOCK_INT_H */ diff --git a/block.c b/block.c index 144f52e413..5a42ef49fd 100644 --- a/block.c +++ b/block.c @@ -6918,3 +6918,93 @@ int bdrv_make_empty(BdrvChild *c, Error **errp) =20 return 0; } + +/* + * Return the child that @bs acts as an overlay for, and from which data m= ay be + * copied in COW or COR operations. Usually this is the backing file. + */ +BdrvChild *bdrv_cow_child(BlockDriverState *bs) +{ + if (!bs || !bs->drv) { + return NULL; + } + + if (bs->drv->is_filter) { + return NULL; + } + + if (!bs->backing) { + return NULL; + } + + assert(bs->backing->role & BDRV_CHILD_COW); + return bs->backing; +} + +/* + * If @bs acts as a filter for exactly one of its children, return + * that child. + */ +BdrvChild *bdrv_filter_child(BlockDriverState *bs) +{ + BdrvChild *c; + + if (!bs || !bs->drv) { + return NULL; + } + + if (!bs->drv->is_filter) { + return NULL; + } + + /* Only one of @backing or @file may be used */ + assert(!(bs->backing && bs->file)); + + c =3D bs->backing ?: bs->file; + if (!c) { + return NULL; + } + + assert(c->role & BDRV_CHILD_FILTERED); + return c; +} + +/* + * Return either the result of bdrv_cow_child() or bdrv_filter_child(), + * whichever is non-NULL. + * + * Return NULL if both are NULL. + */ +BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs) +{ + BdrvChild *cow_child =3D bdrv_cow_child(bs); + BdrvChild *filter_child =3D bdrv_filter_child(bs); + + /* Filter nodes cannot have COW backing files */ + assert(!(cow_child && filter_child)); + + return cow_child ?: filter_child; +} + +/* + * Return the primary child of this node: For filters, that is the + * filtered child. For other nodes, that is usually the child storing + * metadata. + * (A generally more helpful description is that this is (usually) the + * child that has the same filename as @bs.) + * + * Drivers do not necessarily have a primary child; for example quorum + * does not. + */ +BdrvChild *bdrv_primary_child(BlockDriverState *bs) +{ + BdrvChild *c; + + QLIST_FOREACH(c, &bs->children, next) { + if (c->role & BDRV_CHILD_PRIMARY) { + return c; + } + } + + return NULL; +} --=20 2.26.2