Skip to content

Commit

Permalink
rust: add module_fs macro
Browse files Browse the repository at this point in the history
This reduces the amount of code needed to implement a module that
only implements a file system.

Signed-off-by: Wedson Almeida Filho <[email protected]>
  • Loading branch information
wedsonaf committed Jul 25, 2022
1 parent bd36aaf commit 17058e1
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
77 changes: 77 additions & 0 deletions rust/kernel/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
bindings, error::code::*, error::from_kernel_result, str::CStr, to_result,
types::PointerWrapper, AlwaysRefCounted, Error, Result, ScopeGuard, ThisModule,
};
use alloc::boxed::Box;
use core::{
cell::UnsafeCell,
marker::{PhantomData, PhantomPinned},
Expand Down Expand Up @@ -763,3 +764,79 @@ impl Filename {
unsafe { &*ptr.cast() }
}
}

/// Kernel module that exposes a single file system implemented by `T`.
pub struct Module<T: Type> {
_fs: Pin<Box<Registration>>,
_p: PhantomData<T>,
}

impl<T: Type + Sync> crate::Module for Module<T> {
fn init(_name: &'static CStr, module: &'static ThisModule) -> Result<Self> {
let mut reg = Pin::from(Box::try_new(Registration::new())?);
reg.as_mut().register::<T>(module)?;
Ok(Self {
_fs: reg,
_p: PhantomData,
})
}
}

/// Declares a kernel module that exposes a single file system.
///
/// The `type` argument must be a type which implements the [`Type`] trait. Also accepts various
/// forms of kernel metadata.
///
/// # Examples
///
/// ```ignore
/// use kernel::prelude::*;
/// use kernel::{c_str, fs};
///
/// module_fs! {
/// type: MyFs,
/// name: b"my_fs_kernel_module",
/// author: b"Rust for Linux Contributors",
/// description: b"My very own file system kernel module!",
/// license: b"GPL",
/// }
///
/// struct MyFs;
///
/// #[vtable]
/// impl fs::Context<Self> for MyFs {
/// type Data = ();
/// fn try_new() -> Result {
/// Ok(())
/// }
/// }
///
/// impl fs::Type for MyFs {
/// type Context = Self;
/// const SUPER_TYPE: fs::Super = fs::Super::Independent;
/// const NAME: &'static CStr = c_str!("example");
/// const FLAGS: i32 = 0;
///
/// fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock<Self>> {
/// let sb = sb.init(
/// (),
/// &fs::SuperParams {
/// magic: 0x6578616d,
/// ..fs::SuperParams::DEFAULT
/// },
/// )?;
/// let sb = sb.init_root()?;
/// Ok(sb)
/// }
/// }
/// ```
#[macro_export]
macro_rules! module_fs {
(type: $type:ty, $($f:tt)*) => {
type ModuleType = $crate::fs::Module<$type>;
$crate::macros::module! {
type: ModuleType,
$($f)*
}
}
}
2 changes: 1 addition & 1 deletion rust/kernel/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use super::{
pr_alert, pr_crit, pr_debug, pr_emerg, pr_err, pr_info, pr_notice, pr_warn,
};

pub use super::module_misc_device;
pub use super::{module_fs, module_misc_device};

#[cfg(CONFIG_ARM_AMBA)]
pub use super::module_amba_driver;
Expand Down
16 changes: 2 additions & 14 deletions samples/rust/rust_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
use kernel::prelude::*;
use kernel::{c_str, fs};

module! {
type: FsModule,
module_fs! {
type: RustFs,
name: b"rust_fs",
author: b"Rust for Linux Contributors",
license: b"GPL",
Expand Down Expand Up @@ -57,15 +57,3 @@ impl fs::Type for RustFs {
Ok(sb)
}
}

struct FsModule {
_fs: Pin<Box<fs::Registration>>,
}

impl kernel::Module for FsModule {
fn init(_name: &'static CStr, module: &'static ThisModule) -> Result<Self> {
let mut reg = Pin::from(Box::try_new(fs::Registration::new())?);
reg.as_mut().register::<RustFs>(module)?;
Ok(Self { _fs: reg })
}
}

0 comments on commit 17058e1

Please sign in to comment.