From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24BB32DBF45; Mon, 16 Jun 2025 13:25:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080359; cv=none; b=B7WKYT1Cg7RA3LvGvjgc40HGoNIOPrIWogNBXOJJIjamHs8G0VAZzstaXk3N/ttiBx5e6UfsN2U2zjL+jL90Q6Ila7GThQotz1PVAD44cj8JwyUvVO2k4rKq1wUiSn7nThCvEzGBAPQTDDU/UoJVTQ70E/mdMnlKxlsF9WxMgvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080359; c=relaxed/simple; bh=kK2Vz4P5l+EAGPswcRexlePDdTbNhMuqAdi5ThpTaQI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=grxqcZZioPGq5QYjrN7MI4AYwhCQUtjIp7uJHlV+hMv/DlmXphyFwquhQmSqqhGbZiattZBHJYlYgePmAeMo0IEXQ7frQtf2z4q4endrJsYjA2417gAuNOZffNcwbLnsAG5+pKtxKdRDaEnc7OK/1s6OrU0db+Wl9vCjTSU29OQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MMw/dSYw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MMw/dSYw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 09E44C4CEEA; Mon, 16 Jun 2025 13:25:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080358; bh=kK2Vz4P5l+EAGPswcRexlePDdTbNhMuqAdi5ThpTaQI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MMw/dSYwphEO2gU5X3BpmelGP1uamo1SIeM+qt+L8emZ1io6KHRKsD0rP/ej5ony6 reXqWJnNMrpqOxYZXxuAT8tCT0oq4naDWLcDaDYgcKxfe1cwVy0d8tsUdSx/VdZUfv qopXW+Z/U3u+g8hrBIu6G3VBevu+R8Ia9Q+mwwzoKUns+v+URq8XJlPxFdxw4s6o56 szhqV+WW39cjWRcHsDBgn+DcOHmpw86GjOva9Dr05cd71HKfBSArmH4bUZPjveUWD3 sU7fIlG+HBCnsp1Q+LbCQVNQiAg/5EURgarSMFtovcaPSHOYC7zX+qrBeW5zshA7hm QdS4+08nqq2LA== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:51 +0200 Subject: [PATCH 1/9] rust: block: remove trait bound from `mq::Request` definition Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-1-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=855; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=kK2Vz4P5l+EAGPswcRexlePDdTbNhMuqAdi5ThpTaQI=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsKzk0UeqCgYRE3RGq6EsAzP7CLTqhCaQ8nP aHIyYFu/U2JAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbCgAKCRDhuBo+eShj d/9OD/0ehczKDfXNxl50GSB+zKd5SB9+uUN/lpE30CxCfq0uwOX6LiiIfLiJ1f4H7rq14NSwzhC LEv5QXzjFcFHPDTZGhoQOnB4N5u9mH2tpj+++AK4v9HQHFLyG7mzz7c/W4mUNq/7lz5UaL0MZWy Iy4IPizWNnRAIilqch3z2ZX4u0y69WzO/ej+KCnv5wrOeqVex/waeqPOr7d2e74ZRBKciyUdqwk ONVPflnUZwQA7eYWNkAiiYdG87alZ7WnbTU+pRQb0F95xuoiL454otSjmqISGGkepgOzWgVcqEF nZAwdgybzzy0JPQg7brkOXZC6BcxTG8U3lckDJK7drAP+djBC1JvTkqQuSbTv6O+9JJ9bSbPjv6 tPbswn0Ri02mu1o1u+ZeflkHB89guNKnb4mdqpx2hRqLIPNAwnj17eWfwpXeAotJ+e6kS7NbPWC buAE/hQ/IF2rle1aM+ldi2XMA5k+aYPsLJOeelp/eTUi/SN+2sni+rUkIR8u80+TjYl2VUB/duQ o3fxFjK5z/PVfvDkgErXAJ01ZyZk/RId/pLlZgBDCs3CnZyRS6wmMCsNio9sp0TaJbfYBEJGKrH 5XQHPooEXX1ZyzYmkeHfQcY51PZnkmcr3f8wfjsYQyIeWH/YJJENH+PRAn6QpxwJtIcq4qocJy6 COZG6ti+yB9IVWQ== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Remove the trait bound `T:Operations` from `mq::Request`. The bound is not required, so remove it to reduce complexity. Signed-off-by: Andreas Hindborg --- rust/kernel/block/mq/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request= .rs index 4a5b7ec914ef..2d14a6261a31 100644 --- a/rust/kernel/block/mq/request.rs +++ b/rust/kernel/block/mq/request.rs @@ -53,7 +53,7 @@ /// [`struct request`]: srctree/include/linux/blk-mq.h /// #[repr(transparent)] -pub struct Request(Opaque, PhantomData); +pub struct Request(Opaque, PhantomData); =20 impl Request { /// Create an [`ARef`] from a [`struct request`] pointer. --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33D902E06E0; Mon, 16 Jun 2025 13:26:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080365; cv=none; b=dRbqD1EtVcgb5mF0MfW2fgshLJTdEdlVmKsQt8SZRC/ZZApFD+u2q+wa+O0sFV/TWnmeI+9GQTMSQCUww7oJg4qqdDnLjMFGifiBMqzK48yrKuL6tTNQfEECBRdcb/BOHZLAEMkyGyW/FUHaNBe2KLr4OEhoKOf3pl7CxUQmhKA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080365; c=relaxed/simple; bh=UIGqb28OhjGi0ShhnGEPp1GLyZDUYd5N5Zi5nYnQrJQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JFtaaGxWt3hcmzksBYza9BZs1JqvSpCBc7kcnnaEpy99ct+lF95MKSIKvUiXVlPFj64uvG+zyyO6UxwTil0zNzEhi+eoGVGieug3onZSQJmLG0B7bGK1cMiXI6ePetbdhDLpTE7VxrC65hyM1lNdV74RH9OF8fmiw/s/aqISCPY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dhJON0XK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dhJON0XK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 573AAC4CEEA; Mon, 16 Jun 2025 13:26:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080364; bh=UIGqb28OhjGi0ShhnGEPp1GLyZDUYd5N5Zi5nYnQrJQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dhJON0XKg+NgBXbCcLLwCLCHdtrnxTiLT4j8arcj7jMSmtlSOvHxYgie8IuWk3oY4 zvcYG7x4Zg6IVMYNPvO74VlnJEZrcllzmPAieCMROvTx8+ZskktVXZS8l/GGpzeB9U aTfi22vrQvZntbNYaeYrvJ+gnDEsr005bjIxgWgaH7DWNVqI8BX+KSbm+/BHpCSHqO DNSrwI7k289HVPmDkUOIL8AArmrZaRql6orGedvpq7CjLFEow7gPV9pQiuSKlBMDJj 3IMGytEoXGFIjuDSXtrV6XhBcGoPriqeWSBdAS7lDRVXqUCcRYXVFLtRdXAADncDT8 d7yKGfFow17PA== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:52 +0200 Subject: [PATCH 2/9] rust: block: add block related constants Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-2-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=961; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=UIGqb28OhjGi0ShhnGEPp1GLyZDUYd5N5Zi5nYnQrJQ=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsLt44lXpykJGpSDz2lZX4hbtWnNegNyeE1l qkxc0Y+elqJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbCwAKCRDhuBo+eShj d+e1EACpZbZvhtMlv8Xw/JAufrfAJ7FtM6sl44AhN8GSGQyqm0egya/Kwx1Re+MtzHAlGpKete6 9KHTglXEXEsVXrl60388Mc6zPrryXe3k9sqFy3ALVGZjKHxbJH7w3iK6MOw2g2P4CTH1jRS1AXR ltDyMnO4bvD6A3nrzAFr1RNFESm1BvfQAnto3+7OBP1rpZEmYJBZHihR2nG6+aLZstwwSqXm+9t Jqm/gkc6Z0t02TyQgfyp3gOSBbdBSkNTisV1CtBMNHpEoqL2dl5KOA7atDCDkNv5i1T5GREHsy1 zTK9/qse53WcLPnP+t/qshWbwSAzswKt3xofctboQd2779Ibh7Z6N9RRvHPFmdBTtw9TUAnXGUQ a9QpmN0gc95cglwUFKj8WdY9KOdXltU/0RNM+mP4jcZgyHNzIhQEFn2tiswakQQKCGSLonqkmeK tOvPTtnrm1SYY9n7CvZD3rLxbmrkSwIQP2RcODxJY948WoHayrQuN/5qriAd4sQVpRkbePgJ9/+ tJX8k7NU/jQ8vgNkWf2r4KV2kTeoRyrjfdOxSXedDO/Eefe0D4Jmt39XnH6jLzIYhHPyYhnh8w6 ckThm54dnqIQOLz3hfDtzIrxdzg6up5M/oQ0p4fIfyVot785GFQZ/gLrqEfGth8j5cWXk0GMbIc F+OrtwGnzc1R1ng== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Add a few block subsystem constants to the rust `kernel::block` name space. This makes it easier to access the constants from rust code. Signed-off-by: Andreas Hindborg --- rust/kernel/block.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rust/kernel/block.rs b/rust/kernel/block.rs index 150f710efe5b..7461adf4d7e0 100644 --- a/rust/kernel/block.rs +++ b/rust/kernel/block.rs @@ -3,3 +3,15 @@ //! Types for working with the block layer. =20 pub mod mq; + +/// Bit mask for masking out [`SECTOR_SIZE`] +pub const SECTOR_MASK: u32 =3D bindings::SECTOR_MASK; + +/// Sectors are size `1 << SECTOR_SHIFT`. +pub const SECTOR_SHIFT: u32 =3D bindings::SECTOR_SHIFT; + +/// Size of a sector. +pub const SECTOR_SIZE: u32 =3D bindings::SECTOR_SIZE; + +/// Power of two difference in size of a page and size of a sector. +pub const PAGE_SECTORS_SHIFT: u32 =3D bindings::PAGE_SECTORS_SHIFT; --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A5D32F363D; Mon, 16 Jun 2025 13:26:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080384; cv=none; b=XALtYd1x49SEYHeAxny0qPq5FXglJozvkIOd68aTQvaKuVGBY6m5JvRoXuc2Ra18llKaMVW+45CjVgVucvojNccxVZgeoNh9E69FuXBzbDcZ+tynArb8seakyQjx2rpg2JxqLDo2zoX5d2Q4OtfmPE2rBvuhZ5rFraCAIk9keWs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080384; c=relaxed/simple; bh=Xy4pDJyFz8OGfWuNES6lZszWTLpneVMuG7SL/mculR4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kr9kuAWfruVAAQZ8WhQizOYcLoZr7y+GLNlDehZr+5P9nXu6ctOzt0LX3fGzwo3dQNLLQH23vDGGTq5yUkB/10X8pXZbqFU8nOv2tCDNuWD0VOa+cP9feBXpoyWVnRLeh26nmU/lmrfC6Ng/9TrmcpmIzqAT4Uwi8/eKsIxyaZc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VtBvcjrN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VtBvcjrN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C8E2C4CEED; Mon, 16 Jun 2025 13:26:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080383; bh=Xy4pDJyFz8OGfWuNES6lZszWTLpneVMuG7SL/mculR4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VtBvcjrNBhyGSteNt40vjNLy/u3qSJpEeoBRQoSHYBkhNq5nbQ4CK9xSOPHZobf+D xCdzmBbcRgpeHEqVicOx0F6DI4DLXJLwG+xjzv6iP+0ayYpPEURck9XG3XItNPhC+7 BHFfREfiwSFpP9XIteQ1OFHc6Jg2egXRZ8XTb/jemP7dOqHF2gQ+YazPh+qhh5d5+p 8O5GEarGLiqOq4mkQ76KWkFLGkvgfOGkuqN/P0sb+Ju80yU0R5h5ttJ9GUJMqKEs+G LxbHzdkLJpiqams2ENXeGEoyaWF/p/HRZQKzRST8k7T8FFB2mKu14hVTpVYC4z9QQw JXz8gM4+uDCig== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:53 +0200 Subject: [PATCH 3/9] rust: block,core: rename `RawWriter` to `BufferWriter` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-3-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4734; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=Xy4pDJyFz8OGfWuNES6lZszWTLpneVMuG7SL/mculR4=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsMfSsfIU2x8vir85/W36Zd1c9jT2rWnH4/s 3CWw5F33KqJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbDAAKCRDhuBo+eShj d7EtD/9fnPiUMZOU1FZDKFyILpEcOaP7FCJ7kn1RrBH8mhYofXPV+7f2z71RnHB0h/bM26cNTZz g3U6tGu0o6MHuSDqGOHXcWyWl45svJqLep7VQ0zVvWYvjhZtvOjvNa243eBZB2BccOsN3AC5e1I qfrsFWbowH8c0lUMbg4ey/S8Hlg/sLbUHZoDVfrUZe6hl12jRRhZ+8hT8X+FXS1x15o8bE0ct/Q JR84tq/w9JaKf3jXseI25yGe+It95ZQQoBn+HzPPJQivjcQlUqM7k7Pw23bO8KM1HwKIZhg0FyI BN2/7WN1mrzwAvAFUoTQx1v87jSAf6hRAnUPp1fbBHF2n373gPOGpHvw8t3jUGGZ6Kv7NDbXitK vdPoJXjhaRdqlhSXN8MT0ORTm6Nf8HkaLxjkW50viGxFxVOLsN3MODxAvanREzNpzPn2T+pBJo8 g1gNEfeYwvKxM6ON17gTwRJ2z22WZcpfn9QBYzQJlwqctSIUv1yuVXHg6E/XbOoPe9an/4tvfRk d24ZJya1C2Al0QGtexJsO6Sl55K0oojp2jowaRJnB8j2noU4kiDxlseEy57u9pMC4LI4ToAD2+h 6TmrM0Zj0A6wpm+95yAvIiR6pKLt+d4X2WMZzMvZSat1yJof2pbowMkyvfKFs+YNFMqEHYUIv4W xSEODMIUN0a2cCg== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Rename the `RawWriter` to `BufferWriter`, wihich is a more suitable name. Also move the module from `block` to `str`. The ability to format a string to a byte buffer is something that is not specific to `block`, so there is no reason this code should live in `block`. Signed-off-by: Andreas Hindborg --- `BufferWriter` is used in `rnull` for interacting with `configfs`. --- rust/kernel/block/mq.rs | 1 - rust/kernel/block/mq/gen_disk.rs | 9 +++++---- rust/kernel/str.rs | 3 +++ .../{block/mq/raw_writer.rs =3D> str/buffer_writer.rs} | 17 +++++++++++= ------ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs index fb0f393c1cea..faa3ccb5a49a 100644 --- a/rust/kernel/block/mq.rs +++ b/rust/kernel/block/mq.rs @@ -89,7 +89,6 @@ =20 pub mod gen_disk; mod operations; -mod raw_writer; mod request; mod tag_set; =20 diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_di= sk.rs index cd54cd64ea88..a04b709514ac 100644 --- a/rust/kernel/block/mq/gen_disk.rs +++ b/rust/kernel/block/mq/gen_disk.rs @@ -5,10 +5,11 @@ //! C header: [`include/linux/blkdev.h`](srctree/include/linux/blkdev.h) //! C header: [`include/linux/blk_mq.h`](srctree/include/linux/blk_mq.h) =20 -use crate::block::mq::{raw_writer::RawWriter, Operations, TagSet}; +use crate::block::mq::{Operations, TagSet}; use crate::{bindings, error::from_err_ptr, error::Result, sync::Arc}; use crate::{error, static_lock_class}; use core::fmt::{self, Write}; +use kernel::str::BufferWriter; =20 /// A builder for [`GenDisk`]. /// @@ -139,14 +140,14 @@ pub fn build( // SAFETY: `gendisk` is a valid pointer as we initialized it above unsafe { (*gendisk).fops =3D &TABLE }; =20 - let mut raw_writer =3D RawWriter::from_array( + let mut writer =3D BufferWriter::from_array( // SAFETY: `gendisk` points to a valid and initialized instanc= e. We // have exclusive access, since the disk is not added to the V= FS // yet. unsafe { &mut (*gendisk).disk_name }, )?; - raw_writer.write_fmt(name)?; - raw_writer.write_char('\0')?; + writer.write_fmt(name)?; + writer.write_char('\0')?; =20 // SAFETY: `gendisk` points to a valid and initialized instance of // `struct gendisk`. `set_capacity` takes a lock to synchronize th= is diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index a927db8e079c..050793fb7d3a 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -936,3 +936,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Resul= t { macro_rules! fmt { ($($f:tt)*) =3D> ( ::core::format_args!($($f)*) ) } + +mod buffer_writer; +pub use buffer_writer::BufferWriter; diff --git a/rust/kernel/block/mq/raw_writer.rs b/rust/kernel/str/buffer_wr= iter.rs similarity index 77% rename from rust/kernel/block/mq/raw_writer.rs rename to rust/kernel/str/buffer_writer.rs index 7e2159e4f6a6..364842a6cff8 100644 --- a/rust/kernel/block/mq/raw_writer.rs +++ b/rust/kernel/str/buffer_writer.rs @@ -10,14 +10,14 @@ /// # Invariants /// /// `buffer` is always null terminated. -pub(crate) struct RawWriter<'a> { +pub struct BufferWriter<'a> { buffer: &'a mut [u8], pos: usize, } =20 -impl<'a> RawWriter<'a> { - /// Create a new `RawWriter` instance. - fn new(buffer: &'a mut [u8]) -> Result> { +impl<'a> BufferWriter<'a> { + /// Create a new [`Self`] instance. + pub fn new(buffer: &'a mut [u8]) -> Result> { *(buffer.last_mut().ok_or(EINVAL)?) =3D 0; =20 // INVARIANT: We null terminated the buffer above. @@ -26,16 +26,21 @@ fn new(buffer: &'a mut [u8]) -> Result> { =20 pub(crate) fn from_array( a: &'a mut [crate::ffi::c_char; N], - ) -> Result> { + ) -> Result> { Self::new( // SAFETY: the buffer of `a` is valid for read and write as `u= 8` for // at least `N` bytes. unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr().cast::= (), N) }, ) } + + /// Return the position of the write pointer in the underlying buffer. + pub fn pos(&self) -> usize { + self.pos + } } =20 -impl Write for RawWriter<'_> { +impl Write for BufferWriter<'_> { fn write_str(&mut self, s: &str) -> fmt::Result { let bytes =3D s.as_bytes(); let len =3D bytes.len(); --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 196982ECEAD; Mon, 16 Jun 2025 13:26:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080378; cv=none; b=htocEjOMHkW2vlU/hp1Hj7qAbY2dWgRX432HMXFQkueu+wpZjqLhVIxPrVYawpDCiUX1TiyzdtqImoWwN+Z4yjrDpdJBIDhiuHYs4sZv6ta0CRjU3QxkHMASqQXTUBdIB+tbDGXQAgvZj8xDR24nkR+AT3iXTXDBYegBIAdp4J4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080378; c=relaxed/simple; bh=7kKEIeuBmyNvAHyL84OBtlsy59K5vqkobCWeseIJrWM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lRvPixE9lzbUgnKIL3ZwWXSqGLNi7eu7Mw/ldaFZbmfU3hdIm2omJO5k2aOt9UU1t7lx0rCP1ljqbFVVZYEHudPxFq4acuI5KQPJQsRE0pnf0kXiBKAkUT6rVIT01Qq6WsYKIpS0hCeYVGdOwL7aau9by4NL8uT9eAvlwi5n4HQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jPgCMLga; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jPgCMLga" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1070EC4CEED; Mon, 16 Jun 2025 13:26:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080377; bh=7kKEIeuBmyNvAHyL84OBtlsy59K5vqkobCWeseIJrWM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jPgCMLgaC1cj6E4EQkkfulSy6mf13vILeDY5T4XNoZ6V9vKc7EhaQ4jeyExSAjWLc 0MF4XIsQCSFSRERpBtDPImVYAVmd0CjoLoWsrSdRqPgqN+8GagD2+Dqr9H70VWNiRG 9tOLjkyj9spKeYDaUdq3Y2IxB/EQT7osGEeq5PkmKNtvr1eCqIGzJA5vR6LN1CzunM aBm/RB4fWQ4sgZJXRRkAloAh6XzoXai/y5Ml1eqRrkVfC/td/MiTf36fzlm4j3emCi Fh8mpA+bXYbYLCiURhGCJ47EFSsIsa7FXPNwUFydggg0pA5ItQsekIGGiDXMv9Xv9r aJef3LkqNlJJA== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:54 +0200 Subject: [PATCH 4/9] rnull: move driver to separate directory Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-4-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=3672; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=7kKEIeuBmyNvAHyL84OBtlsy59K5vqkobCWeseIJrWM=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsNuWVooiswOAiBS7iM03o7bREFopLpUcPYw 0RkYsMOHeWJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbDQAKCRDhuBo+eShj d+1mEACo74mjrLW2U1XkyKPDe2+32sTt7tbG6qKFDMPh0HCp6TgYQv3zCw6WYhyW00+wS77qoYZ JijdGVyiwCzntQEPxY0bo+GMaE6f3FTenbI7CKPgtDcWhWKsBo7XmkSejEkOdpbCHD7xN+41HJO /iteEgs1/Vxuy1q9EkKZSv+860wfr+X5LtmwqR/mQncbfP1Wls7yK8oyvcLk1bZhGAjJTHf+Ix9 dvlzBNOE80c/UdfBqGA+sjuBXfA3QP3nnKJxpKEWmNilfB6NqTQtUdipoNEaKBlaNXO1JMs0Eg9 v5nWwbpOueZGjL7HQCetRDBblc2Xi2Fg4Gl7ODgd/VV794KpBMTJfJyCYza4YGNXNOJVJmCaxHn Glg2YSIjsL//y8hwZaPXyvbO09WzPJHl61MuuuuppBGkeBKU/6wM1SNrgRBi3UnX2nUOXsNMzoU fazsjSPuZHkndM/E76t7s/J/3t5ZZOKLEGvC6BwQvHZi5q3rqRjrYsDIkKykfxqavYKLormW3uK A5aw2eId196EaWWF6x2aHsD+IMfRpq+wZSQPUFzS+BBpjxda+N84Cc5vMMiPJ9BTvWZ0HvKTEgK /5SDizKlkf13d11xnTnje4g5SurDCgvHt8AXEEhFT10Yzvn1rJuBTbC6LB7LtHNKSr+Rlr2MZJY BFaShSqUwnfqSWA== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 The rust null block driver is about to gain some additional modules. Rather than pollute the current directory, move the driver to a subdirectory. Signed-off-by: Andreas Hindborg --- MAINTAINERS | 2 +- drivers/block/Kconfig | 10 +--------- drivers/block/Makefile | 4 +--- drivers/block/rnull/Kconfig | 13 +++++++++++++ drivers/block/rnull/Makefile | 3 +++ drivers/block/{ =3D> rnull}/rnull.rs | 0 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 0c1d245bf7b8..29b14aec3559 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4246,7 +4246,7 @@ W: https://rust-for-linux.com B: https://github.com/Rust-for-Linux/linux/issues C: https://rust-for-linux.zulipchat.com/#narrow/stream/Block T: git https://github.com/Rust-for-Linux/linux.git rust-block-next -F: drivers/block/rnull.rs +F: drivers/block/rnull/ F: rust/kernel/block.rs F: rust/kernel/block/ =20 diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 0f70e2374e7f..6b50dbc0495b 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -17,6 +17,7 @@ menuconfig BLK_DEV if BLK_DEV =20 source "drivers/block/null_blk/Kconfig" +source "drivers/block/rnull/Kconfig" =20 config BLK_DEV_FD tristate "Normal floppy disk support" @@ -354,15 +355,6 @@ config VIRTIO_BLK This is the virtual block driver for virtio. It can be used with QEMU based VMMs (like KVM or Xen). Say Y or M. =20 -config BLK_DEV_RUST_NULL - tristate "Rust null block driver (Experimental)" - depends on RUST - help - This is the Rust implementation of the null block driver. For now it - is only a minimal stub. - - If unsure, say N. - config BLK_DEV_RBD tristate "Rados block device (RBD)" depends on INET && BLOCK diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 097707aca725..aba3e93d5014 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -9,9 +9,6 @@ # needed for trace events ccflags-y +=3D -I$(src) =20 -obj-$(CONFIG_BLK_DEV_RUST_NULL) +=3D rnull_mod.o -rnull_mod-y :=3D rnull.o - obj-$(CONFIG_MAC_FLOPPY) +=3D swim3.o obj-$(CONFIG_BLK_DEV_SWIM) +=3D swim_mod.o obj-$(CONFIG_BLK_DEV_FD) +=3D floppy.o @@ -39,6 +36,7 @@ obj-$(CONFIG_ZRAM) +=3D zram/ obj-$(CONFIG_BLK_DEV_RNBD) +=3D rnbd/ =20 obj-$(CONFIG_BLK_DEV_NULL_BLK) +=3D null_blk/ +obj-$(CONFIG_BLK_DEV_RUST_NULL) +=3D rnull/ =20 obj-$(CONFIG_BLK_DEV_UBLK) +=3D ublk_drv.o obj-$(CONFIG_BLK_DEV_ZONED_LOOP) +=3D zloop.o diff --git a/drivers/block/rnull/Kconfig b/drivers/block/rnull/Kconfig new file mode 100644 index 000000000000..6dc5aff96bf4 --- /dev/null +++ b/drivers/block/rnull/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Rust null block device driver configuration + +config BLK_DEV_RUST_NULL + tristate "Rust null block driver (Experimental)" + depends on RUST + help + This is the Rust implementation of the null block driver. Like + the C version, the driver allows the user to create virutal block + devices that can be configured via various configuration options. + + If unsure, say N. diff --git a/drivers/block/rnull/Makefile b/drivers/block/rnull/Makefile new file mode 100644 index 000000000000..11cfa5e615dc --- /dev/null +++ b/drivers/block/rnull/Makefile @@ -0,0 +1,3 @@ + +obj-$(CONFIG_BLK_DEV_RUST_NULL) +=3D rnull_mod.o +rnull_mod-y :=3D rnull.o diff --git a/drivers/block/rnull.rs b/drivers/block/rnull/rnull.rs similarity index 100% rename from drivers/block/rnull.rs rename to drivers/block/rnull/rnull.rs --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B5072877C5; Mon, 16 Jun 2025 13:26:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080387; cv=none; b=IIzp+pWHQYdZMkFhSt9JGi7ycl5EVYzBfnH+W3ccDl0G+gb+wvcMW9GgZPfu4bvjOmjiXpR1HJ/L6hP/qAi4l9MK8G4aDUDDMMQK1A5IWRv/cRhypuLaROSKqm+4qQLhlJ0CTpVfeKubPO0yLmz372uCQdk/vy6QQpXj2jlEovU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080387; c=relaxed/simple; bh=bsIMENmfiGwVNughGF1+CFgnbpU5HmIuIzJX6r2w+QQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z6gCifDpZlmuQIZ78TN/0oJQQCxv5m1RF8/M3/JnKvmNxoxV229nGOXy2yqDDnm8j57D7LWO1o88moquLizhyiHog5PUJ6SFCP72I7HtT5xoHAF5XI7yoKomhBeGyFquuODl1HVle7CZlNuqeGcwhRBrC7ZaanCalJ4kqsHNy5E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=biNVG4xM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="biNVG4xM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70689C4CEF0; Mon, 16 Jun 2025 13:26:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080387; bh=bsIMENmfiGwVNughGF1+CFgnbpU5HmIuIzJX6r2w+QQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=biNVG4xME3Kp6hbTQq1Nn8ZMO87lZ2fgSnxLPK2ES9Hr4wYfye2Uj4isdJRSofoT1 5YZPgQgnfV8fz5fjwKyMnzBkkGUJkzMHWqpnsEz/QC6dBa8kL6vrWjd4XwOI0B4cHM fpudcGuughJJTrJ9J/znp37JJ/d3YT++Bo0bk8+sFTbBOWfupGjY0HlX6eNlXaaVh3 GHgo3sdSMU/bEa/movVSrcNQldFL9jpIlLYjH85fVbdSke3YEoNc2VU9LXaQ0IUZrN xAJDSzB3Wh37tB9MCgoHbZkTDyD+7lfUm8av2rKmNSQYfG+An1/kffV1ZaBuXTrTUw HwapCPJxmC4ww== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:55 +0200 Subject: [PATCH 5/9] rnull: enable configuration via `configfs` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-5-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=10856; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=bsIMENmfiGwVNughGF1+CFgnbpU5HmIuIzJX6r2w+QQ=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsOtuEuLxNkwhtiH7zfUfQrdgMsWPBmpIzOv /xKW+PFFL6JAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbDgAKCRDhuBo+eShj dwVKEACU0Y1gFSPvPyu4UBbnLSI/2k3g7k9qpRY04jrzVq+hTSzBvUiNkAcZMQFrySNtN3WCdXL Y8MC9KYioTEUnnhzkctwsQmxeptUeC4uY/2w9igbrLvIxDQTlQC0CJXLc2QEOfLCsKx/Xby/LAE /0MHkfmZWnQc7mfAMdkW6QWID5lkdOXZpZwIC+61VRJFznzD+0pkIIGKg5U+AAS+LU8ZDATssTb q8iacQmZrrSMuycZeiZmrVUirrDHWGiF9h87Umvq9kfT9k3rc54B1SXJ4VtbtWq3SxBb8t1f5YM RIged9wdossTSEjagefxVBrePra2UOZgXHh9CX3R02Oisan2oGUu8i0Muk/6VNtautSzdEYVROt i4AntLVuJbSRMuubkvhQN5V80QXtyu8U+UtA3/NRvrwcPcv8qk58xtxUHbJY0SQjeXKovx9G4K7 +JDonZotB+FbP1UgwHVfCVcoNhaU6NTtI2/I7tJZzMMyvCTkx9x4qBo36vsiyn5gKQIB12VZIeE +bCCrM9c47TmLzpV7VNWdTKyWhLREaqa7tEaEu4wa0aQJItzXseFEDfI57wK2SrLv1300IceKd+ X+WjotY1DhSjw1RlpzIfUdyRzBksvNyh39JvM4unajw7F4eUxdzvCVoZzjy9s/5nK9fnxcSA1oi xY4SXcA8Y4fpEuQ== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Allow rust null block devices to be configured and instantiated via `configfs`. Signed-off-by: Andreas Hindborg --- drivers/block/rnull/Kconfig | 2 +- drivers/block/rnull/configfs.rs | 220 +++++++++++++++++++++++++++++++++++= ++++ drivers/block/rnull/rnull.rs | 58 ++++++----- rust/kernel/block/mq/gen_disk.rs | 2 +- 4 files changed, 253 insertions(+), 29 deletions(-) diff --git a/drivers/block/rnull/Kconfig b/drivers/block/rnull/Kconfig index 6dc5aff96bf4..7bc5b376c128 100644 --- a/drivers/block/rnull/Kconfig +++ b/drivers/block/rnull/Kconfig @@ -4,7 +4,7 @@ =20 config BLK_DEV_RUST_NULL tristate "Rust null block driver (Experimental)" - depends on RUST + depends on RUST && CONFIGFS_FS help This is the Rust implementation of the null block driver. Like the C version, the driver allows the user to create virutal block diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs= .rs new file mode 100644 index 000000000000..315e04fbf14f --- /dev/null +++ b/drivers/block/rnull/configfs.rs @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 + +use super::{NullBlkDevice, THIS_MODULE}; +use core::fmt::Write; +use kernel::{ + block::mq::gen_disk::{GenDisk, GenDiskBuilder}, + c_str, + configfs::{self, AttributeOperations}, + configfs_attrs, new_mutex, + page::PAGE_SIZE, + prelude::*, + str::CString, + sync::Mutex, +}; +use pin_init::PinInit; + +pub(crate) fn subsystem() -> impl PinInit, Error> { + let item_type =3D configfs_attrs! { + container: configfs::Subsystem, + data: Config, + child: DeviceConfig, + attributes: [ + features: 0, + ], + }; + + kernel::configfs::Subsystem::new(c_str!("rnull"), item_type, try_pin_i= nit!(Config {})) +} + +#[pin_data] +pub(crate) struct Config {} + +#[vtable] +impl AttributeOperations<0> for Config { + type Data =3D Config; + + fn show(_this: &Config, page: &mut [u8; PAGE_SIZE]) -> Result { + let mut writer =3D kernel::str::BufferWriter::new(page)?; + writer.write_str("blocksize,size,rotational\n")?; + Ok(writer.pos()) + } +} + +#[vtable] +impl configfs::GroupOperations for Config { + type Child =3D DeviceConfig; + + fn make_group( + &self, + name: &CStr, + ) -> Result, Error>> { + let item_type =3D configfs_attrs! { + container: configfs::Group, + data: DeviceConfig, + attributes: [ + // Named for compatibility with C null_blk + power: 0, + blocksize: 1, + rotational: 2, + size: 3, + ], + }; + + Ok(configfs::Group::new( + name.try_into()?, + item_type, + // TODO: cannot coerce new_mutex!() to impl PinInit<_, Error>,= so put mutex inside + try_pin_init!( DeviceConfig { + data <- new_mutex!( DeviceConfigInner { + powered: false, + block_size: 4096, + rotational: false, + disk: None, + capacity_mib: 4096, + name: name.try_into()?, + }), + }), + )) + } +} + +#[pin_data] +pub(crate) struct DeviceConfig { + #[pin] + data: Mutex, +} + +#[pin_data] +struct DeviceConfigInner { + powered: bool, + name: CString, + block_size: u32, + rotational: bool, + capacity_mib: u64, + disk: Option>, +} + +#[vtable] +impl configfs::AttributeOperations<0> for DeviceConfig { + type Data =3D DeviceConfig; + + fn show(this: &DeviceConfig, page: &mut [u8; PAGE_SIZE]) -> Result { + let mut writer =3D kernel::str::BufferWriter::new(page)?; + + if this.data.lock().powered { + writer.write_fmt(fmt!("1\n"))?; + } else { + writer.write_fmt(fmt!("0\n"))?; + } + + Ok(writer.pos()) + } + + fn store(this: &DeviceConfig, page: &[u8]) -> Result { + let power_op: bool =3D core::str::from_utf8(page)? + .trim() + .parse::() + .map_err(|_| kernel::error::code::EINVAL)? + !=3D 0; + + let mut guard =3D this.data.lock(); + + if !guard.powered && power_op { + guard.disk =3D Some(NullBlkDevice::new( + &guard.name, + guard.block_size, + guard.rotational, + guard.capacity_mib, + )?); + guard.powered =3D true; + } else if guard.powered && !power_op { + drop(guard.disk.take()); + guard.powered =3D false; + } + + Ok(()) + } +} + +#[vtable] +impl configfs::AttributeOperations<1> for DeviceConfig { + type Data =3D DeviceConfig; + + fn show(this: &DeviceConfig, page: &mut [u8; PAGE_SIZE]) -> Result { + let mut writer =3D kernel::str::BufferWriter::new(page)?; + writer.write_fmt(fmt!("{}\n", this.data.lock().block_size))?; + Ok(writer.pos()) + } + + fn store(this: &DeviceConfig, page: &[u8]) -> Result { + if this.data.lock().powered { + return Err(EBUSY); + } + + let text =3D core::str::from_utf8(page)?.trim(); + let value =3D text + .parse::() + .map_err(|_| kernel::error::code::EINVAL)?; + + GenDiskBuilder::validate_block_size(value)?; + this.data.lock().block_size =3D value; + Ok(()) + } +} + +#[vtable] +impl configfs::AttributeOperations<2> for DeviceConfig { + type Data =3D DeviceConfig; + + fn show(this: &DeviceConfig, page: &mut [u8; PAGE_SIZE]) -> Result { + let mut writer =3D kernel::str::BufferWriter::new(page)?; + + if this.data.lock().rotational { + writer.write_fmt(fmt!("1\n"))?; + } else { + writer.write_fmt(fmt!("0\n"))?; + } + + Ok(writer.pos()) + } + + fn store(this: &DeviceConfig, page: &[u8]) -> Result { + if this.data.lock().powered { + return Err(EBUSY); + } + + this.data.lock().rotational =3D core::str::from_utf8(page)? + .trim() + .parse::() + .map_err(|_| kernel::error::code::EINVAL)? + !=3D 0; + + Ok(()) + } +} + +#[vtable] +impl configfs::AttributeOperations<3> for DeviceConfig { + type Data =3D DeviceConfig; + + fn show(this: &DeviceConfig, page: &mut [u8; PAGE_SIZE]) -> Result { + let mut writer =3D kernel::str::BufferWriter::new(page)?; + writer.write_fmt(fmt!("{}\n", this.data.lock().capacity_mib))?; + Ok(writer.pos()) + } + + fn store(this: &DeviceConfig, page: &[u8]) -> Result { + if this.data.lock().powered { + return Err(EBUSY); + } + + let text =3D core::str::from_utf8(page)?.trim(); + let value =3D text + .parse::() + .map_err(|_| kernel::error::code::EINVAL)?; + + this.data.lock().capacity_mib =3D value; + Ok(()) + } +} diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index d07e76ae2c13..d09bc77861e4 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -1,28 +1,26 @@ // SPDX-License-Identifier: GPL-2.0 =20 //! This is a Rust implementation of the C null block driver. -//! -//! Supported features: -//! -//! - blk-mq interface -//! - direct completion -//! - block size 4k -//! -//! The driver is not configurable. + +mod configfs; =20 use kernel::{ alloc::flags, - block::mq::{ + block::{ self, - gen_disk::{self, GenDisk}, - Operations, TagSet, + mq::{ + self, + gen_disk::{self, GenDisk}, + Operations, TagSet, + }, }, error::Result, - new_mutex, pr_info, + pr_info, prelude::*, - sync::{Arc, Mutex}, + sync::Arc, types::ARef, }; +use pin_init::PinInit; =20 module! { type: NullBlkModule, @@ -35,33 +33,39 @@ #[pin_data] struct NullBlkModule { #[pin] - _disk: Mutex>, + configfs_subsystem: kernel::configfs::Subsystem, } =20 impl kernel::InPlaceModule for NullBlkModule { fn init(_module: &'static ThisModule) -> impl PinInit { pr_info!("Rust null_blk loaded\n"); =20 - // Use a immediately-called closure as a stable `try` block - let disk =3D /* try */ (|| { - let tagset =3D Arc::pin_init(TagSet::new(1, 256, 1), flags::GF= P_KERNEL)?; - - gen_disk::GenDiskBuilder::new() - .capacity_sectors(4096 << 11) - .logical_block_size(4096)? - .physical_block_size(4096)? - .rotational(false) - .build(format_args!("rnullb{}", 0), tagset) - })(); - try_pin_init!(Self { - _disk <- new_mutex!(disk?, "nullb:disk"), + configfs_subsystem <- configfs::subsystem(), }) } } =20 struct NullBlkDevice; =20 +impl NullBlkDevice { + fn new( + name: &CStr, + block_size: u32, + rotational: bool, + capacity_mib: u64, + ) -> Result> { + let tagset =3D Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KE= RNEL)?; + + gen_disk::GenDiskBuilder::new() + .capacity_sectors(capacity_mib << (20 - block::SECTOR_SHIFT)) + .logical_block_size(block_size)? + .physical_block_size(block_size)? + .rotational(rotational) + .build(fmt!("{}", name.to_str()?), tagset) + } +} + #[vtable] impl Operations for NullBlkDevice { #[inline(always)] diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_di= sk.rs index a04b709514ac..34f13e9b286f 100644 --- a/rust/kernel/block/mq/gen_disk.rs +++ b/rust/kernel/block/mq/gen_disk.rs @@ -46,7 +46,7 @@ pub fn rotational(mut self, rotational: bool) -> Self { =20 /// Validate block size by verifying that it is between 512 and `PAGE_= SIZE`, /// and that it is a power of two. - fn validate_block_size(size: u32) -> Result { + pub fn validate_block_size(size: u32) -> Result { if !(512..=3Dbindings::PAGE_SIZE as u32).contains(&size) || !size.= is_power_of_two() { Err(error::code::EINVAL) } else { --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81DA82E06E0; Mon, 16 Jun 2025 13:26:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080368; cv=none; b=dd5w1l3cPC/yTyEXP2Ok3aHjiBoSIJLUkVY1FHo5w6zUg3HBo2Emao3l2gBUHpfuq4ME51aBKXbfzLyaSHFq3cILEwO010tiBTyM7SR9G4lm8gSOJfZtN9BJSr9gS5oOTkhTYcp5OfcXvjDLv27NeqGTdSSa0umP/Qv2cWN51EY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080368; c=relaxed/simple; bh=T8/c+G4I7okD19pHsxXGgeFmdqX1wHwwrD4rz3eLRLs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jnAYWbz22Vdbga4sHoJQChzkS6K6/jKyKffaD4xJXZsPeW8nrywYJU5S/uMYVk8qHvXUGm97IeExws+38x/wYQLA1Flb0xleqsXfljQWqSjDn166Hir6m8zI/mr3K2rUDwRK56a9vOQ9WeOT8PLap65xVpWyJl5ZcJCfrgHeCbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fzCgmTAv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fzCgmTAv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6A768C4CEEA; Mon, 16 Jun 2025 13:26:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080368; bh=T8/c+G4I7okD19pHsxXGgeFmdqX1wHwwrD4rz3eLRLs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fzCgmTAvUvfmazNAzqavuHKxwrxusVErnU9VPNWRLF2NZjZLuI/XPCJu0fQ8CrVZc lqOU1IsO0W3Y5rp1INJ6dY5t5zVKoHCare1eXxFFcfO8JLd93TD6XmAdo3VQMyzZl0 EtoMiQ7dgqYbPRyh7OeTtiUuzFJcUuhpTK/rA5Xyym1rBKc25Z98JwHyYAsxBdKDre cxxKylRhZ1Cq9ECeqgcdV/LM2wni45JSkg3zkL7KB+yJ36p78wCEJK3i15pZXrIFoT k+yNxEiBHDERBS9SQbI5BqaSDtk4fExi81yHH7kPwY9SMVrTP0u4nfjiQwDTCblza5 ANQp/Nvnm1ewg== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:56 +0200 Subject: [PATCH 6/9] rust: block: add `GenDisk` private data support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-6-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=11078; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=T8/c+G4I7okD19pHsxXGgeFmdqX1wHwwrD4rz3eLRLs=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsPMevUQ9fSJSvpaCqbg5dlBc4Wid+6rI+8V tXp7HA4o9KJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbDwAKCRDhuBo+eShj d5QMD/9zXw7BuhrsSTVdcooa2w65dH67nFxO5SB77LOMTlHKJ6g9017qlv+vNZSWh/ycin6VZJF i+DWcddR7qHeIEZXy14EZlvy9aC31XZ5PbY3x3AdPxMe9OuBaTpvgYrk+UzYjZ3jimoWmeyybrt TpFB9wa3r5YaQiU9D1LPwjWNIaO9RkldtwX/If9AwyXnpBNvKCnlCu0C140H4n+pAudhgJUwZOX gRNw7OVQe2S6IdbdyDdc/eQ5EOfTa/wqgksRjloWkLdIW9UdNdEUJvaRBn0505FDuDiH5daGykU zeGz/lhNsH1zM+CJiAcQgFNmVJ33cfUWoVLoVcF6q5ttu6vuy2CwelH7GYEQJwxPj+WkoZlH2B2 O32wuYhq4zjo5MdYaCIZ/eIC9TjOPHx3JtVSGEeqd+/gc2ZScO7LF+McVHX8vUDPZ52QzBCh0xk 3H4y7wl+/ktEqOjWCH9mgq7fpqg9pnXhv5u2qjnDWJsUpm65Kw1GGu8Icz7cxeGX8RwkChEg2pr dHPGPBvtUgX7BPr2FsklL49bo5MvRzOi7Ku67ulJaypDC4E2wdBgixDiFrXzM64G/0jAe6ekEp/ GI917JEtuEWmXtxP4kMlWP2N4rvg4WEoS7dJnAcNGelPx9mil2FFepqjB0drOH1+jjZZ/Nus4TC UlirWI86ImNXz7g== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Allow users of the rust block device driver API to install private data in the `GenDisk` structure. Signed-off-by: Andreas Hindborg --- drivers/block/rnull/rnull.rs | 8 ++++--- rust/kernel/block/mq.rs | 7 +++--- rust/kernel/block/mq/gen_disk.rs | 46 +++++++++++++++++++++++++++++++---= ---- rust/kernel/block/mq/operations.rs | 46 ++++++++++++++++++++++++++++++----= ---- 4 files changed, 84 insertions(+), 23 deletions(-) diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index d09bc77861e4..a012c59ecb3c 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -62,14 +62,16 @@ fn new( .logical_block_size(block_size)? .physical_block_size(block_size)? .rotational(rotational) - .build(fmt!("{}", name.to_str()?), tagset) + .build(fmt!("{}", name.to_str()?), tagset, ()) } } =20 #[vtable] impl Operations for NullBlkDevice { + type QueueData =3D (); + #[inline(always)] - fn queue_rq(rq: ARef>, _is_last: bool) -> Result { + fn queue_rq(_queue_data: (), rq: ARef>, _is_last: bo= ol) -> Result { mq::Request::end_ok(rq) .map_err(|_e| kernel::error::code::EIO) // We take no refcounts on the request, so we expect to be abl= e to @@ -80,5 +82,5 @@ fn queue_rq(rq: ARef>, _is_last: bool) = -> Result { Ok(()) } =20 - fn commit_rqs() {} + fn commit_rqs(_queue_data: ()) {} } diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs index faa3ccb5a49a..34b7425fa94d 100644 --- a/rust/kernel/block/mq.rs +++ b/rust/kernel/block/mq.rs @@ -69,20 +69,21 @@ //! //! #[vtable] //! impl Operations for MyBlkDevice { +//! type QueueData =3D (); //! -//! fn queue_rq(rq: ARef>, _is_last: bool) -> Result { +//! fn queue_rq(_queue_data: (), rq: ARef>, _is_last: bo= ol) -> Result { //! Request::end_ok(rq); //! Ok(()) //! } //! -//! fn commit_rqs() {} +//! fn commit_rqs(_queue_data: ()) {} //! } //! //! let tagset: Arc> =3D //! Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?; //! let mut disk =3D gen_disk::GenDiskBuilder::new() //! .capacity_sectors(4096) -//! .build(format_args!("myblk"), tagset)?; +//! .build(format_args!("myblk"), tagset, ())?; //! //! # Ok::<(), kernel::error::Error>(()) //! ``` diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_di= sk.rs index 34f13e9b286f..3a0fd9e47049 100644 --- a/rust/kernel/block/mq/gen_disk.rs +++ b/rust/kernel/block/mq/gen_disk.rs @@ -5,11 +5,18 @@ //! C header: [`include/linux/blkdev.h`](srctree/include/linux/blkdev.h) //! C header: [`include/linux/blk_mq.h`](srctree/include/linux/blk_mq.h) =20 -use crate::block::mq::{Operations, TagSet}; -use crate::{bindings, error::from_err_ptr, error::Result, sync::Arc}; -use crate::{error, static_lock_class}; +use crate::{ + bindings, + block::mq::{Operations, TagSet}, + error::Result, + error::{self, from_err_ptr}, + static_lock_class, + str::BufferWriter, + sync::Arc, + types::ForeignOwnable, + types::ScopeGuard, +}; use core::fmt::{self, Write}; -use kernel::str::BufferWriter; =20 /// A builder for [`GenDisk`]. /// @@ -93,7 +100,14 @@ pub fn build( self, name: fmt::Arguments<'_>, tagset: Arc>, + queue_data: T::QueueData, ) -> Result> { + let data =3D queue_data.into_foreign(); + let recover_data =3D ScopeGuard::new(|| { + // SAFETY: T::QueueData was created by the call to `into_forei= gn()` above + unsafe { T::QueueData::from_foreign(data) }; + }); + // SAFETY: `bindings::queue_limits` contain only fields that are v= alid when zeroed. let mut lim: bindings::queue_limits =3D unsafe { core::mem::zeroed= () }; =20 @@ -108,7 +122,7 @@ pub fn build( bindings::__blk_mq_alloc_disk( tagset.raw_tag_set(), &mut lim, - core::ptr::null_mut(), + data.cast(), static_lock_class!().as_ptr(), ) })?; @@ -162,8 +176,12 @@ pub fn build( }, )?; =20 + recover_data.dismiss(); + // INVARIANT: `gendisk` was initialized above. // INVARIANT: `gendisk` was added to the VFS via `device_add_disk`= above. + // INVARIANT: `gendisk.queue.queue_data` is set to `data` in the c= all to + // `__blk_mq_alloc_disk` above. Ok(GenDisk { _tagset: tagset, gendisk, @@ -175,9 +193,10 @@ pub fn build( /// /// # Invariants /// -/// - `gendisk` must always point to an initialized and valid `struct gend= isk`. -/// - `gendisk` was added to the VFS through a call to -/// `bindings::device_add_disk`. +/// - `gendisk` must always point to an initialized and valid `struct gen= disk`. +/// - `gendisk` was added to the VFS through a call to +/// `bindings::device_add_disk`. +/// - `self.gendisk.queue.queuedata` is initialized by a call to `Foreign= Ownable::into_foreign`. pub struct GenDisk { _tagset: Arc>, gendisk: *mut bindings::gendisk, @@ -189,9 +208,20 @@ unsafe impl Send for GenDisk = {} =20 impl Drop for GenDisk { fn drop(&mut self) { + // SAFETY: By type invariant of `Self`, `self.gendisk` points to a= valid + // and initialized instance of `struct gendisk`, and, `queuedata` = was + // initialized with the result of a call to + // `ForeignOwnable::into_foreign`. + let queue_data =3D unsafe { (*(*self.gendisk).queue).queuedata }; + // SAFETY: By type invariant, `self.gendisk` points to a valid and // initialized instance of `struct gendisk`, and it was previously= added // to the VFS. unsafe { bindings::del_gendisk(self.gendisk) }; + + // SAFETY: `queue.queuedata` was created by `GenDiskBuilder::build= ` with + // a call to `ForeignOwnable::into_foreign` to create `queuedata`. + // `ForeignOwnable::from_foreign` is only called here. + let _queue_data =3D unsafe { T::QueueData::from_foreign(queue_data= .cast()) }; } } diff --git a/rust/kernel/block/mq/operations.rs b/rust/kernel/block/mq/oper= ations.rs index 864ff379dc91..c50959d5517b 100644 --- a/rust/kernel/block/mq/operations.rs +++ b/rust/kernel/block/mq/operations.rs @@ -6,14 +6,15 @@ =20 use crate::{ bindings, - block::mq::request::RequestDataWrapper, - block::mq::Request, + block::mq::{request::RequestDataWrapper, Request}, error::{from_result, Result}, prelude::*, - types::ARef, + types::{ARef, ForeignOwnable}, }; use core::{marker::PhantomData, sync::atomic::AtomicU64, sync::atomic::Ord= ering}; =20 +type ForeignBorrowed<'a, T> =3D ::Borrowed<'a>; + /// Implement this trait to interface blk-mq as block devices. /// /// To implement a block device driver, implement this trait as described = in the @@ -26,12 +27,20 @@ /// [module level documentation]: kernel::block::mq #[macros::vtable] pub trait Operations: Sized { + /// Data associated with the `struct request_queue` that is allocated = for + /// the `GenDisk` associated with this `Operations` implementation. + type QueueData: ForeignOwnable; + /// Called by the kernel to queue a request with the driver. If `is_la= st` is /// `false`, the driver is allowed to defer committing the request. - fn queue_rq(rq: ARef>, is_last: bool) -> Result; + fn queue_rq( + queue_data: ForeignBorrowed<'_, Self::QueueData>, + rq: ARef>, + is_last: bool, + ) -> Result; =20 /// Called by the kernel to indicate that queued requests should be su= bmitted. - fn commit_rqs(); + fn commit_rqs(queue_data: ForeignBorrowed<'_, Self::QueueData>); =20 /// Called by the kernel to poll the device for completed requests. On= ly /// used for poll queues. @@ -70,7 +79,7 @@ impl OperationsVTable { /// promise to not access the request until the driver calls /// `bindings::blk_mq_end_request` for the request. unsafe extern "C" fn queue_rq_callback( - _hctx: *mut bindings::blk_mq_hw_ctx, + hctx: *mut bindings::blk_mq_hw_ctx, bd: *const bindings::blk_mq_queue_data, ) -> bindings::blk_status_t { // SAFETY: `bd.rq` is valid as required by the safety requirement = for @@ -88,10 +97,20 @@ impl OperationsVTable { // reference counted by `ARef` until then. let rq =3D unsafe { Request::aref_from_raw((*bd).rq) }; =20 + // SAFETY: `hctx` is valid as required by this function. + let queue_data =3D unsafe { (*(*hctx).queue).queuedata }; + + // SAFETY: `queue.queuedata` was created by `GenDisk::try_new()` w= ith a + // call to `ForeignOwnable::into_pointer()` to create `queuedata`. + // `ForeignOwnable::from_foreign()` is only called when the tagset= is + // dropped, which happens after we are dropped. + let queue_data =3D unsafe { T::QueueData::borrow(queue_data.cast()= ) }; + // SAFETY: We have exclusive access and we just set the refcount a= bove. unsafe { Request::start_unchecked(&rq) }; =20 let ret =3D T::queue_rq( + queue_data, rq, // SAFETY: `bd` is valid as required by the safety requirement= for // this function. @@ -110,9 +129,18 @@ impl OperationsVTable { /// /// # Safety /// - /// This function may only be called by blk-mq C infrastructure. - unsafe extern "C" fn commit_rqs_callback(_hctx: *mut bindings::blk_mq_= hw_ctx) { - T::commit_rqs() + /// This function may only be called by blk-mq C infrastructure. The c= aller + /// must ensure that `hctx` is valid. + unsafe extern "C" fn commit_rqs_callback(hctx: *mut bindings::blk_mq_h= w_ctx) { + // SAFETY: `hctx` is valid as required by this function. + let queue_data =3D unsafe { (*(*hctx).queue).queuedata }; + + // SAFETY: `queue.queuedata` was created by `GenDisk::try_new()` w= ith a + // call to `ForeignOwnable::into_pointer()` to create `queuedata`. + // `ForeignOwnable::from_foreign()` is only called when the tagset= is + // dropped, which happens after we are dropped. + let queue_data =3D unsafe { T::QueueData::borrow(queue_data.cast()= ) }; + T::commit_rqs(queue_data) } =20 /// This function is called by the C kernel. It is not currently --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DFF82EB5DE; Mon, 16 Jun 2025 13:26:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080374; cv=none; b=t1bUbmz3lAC4lJha9o9IBMm5V6ZlLWI73oqUhcIN0ngDPZLOfUJFmLAvMSHY0aUOn4REjWQViXn32CjFnxWHRUr2c4P6ip9LPQrHqcm4dPN0ds7vEVuOYxSVwXHIdNE7FOyegFEC2eKfqa94fJWUdJn+s8xQDBC32fHAmEhIV90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080374; c=relaxed/simple; bh=bwWpprsdtyVDZaqvZNUcUvzzn3+xorlxFgD0pWYxMCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EO7FIHeZ0oSditHQIPSYig7PMXLBwTgvqIcFI5Pf/fofGewtoFMfVs51aVIW8UQsA54KnCHIiSkmhqk1ix2e66jH3w9hT2pPh7rb2VBPFKR8kGdN0a+rFVkyLNijw2asrAn2qBovgZWXTOYlXJBLxrRnHi1Dclws2RHXCxepI4g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pTTvqaIU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pTTvqaIU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9C40C4CEEA; Mon, 16 Jun 2025 13:26:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080374; bh=bwWpprsdtyVDZaqvZNUcUvzzn3+xorlxFgD0pWYxMCs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pTTvqaIUEltj8qffyldX2659oMwz4aC/e+FAUrrGYXhQBu3W24cy3wWDEoxDrfygo 3S5ufwV1DfNPyHNQc72gVFPKPamrMvJyXUOMTdbk1KVE8BmMDzi68Jj9X10D+IFyqL fGGcwRQ1xRrm4hGJ3osttgsXBN+haxVF52etF6MM2tdjj3VQIGEcphPXTwj/DuMFmn F6YKaFgCMDyUd59y4xwzbtfjxJ89KYeWMuoqvoRAl409BxbWZe2pqCwH4rALqYziTw Dz3Wt3SFwuQtC+Flc1CF8TXfMp3fkaPnyZDvg5trJJHLLGHP5ZO+Waw1LueBH3a04e 93al9WTGYTkIg== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:57 +0200 Subject: [PATCH 7/9] rust: block: mq: fix spelling in a safety comment Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-7-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=928; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=bwWpprsdtyVDZaqvZNUcUvzzn3+xorlxFgD0pWYxMCs=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsQXws+UPKZShYY9vASY1mUc3xhyzyNEbvbA T9OLCDLHn+JAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbEAAKCRDhuBo+eShj d/PsD/0d7qzRrBSkG3peQMf4MxIYe3XYl0Dv7nzpFhDh8GR12/CmFro7MqYaya8J6iN8NNe2biO dK3Ol1oWWLo3vBtmd57yEB3KHPTaJ5Bk3ArENQm2qscBxWj8KP32v5cW2VnvkI8q6s2bAjEo0VR LsySldkSK56rXEMMlDv06wSDgX6D9uLDT3b6oK5Gp3xktUm8XV70ePA0Ymr1q0dilBKpv181EZf nvr2ZReapyIQ8liiZzzL9n1Vg2fG+AU0WZxnR6uAtau6IGz+vcMVsjfyp03zVzWvTyfxyDCdMZn y6oh6R7fuGDYqavcCimOR0j3WgiJOHRJ+xt3uaPmIYjIrK5K2qWycrwC7/BQQoOxJocUWmIKrnp cPOEDqA3F6dN6c3wCEqo2ixy6mYktznukaIpfLT0YrzqQXwHptSVTWC0hTTiHWsvw67dFPWEHXf phi7HUDJRp6ymBq6ZlrGf+TQZVZ/oB2Vdg9UILKAFl0t1KpYlQHzkTFnVWo5bjd7X2VRbl/Aj45 MOtyP/9XjA4+PcQJAqMQaEbKmOK1Q/db+OSN1FKzSa28OT4A+iOsizkT8VD4nK9IdCCavPIS/O0 Mxy4m1VHd8qEeBZ96kUfPyI57OG0p49hXFs0gPl+EUUqBfDfIxmBxTmm9hjHy0WBd5TKo/r8wSQ DRezl1onw/coKlw== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Add code block quotes to a safety comment. Signed-off-by: Andreas Hindborg --- rust/kernel/block/mq/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request= .rs index 2d14a6261a31..873d00db74dd 100644 --- a/rust/kernel/block/mq/request.rs +++ b/rust/kernel/block/mq/request.rs @@ -143,7 +143,7 @@ pub(crate) unsafe fn wrapper_ptr(this: *mut Self) -> No= nNull // valid allocation. let wrapper_ptr =3D unsafe { bindings::blk_mq_rq_to_pdu(request_ptr).cast::() }; - // SAFETY: By C API contract, wrapper_ptr points to a valid alloca= tion + // SAFETY: By C API contract, `wrapper_ptr` points to a valid allo= cation // and is not null. unsafe { NonNull::new_unchecked(wrapper_ptr) } } --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2272C2F2C4C; Mon, 16 Jun 2025 13:26:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080381; cv=none; b=gRpac6iSiPeB1TSDByTJo1kMnEJZmmropWL5RLpTNNBdfL6Jn1YMcAGLWxL/5K9Z6j8G59r4Mlg+Q71z7AGdldHCC0rT0wX48Wu+3DOEric19WQNzryQuH7XfWE842FEAp8Pyg4rVAgdduuwkfHpKqhabS+4UoKd3Zvz0KUVSk4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080381; c=relaxed/simple; bh=LSx1ItJzMBA57/EBhXrxJqKwSb/byhu1bF1rbuvWUgY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dS1klL7TjdGZSD3zGduD9bOrhqwy8p4oq0H/Bwn+HnwvZQlcYcQ+QLUKRZpcTDYpVt8x5LBW3XslbJ8TzE+3CxUevYi/ycrwzSrPFjSebwRtGlWAWr0L45ricpBBBvLhvACcGfx1vB8ktfbDD0xc3fN9fVRGCOY20oaMTR4GUN4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qTHFzI/T; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qTHFzI/T" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 287E7C4CEF4; Mon, 16 Jun 2025 13:26:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080380; bh=LSx1ItJzMBA57/EBhXrxJqKwSb/byhu1bF1rbuvWUgY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qTHFzI/T7RhcHzlWmWx4c1+3wSc0uDhggiRFZeC41taIiraaPS0iIG6tSFDsucqKH kwOd7u3+XUEtV5ct9U8BO65xt3EozATsEQj5gFdQlPuyyM6CsdnWTeIIEkGwZ8GJVO J1l8ufL54FCE4JU10e2IJ5bCkLGfo4fmsrZ3T8J4n3qHtsu1zS8eFYF37ofuE0SASU ndgBTMvYVRozH+6m1S/4WyfVPjQn4wArvGajJEDlI7UnFnwXm6SL/Ap26Pg8bYx1Dk RmkwehxKs+52eFc5GvLQBZ4NsQnMp4Q3l2a9k/a5QujsDPQXpMozJielPahSaepIZb Q2jgvVCzu4Qcw== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:58 +0200 Subject: [PATCH 8/9] rust: block: add remote completion to `Request` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-8-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=4988; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=LSx1ItJzMBA57/EBhXrxJqKwSb/byhu1bF1rbuvWUgY=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsR/d5gaFcHFDlfh7B9XFwQr1F1YFEYchXmx CtkWTO5JpWJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbEQAKCRDhuBo+eShj d6RgD/40R+zDCrUV9n2zTAAh1R61/NdHRWuZs/dYUE9nBCwpfjfBDIf48u9Fhb0ama//rbKw5RY QaGM/odfgvHWWdrhc6jEegbEs29SR41EiyNkMkNYDHupFCECl/8qL3T+vl91mPlJk/XQ1yE56NV BzVHM+D21yLV6lLO5Z0a1Elo5E/8XBJtYwDpK8MGnXNH2nMVLKuSSM2JneEUNsmHrt5ohcF/Biv 7HD1CYpfbskEH48URIksdX+LKjJ/GvSmRar5wiGLy4Pv/rpl77r/kpCpwvoda0JrJLUrdul6cyQ R97m+KZkdAlx//clMw4XDfxoeIn/WnMXgCrmqc0G3bD1fEPe2djS9j4Z3DXlFN2gneWvo4vTKCW avFeglpTcMYKuZhkYygaHjcd5PBTLzxCgEKt088hDzNUl58FEdrBiIIn7cmmC30rcbsMnnnvyhB OWp8Fzsmk4FhJLk3N/dmJ0TaLJNSZSG3SWQ27YgePVaI1rgSPI4h+VAHTo/QVoC5mp1yyWhOpFQ X+n4hFEHprFoq0aCZeisGedYqR/j78/+rFRYZMQq4y+z6xEAEJT8IgZSwfCCMoU5a/UGpBH9isS L7wBT3o9mpomuK/Gc6AU7ZcywyXiHQd+uqBa0zQrCdtlJwlgrC0YWeXUfK2rII5ZfY2nLfy7QVt lD/9yJGXTEvwh/Q== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 Allow users of rust block device driver API to schedule completion of requests via `blk_mq_complete_request_remote`. Signed-off-by: Andreas Hindborg --- drivers/block/rnull/rnull.rs | 9 +++++++++ rust/kernel/block/mq.rs | 6 ++++++ rust/kernel/block/mq/operations.rs | 19 +++++++++++++++---- rust/kernel/block/mq/request.rs | 17 +++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index a012c59ecb3c..371786be7f47 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -83,4 +83,13 @@ fn queue_rq(_queue_data: (), rq: ARef>= , _is_last: bool) -> Res } =20 fn commit_rqs(_queue_data: ()) {} + + fn complete(rq: ARef>) { + mq::Request::end_ok(rq) + .map_err(|_e| kernel::error::code::EIO) + // We take no refcounts on the request, so we expect to be abl= e to + // end the request. The request reference must be unique at th= is + // point, and so `end_ok` cannot fail. + .expect("Fatal error - expected to be able to end request"); + } } diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs index 34b7425fa94d..551ef38efea2 100644 --- a/rust/kernel/block/mq.rs +++ b/rust/kernel/block/mq.rs @@ -77,6 +77,12 @@ //! } //! //! fn commit_rqs(_queue_data: ()) {} +//! +//! fn complete(rq: ARef>) { +//! Request::end_ok(rq) +//! .map_err(|_e| kernel::error::code::EIO) +//! .expect("Fatal error - expected to be able to end request"= ); +//! } //! } //! //! let tagset: Arc> =3D diff --git a/rust/kernel/block/mq/operations.rs b/rust/kernel/block/mq/oper= ations.rs index c50959d5517b..b6b26cebd4f5 100644 --- a/rust/kernel/block/mq/operations.rs +++ b/rust/kernel/block/mq/operations.rs @@ -42,6 +42,9 @@ fn queue_rq( /// Called by the kernel to indicate that queued requests should be su= bmitted. fn commit_rqs(queue_data: ForeignBorrowed<'_, Self::QueueData>); =20 + /// Called by the kernel when the request is completed. + fn complete(rq: ARef>); + /// Called by the kernel to poll the device for completed requests. On= ly /// used for poll queues. fn poll() -> bool { @@ -143,13 +146,21 @@ impl OperationsVTable { T::commit_rqs(queue_data) } =20 - /// This function is called by the C kernel. It is not currently - /// implemented, and there is no way to exercise this code path. + /// This function is called by the C kernel. A pointer to this functio= n is + /// installed in the `blk_mq_ops` vtable for the driver. /// /// # Safety /// - /// This function may only be called by blk-mq C infrastructure. - unsafe extern "C" fn complete_callback(_rq: *mut bindings::request) {} + /// This function may only be called by blk-mq C infrastructure. `rq` = must + /// point to a valid request that has been marked as completed. The po= intee + /// of `rq` must be valid for write for the duration of this function. + unsafe extern "C" fn complete_callback(rq: *mut bindings::request) { + // SAFETY: This function can only be dispatched through + // `Request::complete`. We leaked a refcount then which we pick ba= ck up + // now. + let aref =3D unsafe { Request::aref_from_raw(rq) }; + T::complete(aref); + } =20 /// This function is called by the C kernel. A pointer to this functio= n is /// installed in the `blk_mq_ops` vtable for the driver. diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request= .rs index 873d00db74dd..244578a802ce 100644 --- a/rust/kernel/block/mq/request.rs +++ b/rust/kernel/block/mq/request.rs @@ -130,6 +130,23 @@ pub fn end_ok(this: ARef) -> Result<(), ARef> { Ok(()) } =20 + /// Complete the request by scheduling `Operations::complete` for + /// execution. + /// + /// The function may be scheduled locally, via SoftIRQ or remotely via= IPMI. + /// See `blk_mq_complete_request_remote` in [`blk-mq.c`] for details. + /// + /// [`blk-mq.c`]: srctree/block/blk-mq.c + pub fn complete(this: ARef) { + let ptr =3D ARef::into_raw(this).cast::().as_pt= r(); + // SAFETY: By type invariant, `self.0` is a valid `struct request` + if !unsafe { bindings::blk_mq_complete_request_remote(ptr) } { + // SAFETY: We released a refcount above that we can reclaim he= re. + let this =3D unsafe { Request::aref_from_raw(ptr) }; + T::complete(this); + } + } + /// Return a pointer to the [`RequestDataWrapper`] stored in the priva= te area /// of the request structure. /// --=20 2.47.2 From nobody Thu Oct 9 20:21:56 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C86912BEC28; Mon, 16 Jun 2025 13:26:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080371; cv=none; b=Gq3bsbkiSiuH/3qxU4OnjsZd/a58CfC+xNR9KuZLd3zY6g9gKQTrZEi7FYIRJqlJUKgSwcborR3yjLfJHR24IWubbXqJKofeiIwH31Ao3Dzr35fdqfujaO6rIDdb79gy1GXDp907ZRItFT4Q5XJCSl60EzE1Z3WS7pZ46vxpXWE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750080371; c=relaxed/simple; bh=dTgPoZkqeSzmhbD3zTW4tZnvROkf83BsbNxNte8KtQY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QsXGzvDZ3YvTRkG7bZchluK34G9jUFJGV8DvFItYL2AsGIEuBjlpDv+3IPl7yd2RkM9jVCewAHkNfSlPtp5Oe062rP6RFCA539N228UaLUXOsm8Jd+AvM7bX8x6zVry4/knAAwUUBV6KVI7X1ai4Bhe1uzbg4/nKL1E7Kqi3MC8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dzKNAZC1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dzKNAZC1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2CCBC4CEED; Mon, 16 Jun 2025 13:26:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1750080371; bh=dTgPoZkqeSzmhbD3zTW4tZnvROkf83BsbNxNte8KtQY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dzKNAZC1WUu7nMBXuaTAdUXCJbgiueXDJxcSE8So0CStqYmwkZHIm1+q2PT/d42ti oTj2ApTOrJoCM07/22V5gm6CCPtux2jwf/C1vdsBn7bSm9j++NmUhGfyyfU/BzkRLB FlrFkawngZxP3eCWT/JhNd+OB6GkWSUuIWZ0W3XCtJl4rk3QhDtLSy14BQZEWzd2q0 uZObPOCO05PTwjMKa9SMjIoIqh2Kz3lysJVuUTLfTSQfLXGJ6FQ9jhmZY6P/uDE5lP LI4uSg/3+fyjEsg20W+HdSkD5y5x42+XQcMp5zgxAlLwy230cyaBARMS4xQTEfVR4Q eN3oi8KFDSSQg== From: Andreas Hindborg Date: Mon, 16 Jun 2025 15:23:59 +0200 Subject: [PATCH 9/9] rnull: add soft-irq completion support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250616-rnull-up-v6-16-v1-9-a4168b8e76b2@kernel.org> References: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> In-Reply-To: <20250616-rnull-up-v6-16-v1-0-a4168b8e76b2@kernel.org> To: Boqun Feng , Miguel Ojeda , Alex Gaynor , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Jens Axboe Cc: linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Hindborg X-Mailer: b4 0.15-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=6402; i=a.hindborg@kernel.org; h=from:subject:message-id; bh=dTgPoZkqeSzmhbD3zTW4tZnvROkf83BsbNxNte8KtQY=; b=owEBbQKS/ZANAwAIAeG4Gj55KGN3AcsmYgBoUBsSCoREy8jtImQsfJflLYzF1UigDvdHuVQvc OO+1YxFgHOJAjMEAAEIAB0WIQQSwflHVr98KhXWwBLhuBo+eShjdwUCaFAbEgAKCRDhuBo+eShj d553D/9VZbWPqk35VqeRAhcq89xfE5xu3K9b9AjTrVoNE1fBO9oBHdbAh+Cb8PdIoNxuWvKfrrN gkDxguSh+v8JnMpAvY6vxNRYrgEA6hrbLVOszYfmm8D4jl5OXcP4RzD1IVOicMFklmvljcEXUb/ MHdNviq87DdtIVe4opK/5+Q6NGSkv4duWGl/Uw/GeUmEv4koc/h7EIpmyvALz/z/n0oQbZz7khh zbcM5dhjxFFCwC/LrhxrKia7B7SH/+acrD1ivg1405jYQ0WQJXTN788uPbK/cuCODkCqkkEC4FE sRMtK4XnuZ6Z6QW5RFmf94hfRZ+qK5QXxjrZEeAjmLEhj8MUcQxLIy17pY4ghH32EW2CLbdMbKu kESQ5KNEC66RVLlYkKty3XBovTunX9vm8a1Qbs8ioFp6wczo2zpjkS/1tHJ0W/uM0B6xVW6bdfv m5xiokinovACYIBi2nKuxenfOn8pBzr/TOcZvNPy+rL/WY9EH2tjTlRLGGKlcWkNZ2pLo5IM9Du WSfio26g0EdhgoYxsauQOZE3YYpe+XAw6qTFfpJdw3R1Lpchghwbdjm8dwsQzrGUBb3LxOg32NH 5Cx+OzEzKubcn752kAUnXIYgX/EyEIiTmJDixb2OZIreRVCZlFgi2upAxx/0Ffvq/9bv9KtBMJz P8nBprzZG9+DD9A== X-Developer-Key: i=a.hindborg@kernel.org; a=openpgp; fpr=3108C10F46872E248D1FB221376EB100563EF7A7 rnull currently only supports direct completion. Add option for completing requests across CPU nodes via soft IRQ or IPMI. Signed-off-by: Andreas Hindborg --- drivers/block/rnull/configfs.rs | 61 +++++++++++++++++++++++++++++++++++++= ++-- drivers/block/rnull/rnull.rs | 32 +++++++++++++-------- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs= .rs index 315e04fbf14f..22a7ec26cb36 100644 --- a/drivers/block/rnull/configfs.rs +++ b/drivers/block/rnull/configfs.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 =20 use super::{NullBlkDevice, THIS_MODULE}; -use core::fmt::Write; +use core::fmt::{Display, Write}; use kernel::{ block::mq::gen_disk::{GenDisk, GenDiskBuilder}, c_str, @@ -36,7 +36,7 @@ impl AttributeOperations<0> for Config { =20 fn show(_this: &Config, page: &mut [u8; PAGE_SIZE]) -> Result { let mut writer =3D kernel::str::BufferWriter::new(page)?; - writer.write_str("blocksize,size,rotational\n")?; + writer.write_str("blocksize,size,rotational,irqmode\n")?; Ok(writer.pos()) } } @@ -58,6 +58,7 @@ fn make_group( blocksize: 1, rotational: 2, size: 3, + irqmode: 4, ], }; =20 @@ -72,6 +73,7 @@ fn make_group( rotational: false, disk: None, capacity_mib: 4096, + irq_mode: IRQMode::None, name: name.try_into()?, }), }), @@ -79,6 +81,34 @@ fn make_group( } } =20 +#[derive(Debug, Clone, Copy)] +pub(crate) enum IRQMode { + None, + Soft, +} + +impl TryFrom for IRQMode { + type Error =3D kernel::error::Error; + + fn try_from(value: u8) -> Result { + match value { + 0 =3D> Ok(Self::None), + 1 =3D> Ok(Self::Soft), + _ =3D> Err(kernel::error::code::EINVAL), + } + } +} + +impl Display for IRQMode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::None =3D> f.write_str("0")?, + Self::Soft =3D> f.write_str("1")?, + } + Ok(()) + } +} + #[pin_data] pub(crate) struct DeviceConfig { #[pin] @@ -92,6 +122,7 @@ struct DeviceConfigInner { block_size: u32, rotational: bool, capacity_mib: u64, + irq_mode: IRQMode, disk: Option>, } =20 @@ -126,6 +157,7 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result { guard.block_size, guard.rotational, guard.capacity_mib, + guard.irq_mode, )?); guard.powered =3D true; } else if guard.powered && !power_op { @@ -218,3 +250,28 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result { Ok(()) } } + +#[vtable] +impl configfs::AttributeOperations<4> for DeviceConfig { + type Data =3D DeviceConfig; + + fn show(this: &DeviceConfig, page: &mut [u8; PAGE_SIZE]) -> Result { + let mut writer =3D kernel::str::BufferWriter::new(page)?; + writer.write_fmt(fmt!("{}\n", this.data.lock().irq_mode))?; + Ok(writer.pos()) + } + + fn store(this: &DeviceConfig, page: &[u8]) -> Result { + if this.data.lock().powered { + return Err(EBUSY); + } + + let text =3D core::str::from_utf8(page)?.trim(); + let value =3D text + .parse::() + .map_err(|_| kernel::error::code::EINVAL)?; + + this.data.lock().irq_mode =3D IRQMode::try_from(value)?; + Ok(()) + } +} diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index 371786be7f47..85b1509a3106 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -4,6 +4,7 @@ =20 mod configfs; =20 +use configfs::IRQMode; use kernel::{ alloc::flags, block::{ @@ -54,35 +55,44 @@ fn new( block_size: u32, rotational: bool, capacity_mib: u64, + irq_mode: IRQMode, ) -> Result> { let tagset =3D Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KE= RNEL)?; =20 + let queue_data =3D Box::new(QueueData { irq_mode }, flags::GFP_KER= NEL)?; + gen_disk::GenDiskBuilder::new() .capacity_sectors(capacity_mib << (20 - block::SECTOR_SHIFT)) .logical_block_size(block_size)? .physical_block_size(block_size)? .rotational(rotational) - .build(fmt!("{}", name.to_str()?), tagset, ()) + .build(fmt!("{}", name.to_str()?), tagset, queue_data) } } =20 +struct QueueData { + irq_mode: IRQMode, +} + #[vtable] impl Operations for NullBlkDevice { - type QueueData =3D (); + type QueueData =3D KBox; =20 #[inline(always)] - fn queue_rq(_queue_data: (), rq: ARef>, _is_last: bo= ol) -> Result { - mq::Request::end_ok(rq) - .map_err(|_e| kernel::error::code::EIO) - // We take no refcounts on the request, so we expect to be abl= e to - // end the request. The request reference must be unique at th= is - // point, and so `end_ok` cannot fail. - .expect("Fatal error - expected to be able to end request"); - + fn queue_rq(queue_data: &QueueData, rq: ARef>, _is_l= ast: bool) -> Result { + match queue_data.irq_mode { + IRQMode::None =3D> mq::Request::end_ok(rq) + .map_err(|_e| kernel::error::code::EIO) + // We take no refcounts on the request, so we expect to be= able to + // end the request. The request reference must be unique a= t this + // point, and so `end_ok` cannot fail. + .expect("Fatal error - expected to be able to end request"= ), + IRQMode::Soft =3D> mq::Request::complete(rq), + } Ok(()) } =20 - fn commit_rqs(_queue_data: ()) {} + fn commit_rqs(_queue_data: &QueueData) {} =20 fn complete(rq: ARef>) { mq::Request::end_ok(rq) --=20 2.47.2