@@ -8,6 +8,7 @@ use crate::{
8
8
bindings, error:: code:: * , error:: from_kernel_result, str:: CStr , to_result,
9
9
types:: PointerWrapper , AlwaysRefCounted , Error , Result , ScopeGuard , ThisModule ,
10
10
} ;
11
+ use alloc:: boxed:: Box ;
11
12
use core:: {
12
13
cell:: UnsafeCell ,
13
14
marker:: { PhantomData , PhantomPinned } ,
@@ -763,3 +764,79 @@ impl Filename {
763
764
unsafe { & * ptr. cast ( ) }
764
765
}
765
766
}
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