On 01.06.24 10:18, Andreas Hindborg wrote: > From: Andreas Hindborg <a.hindborg@xxxxxxxxxxx> > > This patch adds an initial version of the Rust null block driver. > > Signed-off-by: Andreas Hindborg <a.hindborg@xxxxxxxxxxx> > --- > drivers/block/Kconfig | 9 +++++ > drivers/block/Makefile | 3 ++ > drivers/block/rnull.rs | 78 ++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 90 insertions(+) > create mode 100644 drivers/block/rnull.rs I left two comments below, but it already seems fine to me: Reviewed-by: Benno Lossin <benno.lossin@xxxxxxxxx> > > diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig > index 5b9d4aaebb81..ed209f4f2798 100644 > --- a/drivers/block/Kconfig > +++ b/drivers/block/Kconfig > @@ -354,6 +354,15 @@ 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. > > +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 101612cba303..1105a2d4fdcb 100644 > --- a/drivers/block/Makefile > +++ b/drivers/block/Makefile > @@ -9,6 +9,9 @@ > # needed for trace events > ccflags-y += -I$(src) > > +obj-$(CONFIG_BLK_DEV_RUST_NULL) += rnull_mod.o > +rnull_mod-y := rnull.o > + > obj-$(CONFIG_MAC_FLOPPY) += swim3.o > obj-$(CONFIG_BLK_DEV_SWIM) += swim_mod.o > obj-$(CONFIG_BLK_DEV_FD) += floppy.o > diff --git a/drivers/block/rnull.rs b/drivers/block/rnull.rs > new file mode 100644 > index 000000000000..c69ea7e7436e > --- /dev/null > +++ b/drivers/block/rnull.rs > @@ -0,0 +1,78 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +//! 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. > + > +use kernel::{ > + alloc::flags, > + block::mq::{ > + self, > + gen_disk::{self, GenDisk}, > + Operations, TagSet, > + }, > + error::Result, > + new_mutex, pr_info, > + prelude::*, > + sync::{Arc, Mutex}, > + types::ARef, > +}; > + > +module! { > + type: NullBlkModule, > + name: "rnull_mod", > + author: "Andreas Hindborg", > + license: "GPL v2", > +} > + > +struct NullBlkModule { > + _disk: Pin<Box<Mutex<GenDisk<NullBlkDevice, gen_disk::Added>>>>, > +} > + > +impl kernel::Module for NullBlkModule { > + fn init(_module: &'static ThisModule) -> Result<Self> { > + pr_info!("Rust null_blk loaded\n"); > + let tagset = Arc::pin_init(TagSet::try_new(1, 256, 1), flags::GFP_KERNEL)?; > + > + let disk = { > + let block_size: u16 = 4096; > + if block_size % 512 != 0 || !(512..=4096).contains(&block_size) { > + return Err(kernel::error::code::EINVAL); > + } > + > + let mut disk = gen_disk::GenDisk::try_new(tagset)?; > + disk.set_name(format_args!("rnullb{}", 0))?; > + disk.set_capacity_sectors(4096 << 11); > + disk.set_queue_logical_block_size(block_size.into()); > + disk.set_queue_physical_block_size(block_size.into()); > + disk.set_rotational(false); > + disk.add() > + }?; Personally, I would prefer to put the `?` into the line above. > + > + let disk = Box::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?; > + > + Ok(Self { _disk: disk }) > + } > +} > + > +struct NullBlkDevice; > + > +#[vtable] > +impl Operations for NullBlkDevice { > + #[inline(always)] > + fn queue_rq(rq: ARef<mq::Request<Self>>, _is_last: bool) -> Result { > + mq::Request::end_ok(rq) > + .map_err(|_e| kernel::error::code::EIO) > + .expect("Fatal error - expected to be able to end request"); I expected something more along the lines of: "expected to be able to end request, since `NullBlkDevice` never takes refcounts on Requests and as such the ARef must be unique, but `end_ok` only fails if that is not the case". But maybe that would fit better in a comment, what do you think? > + > + Ok(()) > + } > + > + fn commit_rqs() {} > +} > -- > 2.45.1 >