[PATCH 75/79] block: rnull: allow configuration of the maximum IO size

Andreas Hindborg
2026-02-15T23:46:30Z

Add module parameter and configfs option for controlling the maximum size
of an IO for the emulated block device.

Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
drivers/block/rnull/configfs.rs | 5 +++++
drivers/block/rnull/rnull.rs | 10 +++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
index b449ac882d961..9eaace8b4257e 100644
--- a/drivers/block/rnull/configfs.rs
+++ b/drivers/block/rnull/configfs.rs
@@ -122,6 +122,7 @@ fn make_group(
zone_append_max_sectors: 26,
poll_queues: 27,
fua: 28,
+ max_sectors: 29,
],
};

@@ -208,6 +209,7 @@ fn make_group(
requeue_inject,
#[cfg(CONFIG_BLK_DEV_RUST_NULL_FAULT_INJECTION)]
init_hctx_inject,
+ max_sectors: 0,
}),
}),
default_groups,
@@ -290,6 +292,7 @@ struct DeviceConfigInner {
requeue_inject: Arc<FaultConfig>,
#[cfg(CONFIG_BLK_DEV_RUST_NULL_FAULT_INJECTION)]
init_hctx_inject: Arc<FaultConfig>,
+ max_sectors: u32,
}

#[vtable]
@@ -347,6 +350,7 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result {
init_hctx_inject: guard.init_hctx_inject.clone(),
#[cfg(CONFIG_BLK_DEV_RUST_NULL_FAULT_INJECTION)]
timeout_inject: guard.timeout_inject.clone(),
+ max_sectors: guard.max_sectors,
})?);
guard.powered = true;
} else if guard.powered && !power_op {
@@ -624,3 +628,4 @@ fn store(this: &DeviceConfig, page: &[u8]) -> Result {
},
}
configfs_simple_bool_field!(DeviceConfig, 28, fua);
+configfs_simple_field!(DeviceConfig, 29, max_sectors, u32);
diff --git a/drivers/block/rnull/rnull.rs b/drivers/block/rnull/rnull.rs
index b2b089a657f12..495a810f4f4e1 100644
--- a/drivers/block/rnull/rnull.rs
+++ b/drivers/block/rnull/rnull.rs
@@ -206,6 +206,10 @@
default: 1,
description: "Enable/disable FUA support when cache_size is used. Default: 1 (true)",
},
+ max_sectors: u32 {
+ default: 0,
+ description: "Maximum size of a command (in 512B sectors)",
+ },
},
}

@@ -282,6 +286,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
)?,
#[cfg(CONFIG_BLK_DEV_RUST_NULL_FAULT_INJECTION)]
timeout_inject: Arc::pin_init(FaultConfig::new(c"timeout_inject"), GFP_KERNEL)?,
+ max_sectors: *module_parameters::max_sectors.value(),
})?;
disks.push(disk, GFP_KERNEL)?;
}
@@ -336,6 +341,7 @@ struct NullBlkOptions<'a> {
init_hctx_inject: Arc<FaultConfig>,
#[cfg(CONFIG_BLK_DEV_RUST_NULL_FAULT_INJECTION)]
timeout_inject: Arc<FaultConfig>,
+ max_sectors: u32,
}

static SHARED_TAG_SET: SetOnce<Arc<TagSet<NullBlkDevice>>> = SetOnce::new();
@@ -407,6 +413,7 @@ fn new(options: NullBlkOptions<'_>) -> Result<Arc<GenDisk<Self>>> {
init_hctx_inject,
#[cfg(CONFIG_BLK_DEV_RUST_NULL_FAULT_INJECTION)]
timeout_inject,
+ max_sectors,
} = options;

let mut flags = mq::tag_set::Flags::default();
@@ -502,7 +509,8 @@ fn new(options: NullBlkOptions<'_>) -> Result<Arc<GenDisk<Self>>> {
.physical_block_size(block_size_bytes)?
.rotational(rotational)
.write_cache(storage.cache_enabled())
- .forced_unit_access(forced_unit_access && storage.cache_enabled());
+ .forced_unit_access(forced_unit_access && storage.cache_enabled())
+ .max_sectors(max_sectors);

#[cfg(CONFIG_BLK_DEV_ZONED)]
{

--
2.51.2