Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rust: block: add rnull, Rust null_blk implementation

This patch adds an initial version of the Rust null block driver.

Signed-off-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20240611114551.228679-3-nmi@metaspace.dk
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Andreas Hindborg and committed by
Jens Axboe
bc5b533b 3253aba3

+85
+9
drivers/block/Kconfig
··· 354 354 This is the virtual block driver for virtio. It can be used with 355 355 QEMU based VMMs (like KVM or Xen). Say Y or M. 356 356 357 + config BLK_DEV_RUST_NULL 358 + tristate "Rust null block driver (Experimental)" 359 + depends on RUST 360 + help 361 + This is the Rust implementation of the null block driver. For now it 362 + is only a minimal stub. 363 + 364 + If unsure, say N. 365 + 357 366 config BLK_DEV_RBD 358 367 tristate "Rados block device (RBD)" 359 368 depends on INET && BLOCK
+3
drivers/block/Makefile
··· 9 9 # needed for trace events 10 10 ccflags-y += -I$(src) 11 11 12 + obj-$(CONFIG_BLK_DEV_RUST_NULL) += rnull_mod.o 13 + rnull_mod-y := rnull.o 14 + 12 15 obj-$(CONFIG_MAC_FLOPPY) += swim3.o 13 16 obj-$(CONFIG_BLK_DEV_SWIM) += swim_mod.o 14 17 obj-$(CONFIG_BLK_DEV_FD) += floppy.o
+73
drivers/block/rnull.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! This is a Rust implementation of the C null block driver. 4 + //! 5 + //! Supported features: 6 + //! 7 + //! - blk-mq interface 8 + //! - direct completion 9 + //! - block size 4k 10 + //! 11 + //! The driver is not configurable. 12 + 13 + use kernel::{ 14 + alloc::flags, 15 + block::mq::{ 16 + self, 17 + gen_disk::{self, GenDisk}, 18 + Operations, TagSet, 19 + }, 20 + error::Result, 21 + new_mutex, pr_info, 22 + prelude::*, 23 + sync::{Arc, Mutex}, 24 + types::ARef, 25 + }; 26 + 27 + module! { 28 + type: NullBlkModule, 29 + name: "rnull_mod", 30 + author: "Andreas Hindborg", 31 + license: "GPL v2", 32 + } 33 + 34 + struct NullBlkModule { 35 + _disk: Pin<Box<Mutex<GenDisk<NullBlkDevice>>>>, 36 + } 37 + 38 + impl kernel::Module for NullBlkModule { 39 + fn init(_module: &'static ThisModule) -> Result<Self> { 40 + pr_info!("Rust null_blk loaded\n"); 41 + let tagset = Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?; 42 + 43 + let disk = gen_disk::GenDiskBuilder::new() 44 + .capacity_sectors(4096 << 11) 45 + .logical_block_size(4096)? 46 + .physical_block_size(4096)? 47 + .rotational(false) 48 + .build(format_args!("rnullb{}", 0), tagset)?; 49 + 50 + let disk = Box::pin_init(new_mutex!(disk, "nullb:disk"), flags::GFP_KERNEL)?; 51 + 52 + Ok(Self { _disk: disk }) 53 + } 54 + } 55 + 56 + struct NullBlkDevice; 57 + 58 + #[vtable] 59 + impl Operations for NullBlkDevice { 60 + #[inline(always)] 61 + fn queue_rq(rq: ARef<mq::Request<Self>>, _is_last: bool) -> Result { 62 + mq::Request::end_ok(rq) 63 + .map_err(|_e| kernel::error::code::EIO) 64 + // We take no refcounts on the request, so we expect to be able to 65 + // end the request. The request reference must be unique at this 66 + // point, and so `end_ok` cannot fail. 67 + .expect("Fatal error - expected to be able to end request"); 68 + 69 + Ok(()) 70 + } 71 + 72 + fn commit_rqs() {} 73 + }