@@ -9,7 +9,7 @@
use crate::error::{code::*, from_result, to_result, Error};
use crate::types::Opaque;
use crate::{bindings, init::PinInit, str::CStr, try_pin_init, ThisModule};
-use core::{marker::PhantomPinned, pin::Pin};
+use core::{marker::PhantomData, marker::PhantomPinned, pin::Pin};
use macros::{pin_data, pinned_drop};
/// A file system type.
@@ -78,3 +78,57 @@ fn drop(self: Pin<&mut Self>) {
unsafe { bindings::unregister_filesystem(self.fs.get()) };
}
}
+
+/// Kernel module that exposes a single file system implemented by `T`.
+#[pin_data]
+pub struct Module<T: FileSystem + ?Sized> {
+ #[pin]
+ fs_reg: Registration,
+ _p: PhantomData<T>,
+}
+
+impl<T: FileSystem + ?Sized + Sync + Send> crate::InPlaceModule for Module<T> {
+ fn init(module: &'static ThisModule) -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {
+ fs_reg <- Registration::new::<T>(module),
+ _p: PhantomData,
+ })
+ }
+}
+
+/// Declares a kernel module that exposes a single file system.
+///
+/// The `type` argument must be a type which implements the [`FileSystem`] trait. Also accepts
+/// various forms of kernel metadata.
+///
+/// # Examples
+///
+/// ```
+/// # mod module_fs_sample {
+/// use kernel::prelude::*;
+/// use kernel::{c_str, fs};
+///
+/// kernel::module_fs! {
+/// type: MyFs,
+/// name: "myfs",
+/// author: "Rust for Linux Contributors",
+/// description: "My Rust fs",
+/// license: "GPL",
+/// }
+///
+/// struct MyFs;
+/// impl fs::FileSystem for MyFs {
+/// const NAME: &'static CStr = c_str!("myfs");
+/// }
+/// # }
+/// ```
+#[macro_export]
+macro_rules! module_fs {
+ (type: $type:ty, $($f:tt)*) => {
+ type ModuleType = $crate::fs::Module<$type>;
+ $crate::macros::module! {
+ type: ModuleType,
+ $($f)*
+ }
+ }
+}