xref: /linux/drivers/block/rnull/rnull.rs (revision 90d952fac8ac1aa6cb21aad7010d33af4d309f4a)
1edd86506SAndreas Hindborg // SPDX-License-Identifier: GPL-2.0
2edd86506SAndreas Hindborg 
3edd86506SAndreas Hindborg //! This is a Rust implementation of the C null block driver.
4d969d504SAndreas Hindborg 
5d969d504SAndreas Hindborg mod configfs;
6edd86506SAndreas Hindborg 
7edd86506SAndreas Hindborg use kernel::{
8d969d504SAndreas Hindborg     block::{
9d969d504SAndreas Hindborg         self,
10d969d504SAndreas Hindborg         mq::{
11edd86506SAndreas Hindborg             self,
12edd86506SAndreas Hindborg             gen_disk::{self, GenDisk},
13edd86506SAndreas Hindborg             Operations, TagSet,
14edd86506SAndreas Hindborg         },
15d969d504SAndreas Hindborg     },
16edd86506SAndreas Hindborg     error::Result,
17d969d504SAndreas Hindborg     pr_info,
18edd86506SAndreas Hindborg     prelude::*,
19d969d504SAndreas Hindborg     sync::Arc,
20edd86506SAndreas Hindborg     types::ARef,
21edd86506SAndreas Hindborg };
22d969d504SAndreas Hindborg use pin_init::PinInit;
23edd86506SAndreas Hindborg 
24edd86506SAndreas Hindborg module! {
25edd86506SAndreas Hindborg     type: NullBlkModule,
26edd86506SAndreas Hindborg     name: "rnull_mod",
27edd86506SAndreas Hindborg     authors: ["Andreas Hindborg"],
28edd86506SAndreas Hindborg     description: "Rust implementation of the C null block driver",
29edd86506SAndreas Hindborg     license: "GPL v2",
30edd86506SAndreas Hindborg }
31edd86506SAndreas Hindborg 
32edd86506SAndreas Hindborg #[pin_data]
33edd86506SAndreas Hindborg struct NullBlkModule {
34edd86506SAndreas Hindborg     #[pin]
35d969d504SAndreas Hindborg     configfs_subsystem: kernel::configfs::Subsystem<configfs::Config>,
36edd86506SAndreas Hindborg }
37edd86506SAndreas Hindborg 
38edd86506SAndreas Hindborg impl kernel::InPlaceModule for NullBlkModule {
39edd86506SAndreas Hindborg     fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
40edd86506SAndreas Hindborg         pr_info!("Rust null_blk loaded\n");
41edd86506SAndreas Hindborg 
42edd86506SAndreas Hindborg         try_pin_init!(Self {
43d969d504SAndreas Hindborg             configfs_subsystem <- configfs::subsystem(),
44edd86506SAndreas Hindborg         })
45edd86506SAndreas Hindborg     }
46edd86506SAndreas Hindborg }
47edd86506SAndreas Hindborg 
48edd86506SAndreas Hindborg struct NullBlkDevice;
49edd86506SAndreas Hindborg 
50d969d504SAndreas Hindborg impl NullBlkDevice {
51d969d504SAndreas Hindborg     fn new(
52d969d504SAndreas Hindborg         name: &CStr,
53d969d504SAndreas Hindborg         block_size: u32,
54d969d504SAndreas Hindborg         rotational: bool,
55d969d504SAndreas Hindborg         capacity_mib: u64,
56d969d504SAndreas Hindborg     ) -> Result<GenDisk<Self>> {
57d969d504SAndreas Hindborg         let tagset = Arc::pin_init(TagSet::new(1, 256, 1), GFP_KERNEL)?;
58d969d504SAndreas Hindborg 
59d969d504SAndreas Hindborg         gen_disk::GenDiskBuilder::new()
60d969d504SAndreas Hindborg             .capacity_sectors(capacity_mib << (20 - block::SECTOR_SHIFT))
61d969d504SAndreas Hindborg             .logical_block_size(block_size)?
62d969d504SAndreas Hindborg             .physical_block_size(block_size)?
63d969d504SAndreas Hindborg             .rotational(rotational)
64*90d952faSAndreas Hindborg             .build(fmt!("{}", name.to_str()?), tagset, ())
65d969d504SAndreas Hindborg     }
66d969d504SAndreas Hindborg }
67d969d504SAndreas Hindborg 
68edd86506SAndreas Hindborg #[vtable]
69edd86506SAndreas Hindborg impl Operations for NullBlkDevice {
70*90d952faSAndreas Hindborg     type QueueData = ();
71*90d952faSAndreas Hindborg 
72edd86506SAndreas Hindborg     #[inline(always)]
73*90d952faSAndreas Hindborg     fn queue_rq(_queue_data: (), rq: ARef<mq::Request<Self>>, _is_last: bool) -> Result {
74edd86506SAndreas Hindborg         mq::Request::end_ok(rq)
75edd86506SAndreas Hindborg             .map_err(|_e| kernel::error::code::EIO)
76edd86506SAndreas Hindborg             // We take no refcounts on the request, so we expect to be able to
77edd86506SAndreas Hindborg             // end the request. The request reference must be unique at this
78edd86506SAndreas Hindborg             // point, and so `end_ok` cannot fail.
79edd86506SAndreas Hindborg             .expect("Fatal error - expected to be able to end request");
80edd86506SAndreas Hindborg 
81edd86506SAndreas Hindborg         Ok(())
82edd86506SAndreas Hindborg     }
83edd86506SAndreas Hindborg 
84*90d952faSAndreas Hindborg     fn commit_rqs(_queue_data: ()) {}
85edd86506SAndreas Hindborg }
86