Commit bc5b533b authored by Andreas Hindborg's avatar Andreas Hindborg Committed by Jens Axboe
Browse files

rust: block: add rnull, Rust null_blk implementation



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

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


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 3253aba3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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

drivers/block/rnull.rs

0 → 100644
+73 −0
Original line number Diff line number Diff line
// 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>>>>,
}

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::new(1, 256, 1), flags::GFP_KERNEL)?;

        let disk = gen_disk::GenDiskBuilder::new()
            .capacity_sectors(4096 << 11)
            .logical_block_size(4096)?
            .physical_block_size(4096)?
            .rotational(false)
            .build(format_args!("rnullb{}", 0), tagset)?;

        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)
            // We take no refcounts on the request, so we expect to be able to
            // end the request. The request reference must be unique at this
            // point, and so `end_ok` cannot fail.
            .expect("Fatal error - expected to be able to end request");

        Ok(())
    }

    fn commit_rqs() {}
}