@@ -117,8 +117,13 @@ pub enum DirEntryType {
117117impl From < INodeType > for DirEntryType {
118118 fn from ( value : INodeType ) -> Self {
119119 match value {
120+ INodeType :: Fifo => DirEntryType :: Fifo ,
121+ INodeType :: Chr ( _, _) => DirEntryType :: Chr ,
120122 INodeType :: Dir => DirEntryType :: Dir ,
123+ INodeType :: Blk ( _, _) => DirEntryType :: Blk ,
121124 INodeType :: Reg => DirEntryType :: Reg ,
125+ INodeType :: Lnk => DirEntryType :: Lnk ,
126+ INodeType :: Sock => DirEntryType :: Sock ,
122127 }
123128 }
124129}
@@ -280,6 +285,46 @@ impl<T: FileSystem + ?Sized> NewINode<T> {
280285 unsafe { bindings:: mapping_set_large_folios ( inode. i_mapping ) } ;
281286 bindings:: S_IFREG
282287 }
288+ INodeType :: Lnk => {
289+ inode. i_op = & Tables :: < T > :: LNK_INODE_OPERATIONS ;
290+ inode. i_data . a_ops = & Tables :: < T > :: FILE_ADDRESS_SPACE_OPERATIONS ;
291+
292+ // SAFETY: `inode` is valid for write as it's a new inode.
293+ unsafe { bindings:: inode_nohighmem ( inode) } ;
294+ bindings:: S_IFLNK
295+ }
296+ INodeType :: Fifo => {
297+ // SAFETY: `inode` is valid for write as it's a new inode.
298+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFIFO as _ , 0 ) } ;
299+ bindings:: S_IFIFO
300+ }
301+ INodeType :: Sock => {
302+ // SAFETY: `inode` is valid for write as it's a new inode.
303+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFSOCK as _ , 0 ) } ;
304+ bindings:: S_IFSOCK
305+ }
306+ INodeType :: Chr ( major, minor) => {
307+ // SAFETY: `inode` is valid for write as it's a new inode.
308+ unsafe {
309+ bindings:: init_special_inode (
310+ inode,
311+ bindings:: S_IFCHR as _ ,
312+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
313+ )
314+ } ;
315+ bindings:: S_IFCHR
316+ }
317+ INodeType :: Blk ( major, minor) => {
318+ // SAFETY: `inode` is valid for write as it's a new inode.
319+ unsafe {
320+ bindings:: init_special_inode (
321+ inode,
322+ bindings:: S_IFBLK as _ ,
323+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
324+ )
325+ } ;
326+ bindings:: S_IFBLK
327+ }
283328 } ;
284329
285330 inode. i_mode = ( params. mode & 0o777 ) | u16:: try_from ( mode) ?;
@@ -314,11 +359,26 @@ impl<T: FileSystem + ?Sized> Drop for NewINode<T> {
314359/// The type of the inode.
315360#[ derive( Copy , Clone ) ]
316361pub enum INodeType {
362+ /// Named pipe (first-in, first-out) type.
363+ Fifo ,
364+
365+ /// Character device type.
366+ Chr ( u32 , u32 ) ,
367+
317368 /// Directory type.
318369 Dir ,
319370
371+ /// Block device type.
372+ Blk ( u32 , u32 ) ,
373+
320374 /// Regular file type.
321375 Reg ,
376+
377+ /// Symbolic link type.
378+ Lnk ,
379+
380+ /// Named unix-domain socket type.
381+ Sock ,
322382}
323383
324384/// Required inode parameters.
@@ -725,6 +785,34 @@ impl<T: FileSystem + ?Sized> Tables<T> {
725785 }
726786 }
727787
788+ const LNK_INODE_OPERATIONS : bindings:: inode_operations = bindings:: inode_operations {
789+ lookup : None ,
790+ get_link : Some ( bindings:: page_get_link) ,
791+ permission : None ,
792+ get_inode_acl : None ,
793+ readlink : None ,
794+ create : None ,
795+ link : None ,
796+ unlink : None ,
797+ symlink : None ,
798+ mkdir : None ,
799+ rmdir : None ,
800+ mknod : None ,
801+ rename : None ,
802+ setattr : None ,
803+ getattr : None ,
804+ listxattr : None ,
805+ fiemap : None ,
806+ update_time : None ,
807+ atomic_open : None ,
808+ tmpfile : None ,
809+ get_acl : None ,
810+ set_acl : None ,
811+ fileattr_set : None ,
812+ fileattr_get : None ,
813+ get_offset_ctx : None ,
814+ } ;
815+
728816 const FILE_ADDRESS_SPACE_OPERATIONS : bindings:: address_space_operations =
729817 bindings:: address_space_operations {
730818 writepage : None ,
0 commit comments