@@ -8,6 +8,7 @@ use crate::{
88 bindings, error:: code:: * , error:: from_kernel_result, str:: CStr , to_result,
99 types:: PointerWrapper , AlwaysRefCounted , Error , Result , ScopeGuard , ThisModule ,
1010} ;
11+ use alloc:: boxed:: Box ;
1112use core:: {
1213 cell:: UnsafeCell ,
1314 marker:: { PhantomData , PhantomPinned } ,
@@ -763,3 +764,79 @@ impl Filename {
763764 unsafe { & * ptr. cast ( ) }
764765 }
765766}
767+
768+ /// Kernel module that exposes a single file system implemented by `T`.
769+ pub struct Module < T : Type > {
770+ _fs : Pin < Box < Registration > > ,
771+ _p : PhantomData < T > ,
772+ }
773+
774+ impl < T : Type + Sync > crate :: Module for Module < T > {
775+ fn init ( _name : & ' static CStr , module : & ' static ThisModule ) -> Result < Self > {
776+ let mut reg = Pin :: from ( Box :: try_new ( Registration :: new ( ) ) ?) ;
777+ reg. as_mut ( ) . register :: < T > ( module) ?;
778+ Ok ( Self {
779+ _fs : reg,
780+ _p : PhantomData ,
781+ } )
782+ }
783+ }
784+
785+ /// Declares a kernel module that exposes a single file system.
786+ ///
787+ /// The `type` argument must be a type which implements the [`Type`] trait. Also accepts various
788+ /// forms of kernel metadata.
789+ ///
790+ /// # Examples
791+ ///
792+ /// ```ignore
793+ /// use kernel::prelude::*;
794+ /// use kernel::{c_str, fs};
795+ ///
796+ /// module_fs! {
797+ /// type: MyFs,
798+ /// name: b"my_fs_kernel_module",
799+ /// author: b"Rust for Linux Contributors",
800+ /// description: b"My very own file system kernel module!",
801+ /// license: b"GPL",
802+ /// }
803+ ///
804+ /// struct MyFs;
805+ ///
806+ /// #[vtable]
807+ /// impl fs::Context<Self> for MyFs {
808+ /// type Data = ();
809+ /// fn try_new() -> Result {
810+ /// Ok(())
811+ /// }
812+ /// }
813+ ///
814+ /// impl fs::Type for MyFs {
815+ /// type Context = Self;
816+ /// const SUPER_TYPE: fs::Super = fs::Super::Independent;
817+ /// const NAME: &'static CStr = c_str!("example");
818+ /// const FLAGS: i32 = 0;
819+ ///
820+ /// fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock<Self>> {
821+ /// let sb = sb.init(
822+ /// (),
823+ /// &fs::SuperParams {
824+ /// magic: 0x6578616d,
825+ /// ..fs::SuperParams::DEFAULT
826+ /// },
827+ /// )?;
828+ /// let sb = sb.init_root()?;
829+ /// Ok(sb)
830+ /// }
831+ /// }
832+ /// ```
833+ #[ macro_export]
834+ macro_rules! module_fs {
835+ ( type : $type: ty, $( $f: tt) * ) => {
836+ type ModuleType = $crate:: fs:: Module <$type>;
837+ $crate:: macros:: module! {
838+ type : ModuleType ,
839+ $( $f) *
840+ }
841+ }
842+ }
0 commit comments