From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CE3F3E0220 for ; Wed, 5 Aug 2026 19:20:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.169 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785957655; cv=none; b=uefjJFMqs2hIlmyDozwCmYZTMFS2ilapGD4Oq7yVjjCKj+9pnSrSHKGu8sDNSBplYbGnOuxbvub9aJagS6d3Xu4VoumhxeEjg2mf33Tmcwnh+LV6TvCWoJKL8YOEX3CYptBV31aLeFwsmfqkbMSqjjbcmiMFBMFlShCnrHuezp0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785957655; c=relaxed/simple; bh=M7+Xp5G3tZjyNJEGVQVB6k60p7Qw9FijqopxCE9sFOc=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=DtmMBBTLIjz6m7mRjIJyInRV2ZbX8GtZNUwfOYisnjKKpBvixIxEJditpAxm719DfcfCjfeWVpHAg5UaAWkTwOLUBFl/T9GLekFZqPqeQpcCmSL6LTve8xpm/rxXS9BwaV/jORMNI6yma5AfzcVPWT6TYoR3Bbnz2lW0NdLQfhM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qc/cEU7w; arc=none smtp.client-ip=209.85.214.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qc/cEU7w" Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-2cf452def93so1706805ad.1 for ; Wed, 05 Aug 2026 12:20:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785957648; x=1786562448; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=CJyM/9okkHYCeVF069aAYJMZJUD0kZWBXu8tJw0Mi1w=; b=qc/cEU7w42YEzgIaid8rWB0Bp+RokkA+FLzQ3J8+fxw+cSoTJtfNvWX//c4oz7yLuS l0Wm8Y/lKv22jbb3seFhvEe2tmRLUvzmV1HOcTdA8TgVZEU5JBwJx4FOvUJFlaaIwyv0 gaSD5QP+BRGdqDeVooIcdtvx2cxvrUBtJSu7CfPMzwBZcqZrLFTOy0bv2lYX3nfLbv0t jHwsS9INh/RHTy8uYbqyGItjS26pT+xGxzuVdfK4htD0Iesds2+0UThgETEaZiYn9BNM VzdixjRJ3rXF1zBBgSaozGtwx3RVDu4P2syxtb6GfrMh0RnwH1arAxP+i7AZG10rYO8P CcRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785957648; x=1786562448; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=CJyM/9okkHYCeVF069aAYJMZJUD0kZWBXu8tJw0Mi1w=; b=JXSK8T2u2m3tTH2SOfYbWJw9BL65AFSy0xiwXTXhnMh1cppPPOTjnkJLmqg6vNxGLm zmSXUqmkDVNZiNn1LpfXUJJqDIc14j2gCzh4dcS064vH2Q9kTjXKWxplGx1zIm1++Vgv 9n3QoHgCuXVPHmBNDtRuPq59gWaHhcBH+1903yknMzVOfc5oMv9pjrFzDBfAItWCkb/5 qVkzDIa7u9bgSIwwzPWdF7elww8AIf8AngR6OPsmhGqmaVe9jHcAOXpfGxvGLaWv6ipl eLIcQ9yAeZl7K2Le3sqxacq28btA+Gm1eoTszknhwZZDNCL80d6XwCigt9sykTm/b/Aw 46hw== X-Forwarded-Encrypted: i=1; AHgh+RolBlT/UwGCWwtjmrcVGMZyoaIx+zsXwB8+ecG4UJgqdvqqKUKKrydvR74ZqYeBmC4+t7zLAOdoR4366W4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/ECGaKA8yMp9GkotSbwWm5AOi5Hxf8Kqs8vpyp21zg6+8e/NM XWzZYF1LP4Htsrb0g10Hk2vNCVN4B0ACQ8gm3rqQbWz7sQBTV7cxm9dc X-Gm-Gg: AR+sD10inwRziXwYOlaHZDi+2/PUnWZDKyQjlH9fe0AKI/gUWUTNOXUpj9jnkQ5JuBc 4qUxj5873KTtCtMUtEOv+BmMHnvV6UYWLhNMXNdbTpHmwwEJaDqU3WEX/UqJ+mZyd4sZO8O5R42 jv5H1qYuNEq1p8iYppQIlrANTxANCTJTkShS1Ru6fGmQ6/u6L1QJp1iDSU61EhnnRIVA25PZ3Kx nRX3t6vshPMu3sk8mOuOPN0r3FDsyc6Pjyn0SU+k+PQlIGXCoyJSynOruPJUP31jn+PcuK4O34d 6RDsEDhlnUDaJLiPloEMsn7i4qdGJaMwWgFHR/yUCM3NCYF8Waw6L58gjOs9bcW5uSh+3mcZ6ha uXrhFEOdduZ3MZqwbY+e2onU00rSV+oHxiVGqSHsw5ngEFJhfxPkLtGxK93yFwqBqO489rCro8p boTqzCn3uqXwAPIoqQas/Hb1udgoXD0t6m3Rf/H9TwV6T0sK1ObKFC5ddOz+wEYVw= X-Received: by 2002:a17:902:da87:b0:2d0:401c:2edc with SMTP id d9443c01a7336-2d0f185d642mr11951815ad.1.1785957648176; Wed, 05 Aug 2026 12:20:48 -0700 (PDT) Received: from archlinux ([2402:e280:411b:ec:aa93:b1ec:5a6b:5fce]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315863b76cfsm18043913eec.4.2026.08.05.12.20.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Aug 2026 12:20:47 -0700 (PDT) From: Adarsh Das To: Andreas Hindborg Cc: Boqun Feng , Jens Axboe , Miguel Ojeda , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?UTF-8?q?Onur=20=C3=96zkan?= , linux-block@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Adarsh Das Subject: [PATCH] rust: block: set GenDisk block_device_operations.owner to THIS_MODULE Date: Thu, 6 Aug 2026 00:50:20 +0530 Message-ID: <20260805192020.107601-1-adarshdas950@gmail.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit GenDiskBuilder currently installs block_device_operations with owner set to NULL. The block layer uses this field to pin the driver module while block device file operations are in use. Take the driver's ThisModule in GenDiskBuilder::build() and store the operations table in GenDisk so gendisk->fops stays valid if the disk is moved, such as when rnull keeps it in an Option behind configfs. Update rnull as the in-tree caller. Signed-off-by: Adarsh Das --- drivers/block/rnull/configfs.rs | 1 + drivers/block/rnull/rnull.rs | 3 +- rust/kernel/block/mq.rs | 9 +++-- rust/kernel/block/mq/gen_disk.rs | 58 +++++++++++++++++++------------- 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs index 7c2eb5c0b722..bba30d590f68 100644 --- a/drivers/block/rnull/configfs.rs +++ b/drivers/block/rnull/configfs.rs @@ -147,6 +147,7 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result { if !guard.powered && power_op { guard.disk = Some(NullBlkDevice::new( + &THIS_MODULE, &guard.name, guard.block_size, guard.rotational, diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs index 0ca8715febe8..4265a133cbf0 100644 --- a/drivers/block/rnull/rnull.rs +++ b/drivers/block/rnull/rnull.rs @@ -46,6 +46,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit { impl NullBlkDevice { fn new( + this_module: &'static ThisModule, name: &CStr, block_size: u32, rotational: bool, @@ -61,7 +62,7 @@ fn new( .logical_block_size(block_size)? .physical_block_size(block_size)? .rotational(rotational) - .build(fmt!("{}", name.to_str()?), tagset, queue_data) + .build(this_module, fmt!("{}", name.to_str()?), tagset, queue_data) } } diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs index 1fd0d54dd549..33561e0f67af 100644 --- a/rust/kernel/block/mq.rs +++ b/rust/kernel/block/mq.rs @@ -8,8 +8,8 @@ //! - Implement [`Operations`] for a type `T`. //! - Create a [`TagSet`]. //! - Create a [`GenDisk`], via the [`GenDiskBuilder`]. -//! - Add the disk to the system by calling [`GenDiskBuilder::build`] passing in -//! the `TagSet` reference. +//! - Add the disk to the system by calling [`GenDiskBuilder::build`], passing in +//! the driver's [`ThisModule`], the disk name, the `TagSet`, and queue data. //! //! The types available in this module that have direct C counterparts are: //! @@ -86,9 +86,12 @@ //! //! let tagset: Arc> = //! Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?; +//! # // SAFETY: Dummy `ThisModule` for doctest compilation only. +//! # static THIS_MODULE: ThisModule = +//! # unsafe { ThisModule::from_ptr(core::ptr::null_mut()) }; //! let mut disk = gen_disk::GenDiskBuilder::new() //! .capacity_sectors(4096) -//! .build(fmt!("myblk"), tagset, ())?; +//! .build(&THIS_MODULE, fmt!("myblk"), tagset, ())?; //! //! # Ok::<(), kernel::error::Error>(()) //! ``` diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_disk.rs index fc97dd873974..ff079223d31a 100644 --- a/rust/kernel/block/mq/gen_disk.rs +++ b/rust/kernel/block/mq/gen_disk.rs @@ -95,8 +95,12 @@ pub fn capacity_sectors(mut self, capacity: u64) -> Self { } /// Build a new `GenDisk` and add it to the VFS. + /// + /// `this_module` must be the [`ThisModule`] for the kernel module registering + /// the disk. pub fn build( self, + this_module: &'static ThisModule, name: fmt::Arguments<'_>, tagset: Arc>, queue_data: T::QueueData, @@ -125,30 +129,32 @@ pub fn build( ) })?; - const TABLE: bindings::block_device_operations = bindings::block_device_operations { - submit_bio: None, - open: None, - release: None, - ioctl: None, - compat_ioctl: None, - check_events: None, - unlock_native_capacity: None, - getgeo: None, - set_read_only: None, - swap_slot_free_notify: None, - report_zones: None, - devnode: None, - alternative_gpt_sector: None, - get_unique_id: None, - // TODO: Set to `THIS_MODULE`. - owner: core::ptr::null_mut(), - pr_ops: core::ptr::null_mut(), - free_disk: None, - poll_bio: None, - }; - - // SAFETY: `gendisk` is a valid pointer as we initialized it above - unsafe { (*gendisk).fops = &TABLE }; + let fops = KBox::new( + bindings::block_device_operations { + submit_bio: None, + open: None, + release: None, + ioctl: None, + compat_ioctl: None, + check_events: None, + unlock_native_capacity: None, + getgeo: None, + set_read_only: None, + swap_slot_free_notify: None, + report_zones: None, + devnode: None, + alternative_gpt_sector: None, + get_unique_id: None, + owner: this_module.as_ptr(), + pr_ops: core::ptr::null_mut(), + free_disk: None, + poll_bio: None, + }, + GFP_KERNEL, + )?; + + // SAFETY: `gendisk` is a valid pointer as we initialized it above. + unsafe { (*gendisk).fops = core::ptr::from_ref(&*fops) }; let cleanup_failure = ScopeGuard::new_with_data((gendisk, data), |(gendisk, data)| { // SAFETY: `gendisk` came from `__blk_mq_alloc_disk()` above and @@ -193,6 +199,7 @@ pub fn build( // `__blk_mq_alloc_disk` above. Ok(GenDisk { _tagset: tagset, + _fops: fops, gendisk, }) } @@ -206,8 +213,11 @@ pub fn build( /// - `gendisk` was added to the VFS through a call to /// `bindings::device_add_disk`. /// - `self.gendisk.queue.queuedata` is initialized by a call to `ForeignOwnable::into_foreign`. +/// - `self._fops` stores the [`bindings::block_device_operations`] pointed to by +/// `gendisk.fops`. pub struct GenDisk { _tagset: Arc>, + _fops: KBox, gendisk: *mut bindings::gendisk, } -- 2.55.0