[PATCH 12/79] block: rust: add `TagSet` flags

Andreas Hindborg
2026-02-15T23:44:56Z

Add support for `TagSet` flags by introducing a `Flags` type and adding
a flags parameter to `TagSet::new`. This allows configuring tagset
behavior such as blocking vs non-blocking operation.

The Flags type supports bitwise operations and provides values like
`Blocking` for common use cases. The module documentation example is
updated to demonstrate the new API.

For now, only a single flag is added.

Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
drivers/block/rnull/rnull.rs | 5 ++++-
rust/kernel/block/mq.rs | 6 +++---
rust/kernel/block/mq/tag_set.rs | 7 ++++++-
rust/kernel/block/mq/tag_set/flags.rs | 19 +++++++++++++++++++
4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs
index 55e56c39f1c2c..33c1144550a0e 100644
--- a/drivers/block/rnull/rnull.rs
+++ b/drivers/block/rnull/rnull.rs
@@ -130,7 +130,10 @@ fn new(
irq_mode: IRQMode,
completion_time: Delta,
) -> Result<GenDisk<Self>> {
- let tagset = Arc::pin_init(TagSet::new(1, 256, 1), GFP_KERNEL)?;
+ let tagset = Arc::pin_init(
+ TagSet::new(1, 256, 1, mq::tag_set::Flags::default()),
+ GFP_KERNEL,
+ )?;

let queue_data = Box::new(
QueueData {
diff --git a/rust/kernel/block/mq.rs b/rust/kernel/block/mq.rs
index 884bf18abbba5..76e790cdb1f8f 100644
--- a/rust/kernel/block/mq.rs
+++ b/rust/kernel/block/mq.rs
@@ -57,7 +57,7 @@
//!
//! ```rust
//! use kernel::{
-//! block::mq::*,
+//! block::mq::{self, *},
//! new_mutex,
//! prelude::*,
//! sync::{aref::ARef, Arc, Mutex},
@@ -92,7 +92,7 @@
//! }
//!
//! let tagset: Arc<TagSet<MyBlkDevice>> =
-//! Arc::pin_init(TagSet::new(1, 256, 1), GFP_KERNEL)?;
+//! Arc::pin_init(TagSet::new(1, 256, 1, mq::tag_set::Flags::default()), GFP_KERNEL)?;
//! let mut disk = gen_disk::GenDiskBuilder::new()
//! .capacity_sectors(4096)
//! .build(fmt!("myblk"), tagset, ())?;
@@ -103,7 +103,7 @@
pub mod gen_disk;
mod operations;
mod request;
-mod tag_set;
+pub mod tag_set;

pub use operations::Operations;
pub use request::Request;
diff --git a/rust/kernel/block/mq/tag_set.rs b/rust/kernel/block/mq/tag_set.rs
index 46481754b1335..af214f7dd0c10 100644
--- a/rust/kernel/block/mq/tag_set.rs
+++ b/rust/kernel/block/mq/tag_set.rs
@@ -16,6 +16,10 @@
use core::{convert::TryInto, marker::PhantomData};
use pin_init::{pin_data, pinned_drop, PinInit};

+mod flags;
+pub use flags::Flag;
+pub use flags::Flags;
+
/// A wrapper for the C `struct blk_mq_tag_set`.
///
/// `struct blk_mq_tag_set` contains a `struct list_head` and so must be pinned.
@@ -37,6 +41,7 @@ pub fn new(
nr_hw_queues: u32,
num_tags: u32,
num_maps: u32,
+ flags: Flags,
) -> impl PinInit<Self, error::Error> {
// SAFETY: `blk_mq_tag_set` only contains integers and pointers, which
// all are allowed to be 0.
@@ -51,7 +56,7 @@ pub fn new(
numa_node: bindings::NUMA_NO_NODE,
queue_depth: num_tags,
cmd_size,
- flags: 0,
+ flags: flags.into_inner(),
driver_data: core::ptr::null_mut::<crate::ffi::c_void>(),
nr_maps: num_maps,
..tag_set
diff --git a/rust/kernel/block/mq/tag_set/flags.rs b/rust/kernel/block/mq/tag_set/flags.rs
new file mode 100644
index 0000000000000..768db938b9a95
--- /dev/null
+++ b/rust/kernel/block/mq/tag_set/flags.rs
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::prelude::*;
+
+impl_flags! {
+
+ /// Flags to be used when creating [`super::TagSet`] objects.
+ #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
+ pub struct Flags(u32);
+
+ /// Allowed values for [`Flags`].
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub enum Flag {
+ /// Indicate that the queues associated with this tag set might sleep when
+ /// processing IO. When this flag is not set, IO is processed in atomic
+ /// context. When this flag is set, IO is processed in process context.
+ Blocking = bindings::BLK_MQ_F_BLOCKING,
+ }
+}

--
2.51.2