@@ -112,8 +112,13 @@ pub enum DirEntryType {
112112impl From < INodeType > for DirEntryType {
113113 fn from ( value : INodeType ) -> Self {
114114 match value {
115+ INodeType :: Fifo => DirEntryType :: Fifo ,
116+ INodeType :: Chr ( _, _) => DirEntryType :: Chr ,
115117 INodeType :: Dir => DirEntryType :: Dir ,
118+ INodeType :: Blk ( _, _) => DirEntryType :: Blk ,
116119 INodeType :: Reg => DirEntryType :: Reg ,
120+ INodeType :: Lnk => DirEntryType :: Lnk ,
121+ INodeType :: Sock => DirEntryType :: Sock ,
117122 }
118123 }
119124}
@@ -281,6 +286,46 @@ impl<T: FileSystem + ?Sized> NewINode<T> {
281286 unsafe { bindings:: mapping_set_large_folios ( inode. i_mapping ) } ;
282287 bindings:: S_IFREG
283288 }
289+ INodeType :: Lnk => {
290+ inode. i_op = & Tables :: < T > :: LNK_INODE_OPERATIONS ;
291+ inode. i_data . a_ops = & Tables :: < T > :: FILE_ADDRESS_SPACE_OPERATIONS ;
292+
293+ // SAFETY: `inode` is valid for write as it's a new inode.
294+ unsafe { bindings:: inode_nohighmem ( inode) } ;
295+ bindings:: S_IFLNK
296+ }
297+ INodeType :: Fifo => {
298+ // SAFETY: `inode` is valid for write as it's a new inode.
299+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFIFO as _ , 0 ) } ;
300+ bindings:: S_IFIFO
301+ }
302+ INodeType :: Sock => {
303+ // SAFETY: `inode` is valid for write as it's a new inode.
304+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFSOCK as _ , 0 ) } ;
305+ bindings:: S_IFSOCK
306+ }
307+ INodeType :: Chr ( major, minor) => {
308+ // SAFETY: `inode` is valid for write as it's a new inode.
309+ unsafe {
310+ bindings:: init_special_inode (
311+ inode,
312+ bindings:: S_IFCHR as _ ,
313+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
314+ )
315+ } ;
316+ bindings:: S_IFCHR
317+ }
318+ INodeType :: Blk ( major, minor) => {
319+ // SAFETY: `inode` is valid for write as it's a new inode.
320+ unsafe {
321+ bindings:: init_special_inode (
322+ inode,
323+ bindings:: S_IFBLK as _ ,
324+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
325+ )
326+ } ;
327+ bindings:: S_IFBLK
328+ }
284329 } ;
285330
286331 inode. i_mode = ( params. mode & 0o777 ) | u16:: try_from ( mode) ?;
@@ -315,11 +360,26 @@ impl<T: FileSystem + ?Sized> Drop for NewINode<T> {
315360/// The type of the inode.
316361#[ derive( Copy , Clone ) ]
317362pub enum INodeType {
363+ /// Named pipe (first-in, first-out) type.
364+ Fifo ,
365+
366+ /// Character device type.
367+ Chr ( u32 , u32 ) ,
368+
318369 /// Directory type.
319370 Dir ,
320371
372+ /// Block device type.
373+ Blk ( u32 , u32 ) ,
374+
321375 /// Regular file type.
322376 Reg ,
377+
378+ /// Symbolic link type.
379+ Lnk ,
380+
381+ /// Named unix-domain socket type.
382+ Sock ,
323383}
324384
325385/// Required inode parameters.
@@ -701,6 +761,34 @@ impl<T: FileSystem + ?Sized> Tables<T> {
701761 }
702762 }
703763
764+ const LNK_INODE_OPERATIONS : bindings:: inode_operations = bindings:: inode_operations {
765+ lookup : None ,
766+ get_link : Some ( bindings:: page_get_link) ,
767+ permission : None ,
768+ get_inode_acl : None ,
769+ readlink : None ,
770+ create : None ,
771+ link : None ,
772+ unlink : None ,
773+ symlink : None ,
774+ mkdir : None ,
775+ rmdir : None ,
776+ mknod : None ,
777+ rename : None ,
778+ setattr : None ,
779+ getattr : None ,
780+ listxattr : None ,
781+ fiemap : None ,
782+ update_time : None ,
783+ atomic_open : None ,
784+ tmpfile : None ,
785+ get_acl : None ,
786+ set_acl : None ,
787+ fileattr_set : None ,
788+ fileattr_get : None ,
789+ get_offset_ctx : None ,
790+ } ;
791+
704792 const FILE_ADDRESS_SPACE_OPERATIONS : bindings:: address_space_operations =
705793 bindings:: address_space_operations {
706794 writepage : None ,
0 commit comments