From nobody Fri Nov 14 22:20:20 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759265281; cv=none; d=zohomail.com; s=zohoarc; b=Dp/w6V+cujLWjSPxWRTHodPu4zxkyXHRVlSCGX+IlFRSYY1Xohm6WuTMUSsGpyVsT1c0SD1Cy4kTCcRvWPRFmifegYecBduQdiheX+o/plpz90kwOHFiLj9FpZA8dQv5/r3h6sGzBBXfPR6KtxwSAliLdjNVMu4b7iL2EQlsVDk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759265281; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=YEKV8SOceCi8315UWrvm8kMs40DvpLQA0Xl6Ue4LHEg=; b=jJ12reDMDGBwXFIr3WbAEXuqJgEqpVi18ZdmHWQmHdjK4GvD82rZkBEz67rXUedDO5OwjiPAIRQrTAfVaCdp+KYjvNjodiNzlaMPfi2exPHD9RhWmBG4wB0w4FPkB9+1Ggqc2c2cfw0CkbD5YclOdMk0sDic3odpMl5Zot83ZqA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175926528125073.5101695099712; Tue, 30 Sep 2025 13:48:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v3hEr-0000Pj-IJ; Tue, 30 Sep 2025 16:46:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEq-0000PU-Ds for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:20 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEf-0004Am-C1 for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:20 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-218-GQX3OFUJOZeDQ7q4VSa3Aw-1; Tue, 30 Sep 2025 16:46:02 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0CAD6195609E; Tue, 30 Sep 2025 20:46:01 +0000 (UTC) Received: from localhost (unknown [10.2.16.110]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E31061800282; Tue, 30 Sep 2025 20:45:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759265163; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YEKV8SOceCi8315UWrvm8kMs40DvpLQA0Xl6Ue4LHEg=; b=bzz99DPugpUyrPNMhbYytMRe3x516DUtq5uHmHrA9amQ6/gzzNilx2M1rBE8wvKOXLHcC+ ZZYZ/U/s2NSKu8bU0nOgx2+cSamVETny+P8PjPikKu5tp8LqAKUmJPPNkRFW56SEmOCqgV K1UHd5FrLP0CMoi7pmHfCZ48SmnQi+s= X-MC-Unique: GQX3OFUJOZeDQ7q4VSa3Aw-1 X-Mimecast-MFC-AGG-ID: GQX3OFUJOZeDQ7q4VSa3Aw_1759265161 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 1/4] block: add BdrvChildClass->propagate_attach/detach() callbacks Date: Tue, 30 Sep 2025 16:45:52 -0400 Message-ID: <20250930204555.162133-2-stefanha@redhat.com> In-Reply-To: <20250930204555.162133-1-stefanha@redhat.com> References: <20250930204555.162133-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, T_SPF_TEMPERROR=0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759265282986116600 Content-Type: text/plain; charset="utf-8" bdrv_replace_child_noperm() is the heart of block graph changes. It is called when a node is inserted, removed, or replaced. These changes happen without notifying parents in the graph, so it is currently not possible to monitor changes. Add BdrvChildClass callbacks to propagate attach/detach operations to the roots of the graph. The next commit will introduce a BlockBackend API for monitoring changes using this mechanism. Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/block/block_int-common.h | 11 +++++++ block.c | 56 +++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/block/block_int-common.h b/include/block/block_int-com= mon.h index 034c0634c8..0368a3191c 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -963,6 +963,17 @@ struct BdrvChildClass { void GRAPH_RDLOCK_PTR (*activate)(BdrvChild *child, Error **errp); int GRAPH_RDLOCK_PTR (*inactivate)(BdrvChild *child); =20 + /* + * Optional callbacks when a descendant (child, grandchild, etc) attac= hes + * or detaches a BlockDriverState. Allows monitoring changes to the gr= aph. + * + * Called after ->attach() and before ->detach(). + */ + void GRAPH_WRLOCK_PTR (*propagate_attach)(BdrvChild *self, + BdrvChild *descendant); + void GRAPH_WRLOCK_PTR (*propagate_detach)(BdrvChild *self, + BdrvChild *descendant); + void GRAPH_WRLOCK_PTR (*attach)(BdrvChild *child); void GRAPH_WRLOCK_PTR (*detach)(BdrvChild *child); =20 diff --git a/block.c b/block.c index 8848e9a7ed..e1480dda04 100644 --- a/block.c +++ b/block.c @@ -1497,6 +1497,32 @@ static void GRAPH_WRLOCK bdrv_child_cb_detach(BdrvCh= ild *child) } } =20 +static void GRAPH_WRLOCK +bdrv_child_cb_propagate_attach(BdrvChild *self, BdrvChild *descendant) +{ + BlockDriverState *bs =3D self->opaque; + BdrvChild *c; + + QLIST_FOREACH(c, &bs->parents, next_parent) { + if (c->klass->propagate_attach) { + c->klass->propagate_attach(c, descendant); + } + } +} + +static void GRAPH_WRLOCK +bdrv_child_cb_propagate_detach(BdrvChild *self, BdrvChild *descendant) +{ + BlockDriverState *bs =3D self->opaque; + BdrvChild *c; + + QLIST_FOREACH(c, &bs->parents, next_parent) { + if (c->klass->propagate_detach) { + c->klass->propagate_detach(c, descendant); + } + } +} + static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *b= ase, const char *filename, bool backing_mask_protocol, @@ -1519,17 +1545,19 @@ AioContext *child_of_bds_get_parent_aio_context(Bdr= vChild *c) } =20 const BdrvChildClass child_of_bds =3D { - .parent_is_bds =3D true, - .get_parent_desc =3D bdrv_child_get_parent_desc, - .inherit_options =3D bdrv_inherited_options, - .drained_begin =3D bdrv_child_cb_drained_begin, - .drained_poll =3D bdrv_child_cb_drained_poll, - .drained_end =3D bdrv_child_cb_drained_end, - .attach =3D bdrv_child_cb_attach, - .detach =3D bdrv_child_cb_detach, - .inactivate =3D bdrv_child_cb_inactivate, - .change_aio_ctx =3D bdrv_child_cb_change_aio_ctx, - .update_filename =3D bdrv_child_cb_update_filename, + .parent_is_bds =3D true, + .get_parent_desc =3D bdrv_child_get_parent_desc, + .inherit_options =3D bdrv_inherited_options, + .drained_begin =3D bdrv_child_cb_drained_begin, + .drained_poll =3D bdrv_child_cb_drained_poll, + .drained_end =3D bdrv_child_cb_drained_end, + .attach =3D bdrv_child_cb_attach, + .detach =3D bdrv_child_cb_detach, + .propagate_attach =3D bdrv_child_cb_propagate_attach, + .propagate_detach =3D bdrv_child_cb_propagate_detach, + .inactivate =3D bdrv_child_cb_inactivate, + .change_aio_ctx =3D bdrv_child_cb_change_aio_ctx, + .update_filename =3D bdrv_child_cb_update_filename, .get_parent_aio_context =3D child_of_bds_get_parent_aio_context, }; =20 @@ -2967,6 +2995,9 @@ bdrv_replace_child_noperm(BdrvChild *child, BlockDriv= erState *new_bs) } =20 if (old_bs) { + if (child->klass->propagate_detach) { + child->klass->propagate_detach(child, child); + } if (child->klass->detach) { child->klass->detach(child); } @@ -2980,6 +3011,9 @@ bdrv_replace_child_noperm(BdrvChild *child, BlockDriv= erState *new_bs) if (child->klass->attach) { child->klass->attach(child); } + if (child->klass->propagate_attach) { + child->klass->propagate_attach(child, child); + } } =20 /* --=20 2.51.0 From nobody Fri Nov 14 22:20:20 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759265244; cv=none; d=zohomail.com; s=zohoarc; b=ddjlC1C+9odNeg9SwlEJwSkZynugycdXVzH8eMHswVvHfdYaYeobLVAnnlBHcB33olORc4rccief3kfwGeSW1a2xOysqczc+p9cqkHTkeos5ORRir2+/z3MQbondjeIPofYyI0zRwbp3heMQGvBzWBmgpp9bVac3zOkEgwm1d6g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759265244; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Eu7XUIB56qE+E3bUTWxkMbbsl4P6ahbxfR8YPn5lggM=; b=Hl2QmoL9d/rsnGu2Q3/88Ue6+qITXdJZkIkvCPyIbXDXgNZtk5Kd3zt8Pey8hAZsRWOCsvr2XDn1378MtEmLlPIIoENUnCahCb53dNQVz3Xco5c42bnwRZAeHHBctej0zR6WK3MPetNOI3U1u/ENb40dCKMOKjIzNFBvpysgSLo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759265244704425.3300642808275; Tue, 30 Sep 2025 13:47:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v3hEv-0000RH-Vn; Tue, 30 Sep 2025 16:46:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEu-0000Qd-8n for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:24 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEg-0004CE-Pc for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:24 -0400 Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-494-8zGdZMnfMiqJtdxPetn5QA-1; Tue, 30 Sep 2025 16:46:04 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F1D5419560A2; Tue, 30 Sep 2025 20:46:02 +0000 (UTC) Received: from localhost (unknown [10.2.16.110]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 887B61800577; Tue, 30 Sep 2025 20:46:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759265165; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Eu7XUIB56qE+E3bUTWxkMbbsl4P6ahbxfR8YPn5lggM=; b=XX0ws1AM4Lf1xpMOcl8z64aisBOBJhYxh+U1EQfCTo0RGJ5/o+wVGWmJF5XFfxmkPTbpCU 2bS2qryBiBpOjEHmeRpQd9w4XaoQ+yu1KOmux20fbRSqO1R4bMupwkDcPVogeeSPIsid0K yTtG3ZxwC7gkFgMrZ/m7QNAt44rOoQQ= X-MC-Unique: 8zGdZMnfMiqJtdxPetn5QA-1 X-Mimecast-MFC-AGG-ID: 8zGdZMnfMiqJtdxPetn5QA_1759265163 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 2/4] block: add blk_add_attach/detach_notifier() APIs Date: Tue, 30 Sep 2025 16:45:53 -0400 Message-ID: <20250930204555.162133-3-stefanha@redhat.com> In-Reply-To: <20250930204555.162133-1-stefanha@redhat.com> References: <20250930204555.162133-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=170.10.133.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759265248681116600 Content-Type: text/plain; charset="utf-8" Add an API to receive a callback when a BlockDriverState is attached or detached from the block graph. This allows callers to track insert, remove, and replace operations. Note that this API might be able to replace the blk_add_remove_bs_notifier() API if the callback checks that the root BDS is being removed and ignores all other calls. I think this is a bit messy though, so I kept blk_add_remove_bs_notifier(). Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/system/block-backend-global-state.h | 9 ++ block/block-backend.c | 44 ++++++ tests/unit/test-block-backend.c | 164 ++++++++++++++++++++ 3 files changed, 217 insertions(+) diff --git a/include/system/block-backend-global-state.h b/include/system/b= lock-backend-global-state.h index c3849640df..e828f271ee 100644 --- a/include/system/block-backend-global-state.h +++ b/include/system/block-backend-global-state.h @@ -97,6 +97,15 @@ void blk_remove_aio_context_notifier(BlockBackend *blk, void (*detach_aio_context)(void *), void *opaque); void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify); + +typedef struct { + BlockBackend *blk; + BlockDriverState *bs; +} BlockBackendAttachDetachArgs; + +void blk_add_attach_notifier(BlockBackend *blk, Notifier *notify); +void blk_add_detach_notifier(BlockBackend *blk, Notifier *notify); + BlockBackendRootState *blk_get_root_state(BlockBackend *blk); void blk_update_root_state(BlockBackend *blk); bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk); diff --git a/block/block-backend.c b/block/block-backend.c index f8d6ba65c1..45e31f0079 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -76,6 +76,7 @@ struct BlockBackend { =20 /* Protected by BQL */ NotifierList remove_bs_notifiers, insert_bs_notifiers; + NotifierList attach_notifiers, detach_notifiers; QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers; =20 int quiesce_counter; /* atomic: written under BQL, read by other threa= ds */ @@ -280,6 +281,30 @@ static int GRAPH_RDLOCK blk_root_inactivate(BdrvChild = *child) return 0; } =20 +static void GRAPH_WRLOCK +blk_root_propagate_attach(BdrvChild *self, BdrvChild *descendant) +{ + BlockBackend *blk =3D self->opaque; + BlockBackendAttachDetachArgs args =3D { + .blk =3D blk, + .bs =3D descendant->bs, + }; + + notifier_list_notify(&blk->attach_notifiers, &args); +} + +static void GRAPH_WRLOCK +blk_root_propagate_detach(BdrvChild *self, BdrvChild *descendant) +{ + BlockBackend *blk =3D self->opaque; + BlockBackendAttachDetachArgs args =3D { + .blk =3D blk, + .bs =3D descendant->bs, + }; + + notifier_list_notify(&blk->detach_notifiers, &args); +} + static void blk_root_attach(BdrvChild *child) { BlockBackend *blk =3D child->opaque; @@ -333,6 +358,9 @@ static const BdrvChildClass child_root =3D { .activate =3D blk_root_activate, .inactivate =3D blk_root_inactivate, =20 + .propagate_attach =3D blk_root_propagate_attach, + .propagate_detach =3D blk_root_propagate_detach, + .attach =3D blk_root_attach, .detach =3D blk_root_detach, =20 @@ -374,6 +402,8 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, u= int64_t shared_perm) qemu_co_queue_init(&blk->queued_requests); notifier_list_init(&blk->remove_bs_notifiers); notifier_list_init(&blk->insert_bs_notifiers); + notifier_list_init(&blk->attach_notifiers); + notifier_list_init(&blk->detach_notifiers); QLIST_INIT(&blk->aio_notifiers); =20 QTAILQ_INSERT_TAIL(&block_backends, blk, link); @@ -492,6 +522,8 @@ static void blk_delete(BlockBackend *blk) } assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); + assert(QLIST_EMPTY(&blk->attach_notifiers.notifiers)); + assert(QLIST_EMPTY(&blk->detach_notifiers.notifiers)); assert(QLIST_EMPTY(&blk->aio_notifiers)); assert(qemu_co_queue_empty(&blk->queued_requests)); qemu_mutex_destroy(&blk->queued_requests_lock); @@ -2512,6 +2544,18 @@ void blk_add_remove_bs_notifier(BlockBackend *blk, N= otifier *notify) notifier_list_add(&blk->remove_bs_notifiers, notify); } =20 +void blk_add_attach_notifier(BlockBackend *blk, Notifier *notify) +{ + GLOBAL_STATE_CODE(); + notifier_list_add(&blk->attach_notifiers, notify); +} + +void blk_add_detach_notifier(BlockBackend *blk, Notifier *notify) +{ + GLOBAL_STATE_CODE(); + notifier_list_add(&blk->detach_notifiers, notify); +} + BlockAcctStats *blk_get_stats(BlockBackend *blk) { IO_CODE(); diff --git a/tests/unit/test-block-backend.c b/tests/unit/test-block-backen= d.c index 4257b3f815..693383f029 100644 --- a/tests/unit/test-block-backend.c +++ b/tests/unit/test-block-backend.c @@ -24,6 +24,7 @@ =20 #include "qemu/osdep.h" #include "block/block.h" +#include "block/block_int.h" #include "system/block-backend.h" #include "qapi/error.h" #include "qemu/main-loop.h" @@ -70,6 +71,167 @@ static void test_drain_all_aio_error(void) blk_unref(blk); } =20 +static int bdrv_test_co_change_backing_file(BlockDriverState *bs, + const char *backing_file, + const char *backing_fmt) +{ + return 0; /* just return success so bdrv_set_backing_hd() works */ +} + +static BlockDriver bdrv_test =3D { + .format_name =3D "test", + .supports_backing =3D true, + .bdrv_child_perm =3D bdrv_default_perms, + .bdrv_co_change_backing_file =3D bdrv_test_co_change_backing_file, +}; + +typedef struct { + Notifier attach_notifier; + Notifier detach_notifier; + GArray *notifications; +} AttachDetach; + +typedef enum { + NOTIFY_END =3D 0, + NOTIFY_ATTACH, + NOTIFY_DETACH, +} NotificationType; + +typedef struct { + NotificationType type; + BlockDriverState *bs; +} Notification; + +static void attach_detach_append(AttachDetach *ad, NotificationType type, + BlockBackendAttachDetachArgs *args) +{ + Notification n =3D { + .type =3D type, + .bs =3D args->bs, + }; + + g_array_append_vals(ad->notifications, &n, 1); +} + +static void attach_notify(Notifier *notifier, void *data) +{ + AttachDetach *ad =3D container_of(notifier, AttachDetach, attach_notif= ier); + attach_detach_append(ad, NOTIFY_ATTACH, data); +} + +static void detach_notify(Notifier *notifier, void *data) +{ + AttachDetach *ad =3D container_of(notifier, AttachDetach, attach_notif= ier); + attach_detach_append(ad, NOTIFY_DETACH, data); +} + +static void attach_detach_init(AttachDetach *ad, BlockBackend *blk) +{ + ad->attach_notifier.notify =3D attach_notify; + ad->detach_notifier.notify =3D detach_notify; + ad->notifications =3D g_array_new(true, true, sizeof(Notification)); + + blk_add_attach_notifier(blk, &ad->attach_notifier); + blk_add_detach_notifier(blk, &ad->detach_notifier); +} + +static void attach_detach_cleanup(AttachDetach *ad) +{ + g_array_free(ad->notifications, true); + notifier_remove(&ad->detach_notifier); + notifier_remove(&ad->attach_notifier); +} + +/* + * Check that the expected notifications occurred. @expected is terminated= by a + * NOTIFY_END element. + */ +static void attach_detach_expect(AttachDetach *ad, const Notification *exp= ected) +{ + GArray *array =3D ad->notifications; + + /* The array is zero terminated so there is at least one element */ + Notification *actual =3D (Notification *)array->data; + + while (expected->type !=3D NOTIFY_END) { + g_assert_cmpint(actual->type, =3D=3D, expected->type); + g_assert(actual->bs =3D=3D expected->bs); + expected++; + actual++; + } + + g_assert_cmpint(actual->type, =3D=3D, NOTIFY_END); + + g_array_remove_range(array, 0, array->len); +} + +static void test_attach_detach_notifier(void) +{ + AttachDetach ad; + BlockDriverState *format; + BlockDriverState *file; + BlockDriverState *file2; + BlockBackend *blk =3D blk_new(qemu_get_aio_context(), + BLK_PERM_ALL, BLK_PERM_ALL); + + attach_detach_init(&ad, blk); + + format =3D bdrv_new_open_driver(&bdrv_test, "format", BDRV_O_RDWR, + &error_abort); + file =3D bdrv_new_open_driver(&bdrv_test, "file", BDRV_O_RDWR, &error_= abort); + file2 =3D bdrv_new_open_driver(&bdrv_test, "file2", BDRV_O_RDWR, + &error_abort); + + bdrv_graph_wrlock_drained(); + bdrv_attach_child(format, file, "file", &child_of_bds, + BDRV_CHILD_PRIMARY | BDRV_CHILD_DATA, &error_abort); + bdrv_graph_wrunlock(); + + /* Insert format -> file */ + blk_insert_bs(blk, format, &error_abort); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_ATTACH, format}, + {}, + }); + + /* Replace format -> file with file2 */ + blk_replace_bs(blk, file2, &error_abort); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_DETACH, format}, + (Notification){NOTIFY_ATTACH, file2}, + {}, + }); + + /* Remove file2 */ + blk_remove_bs(blk); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_DETACH, file2}, + {}, + }); + + /* These BDSes were unrefed so we need new instances */ + file =3D bdrv_new_open_driver(&bdrv_test, "file", BDRV_O_RDWR, &error_= abort); + file2 =3D bdrv_new_open_driver(&bdrv_test, "file2", BDRV_O_RDWR, + &error_abort); + + /* Replace a non-root node */ + bdrv_graph_wrlock_drained(); + bdrv_attach_child(format, file, "file", &child_of_bds, + BDRV_CHILD_PRIMARY | BDRV_CHILD_DATA, &error_abort); + bdrv_replace_node(file, file2, &error_abort); + bdrv_graph_wrunlock(); + attach_detach_expect(&ad, (Notification[]){ + (Notification){NOTIFY_ATTACH, file}, + (Notification){NOTIFY_DETACH, file}, + (Notification){NOTIFY_ATTACH, file2}, + {}, + }); + + attach_detach_cleanup(&ad); + blk_unref(blk); + bdrv_unref(format); +} + int main(int argc, char **argv) { bdrv_init(); @@ -80,6 +242,8 @@ int main(int argc, char **argv) g_test_add_func("/block-backend/drain_aio_error", test_drain_aio_error= ); g_test_add_func("/block-backend/drain_all_aio_error", test_drain_all_aio_error); + g_test_add_func("/block-backend/attach_detach_notifier", + test_attach_detach_notifier); =20 return g_test_run(); } --=20 2.51.0 From nobody Fri Nov 14 22:20:20 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759265247; cv=none; d=zohomail.com; s=zohoarc; b=hDr+I8tntDjqB/Q/lGc5fxheHqOyLRrCEZA6phr6mAzteaH2LVwCsLvRPgQjO6HJq3b08V1adjf3KvGbrZsNX4Cea7R774ugJd9Vy9qECK/cPne+PzBG/aiudBFSaF5SEPlAReza99dQjYqIiO8xsyXVnOZcopULjfctL34EtRA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759265247; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=b1lYjOtXVRjsnu5u4EX+Oa5O/2HPXPK6D7kILNxQDUY=; b=Qkmvz0KhEzaujFf+YUKLTkXNHOh2pgv/daeGMjVi16g0s5j1UKmf0e06KPLaayOpzg8nDkyDRY9VgN7VaRQHZj8gM+xCLFvmCTT+NsrLZsIQN6ZXaUt9slUYS7e4eLvGn5zZ6F4caaFL7jPk9VVsfUT1QG7Tri/uuczCcwsHlSQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759265247692901.0054764109102; Tue, 30 Sep 2025 13:47:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v3hF2-0000Xh-8X; Tue, 30 Sep 2025 16:46:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEy-0000TM-Ie for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:28 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEg-0004Ei-Hc for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:28 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-677-hPhX5qPmN3ud0COgvGRYQA-1; Tue, 30 Sep 2025 16:46:05 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 221F9195608B; Tue, 30 Sep 2025 20:46:05 +0000 (UTC) Received: from localhost (unknown [10.2.16.110]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6073919560B8; Tue, 30 Sep 2025 20:46:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759265167; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=b1lYjOtXVRjsnu5u4EX+Oa5O/2HPXPK6D7kILNxQDUY=; b=PrrdZRg08gy5IkvhoZ9YG4Qp9tEh8jSjt+WGJn+//nGjQaNLNrQcRnjE5JJ5T2isB3qkQG MHqfD4t8TovPxrIkd/x/Dqpi/wmbGQMZOGfprQA7bEFNis6UIXSSHQ+0SN1ITIvQ1LJk3I IeqEloPmeXc9tuAYA0Du+dIvBwl5EZQ= X-MC-Unique: hPhX5qPmN3ud0COgvGRYQA-1 X-Mimecast-MFC-AGG-ID: hPhX5qPmN3ud0COgvGRYQA_1759265165 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , , Hanna Reitz , Stefan Hajnoczi Subject: [PATCH 3/4] block: rename RAMBlockRegistrar->notifier field Date: Tue, 30 Sep 2025 16:45:54 -0400 Message-ID: <20250930204555.162133-4-stefanha@redhat.com> In-Reply-To: <20250930204555.162133-1-stefanha@redhat.com> References: <20250930204555.162133-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=170.10.129.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759265251133116600 Content-Type: text/plain; charset="utf-8" The 'notifier' field name will be confusing when the BlockBackend attach and detach notifiers are added in the next commit. Rename the field so it's clear that this is the RAMBlock notifier. Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/system/block-ram-registrar.h | 2 +- block/block-ram-registrar.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/system/block-ram-registrar.h b/include/system/block-ra= m-registrar.h index d8b2f7942b..76c157bd54 100644 --- a/include/system/block-ram-registrar.h +++ b/include/system/block-ram-registrar.h @@ -21,7 +21,7 @@ */ typedef struct { BlockBackend *blk; - RAMBlockNotifier notifier; + RAMBlockNotifier ram_block_notifier; bool ok; } BlockRAMRegistrar; =20 diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c index fcda2b86af..d5b84667a1 100644 --- a/block/block-ram-registrar.c +++ b/block/block-ram-registrar.c @@ -12,7 +12,8 @@ static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) { - BlockRAMRegistrar *r =3D container_of(n, BlockRAMRegistrar, notifier); + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, ram_block_notifier); Error *err =3D NULL; =20 if (!r->ok) { @@ -21,7 +22,7 @@ static void ram_block_added(RAMBlockNotifier *n, void *ho= st, size_t size, =20 if (!blk_register_buf(r->blk, host, max_size, &err)) { error_report_err(err); - ram_block_notifier_remove(&r->notifier); + ram_block_notifier_remove(n); r->ok =3D false; } } @@ -29,14 +30,15 @@ static void ram_block_added(RAMBlockNotifier *n, void *= host, size_t size, static void ram_block_removed(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) { - BlockRAMRegistrar *r =3D container_of(n, BlockRAMRegistrar, notifier); + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, ram_block_notifier); blk_unregister_buf(r->blk, host, max_size); } =20 void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk) { r->blk =3D blk; - r->notifier =3D (RAMBlockNotifier){ + r->ram_block_notifier =3D (RAMBlockNotifier){ .ram_block_added =3D ram_block_added, .ram_block_removed =3D ram_block_removed, =20 @@ -47,12 +49,12 @@ void blk_ram_registrar_init(BlockRAMRegistrar *r, Block= Backend *blk) }; r->ok =3D true; =20 - ram_block_notifier_add(&r->notifier); + ram_block_notifier_add(&r->ram_block_notifier); } =20 void blk_ram_registrar_destroy(BlockRAMRegistrar *r) { if (r->ok) { - ram_block_notifier_remove(&r->notifier); + ram_block_notifier_remove(&r->ram_block_notifier); } } --=20 2.51.0 From nobody Fri Nov 14 22:20:20 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759265284; cv=none; d=zohomail.com; s=zohoarc; b=Ci91BYrmpK+kpd+SZUroDODkt4w3dsfsUhWP1NARIEZYJELHc/4aVGuWRyVFPczBdJJd3Jw3NjuvDYl/eskmMd3dQV8TXWrRXiibdC5iRyACMTtww1q3b8tGnFEAIcWHJTRIHQ1fsibCR7mHC1CR5SAW3RGkJu6eGfWQFG3elyE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759265284; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=WBqk0CwZK1zHhdhWy93OSfCtnksmdkNPmtF5Z3YJ+50=; b=UcBTLEb+DjSzI2VLESq9kV1S64X5/L7OTLu5Z8phCPUDQaJygqXRj88Eog8TuR1fSftzGF52ZMgjRd5KiFjmW72J6yIXMcbFpBN/Ifl3uQHBrzvN3IWttVDrCxRyJSPEN0PR2adeJgQcMx0cLmXR54+KmzW/sj+2RO9ZH0TFzXE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759265284779698.1594592312641; Tue, 30 Sep 2025 13:48:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v3hF1-0000X2-A4; Tue, 30 Sep 2025 16:46:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEy-0000Sv-05 for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:28 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v3hEn-0004Gk-Sv for qemu-devel@nongnu.org; Tue, 30 Sep 2025 16:46:27 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-669-hW_jhAo0OcO-qAfK-WjsyA-1; Tue, 30 Sep 2025 16:46:08 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2D218180048E; Tue, 30 Sep 2025 20:46:07 +0000 (UTC) Received: from localhost (unknown [10.2.16.110]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B80321800452; Tue, 30 Sep 2025 20:46:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759265171; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WBqk0CwZK1zHhdhWy93OSfCtnksmdkNPmtF5Z3YJ+50=; b=UBic/GCW6ph4prMVKSjF9aZwD+v0oEiKIIyFbdWpXkMYSeT+ziinzyGgeR5yMCH3Zav8K5 5PQ/datchpYeHYZ/tLIR6iZn/lGEl1QNflKivJkWdVbpEm3twQw5ukgvGvznjiw+Dxknqj X1Y2UHIsp5d7Y//Z8PcK0P2kCijR3o8= X-MC-Unique: hW_jhAo0OcO-qAfK-WjsyA-1 X-Mimecast-MFC-AGG-ID: hW_jhAo0OcO-qAfK-WjsyA_1759265167 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Kevin Wolf , , Hanna Reitz , Stefan Hajnoczi , Yingshun Cui Subject: [PATCH 4/4] block: update inserted/removed nodes from BlockRAMRegistrar Date: Tue, 30 Sep 2025 16:45:55 -0400 Message-ID: <20250930204555.162133-5-stefanha@redhat.com> In-Reply-To: <20250930204555.162133-1-stefanha@redhat.com> References: <20250930204555.162133-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=170.10.129.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, T_SPF_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1759265286634116600 Content-Type: text/plain; charset="utf-8" BlockRAMRegistrar ensures that RAMBlocks are registered with BlockDriverStates. This is essential for vdpa-blk because they need to know the memory mappings of I/O buffers. However, BlockRAMRegistrar is currently unaware of changes to the block graph and newly inserted nodes have no RAMBlocks registered. Use the new blk_add_attach_notifier() and blk_add_detach_notifier() APIs to bring nodes up to speed when the graph changes. This fixes vdpa-blk across mirror and other operations that modify the block graph. Previously I/O would not succeed after a new node was inserted due to missing memory mappings. Buglink: https://issues.redhat.com/browse/RHEL-88175 Reported-by: Yingshun Cui Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake --- include/system/block-ram-registrar.h | 2 + block/block-ram-registrar.c | 63 +++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/include/system/block-ram-registrar.h b/include/system/block-ra= m-registrar.h index 76c157bd54..292c197d1c 100644 --- a/include/system/block-ram-registrar.h +++ b/include/system/block-ram-registrar.h @@ -22,6 +22,8 @@ typedef struct { BlockBackend *blk; RAMBlockNotifier ram_block_notifier; + Notifier blk_attach_notifier; + Notifier blk_detach_notifier; bool ok; } BlockRAMRegistrar; =20 diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c index d5b84667a1..a46b5a723f 100644 --- a/block/block-ram-registrar.c +++ b/block/block-ram-registrar.c @@ -7,7 +7,9 @@ #include "qemu/osdep.h" #include "system/block-backend.h" #include "system/block-ram-registrar.h" +#include "system/ramblock.h" #include "qapi/error.h" +#include "trace.h" =20 static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, size_t max_size) @@ -22,8 +24,8 @@ static void ram_block_added(RAMBlockNotifier *n, void *ho= st, size_t size, =20 if (!blk_register_buf(r->blk, host, max_size, &err)) { error_report_err(err); - ram_block_notifier_remove(n); - r->ok =3D false; + blk_ram_registrar_destroy(r); + return; } } =20 @@ -35,6 +37,52 @@ static void ram_block_removed(RAMBlockNotifier *n, void = *host, size_t size, blk_unregister_buf(r->blk, host, max_size); } =20 +static void blk_attached(Notifier *n, void *data) +{ + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, blk_attach_notifier); + BlockBackendAttachDetachArgs *args =3D data; + BlockDriverState *bs =3D args->bs; + Error *err =3D NULL; + + WITH_RCU_READ_LOCK_GUARD() { + RAMBlock *rb; + + RAMBLOCK_FOREACH(rb) { + ram_addr_t max_size =3D qemu_ram_get_max_length(rb); + void *host =3D qemu_ram_get_host_addr(rb); + + if (!bdrv_register_buf(bs, host, max_size, &err)) { + goto err; + } + } + } + + return; + +err: + error_report_err(err); + blk_ram_registrar_destroy(r); +} + +static void blk_detached(Notifier *n, void *data) +{ + BlockRAMRegistrar *r =3D + container_of(n, BlockRAMRegistrar, blk_attach_notifier); + BlockBackendAttachDetachArgs *args =3D data; + BlockDriverState *bs =3D args->bs; + RAMBlock *rb; + + RCU_READ_LOCK_GUARD(); + + RAMBLOCK_FOREACH(rb) { + ram_addr_t max_size =3D qemu_ram_get_max_length(rb); + void *host =3D qemu_ram_get_host_addr(rb); + + bdrv_unregister_buf(bs, host, max_size); + } +} + void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk) { r->blk =3D blk; @@ -47,14 +95,25 @@ void blk_ram_registrar_init(BlockRAMRegistrar *r, Block= Backend *blk) * value that does not change across resize. */ }; + r->blk_attach_notifier =3D (Notifier){ + .notify =3D blk_attached, + }; + r->blk_detach_notifier =3D (Notifier){ + .notify =3D blk_detached, + }; r->ok =3D true; =20 ram_block_notifier_add(&r->ram_block_notifier); + blk_add_attach_notifier(blk, &r->blk_attach_notifier); + blk_add_detach_notifier(blk, &r->blk_detach_notifier); } =20 void blk_ram_registrar_destroy(BlockRAMRegistrar *r) { if (r->ok) { + notifier_remove(&r->blk_detach_notifier); + notifier_remove(&r->blk_attach_notifier); ram_block_notifier_remove(&r->ram_block_notifier); + r->ok =3D false; } } --=20 2.51.0