@@ -106,8 +106,13 @@ pub enum DirEntryType {
106106impl From < INodeType > for DirEntryType {
107107 fn from ( value : INodeType ) -> Self {
108108 match value {
109+ INodeType :: Fifo => DirEntryType :: Fifo ,
110+ INodeType :: Chr ( _, _) => DirEntryType :: Chr ,
109111 INodeType :: Dir => DirEntryType :: Dir ,
112+ INodeType :: Blk ( _, _) => DirEntryType :: Blk ,
110113 INodeType :: Reg => DirEntryType :: Reg ,
114+ INodeType :: Lnk => DirEntryType :: Lnk ,
115+ INodeType :: Sock => DirEntryType :: Sock ,
111116 }
112117 }
113118}
@@ -272,6 +277,46 @@ impl<T: FileSystem + ?Sized> NewINode<T> {
272277 unsafe { bindings:: mapping_set_large_folios ( inode. i_mapping ) } ;
273278 bindings:: S_IFREG
274279 }
280+ INodeType :: Lnk => {
281+ inode. i_op = & Tables :: < T > :: LNK_INODE_OPERATIONS ;
282+ inode. i_data . a_ops = & Tables :: < T > :: FILE_ADDRESS_SPACE_OPERATIONS ;
283+
284+ // SAFETY: `inode` is valid for write as it's a new inode.
285+ unsafe { bindings:: inode_nohighmem ( inode) } ;
286+ bindings:: S_IFLNK
287+ }
288+ INodeType :: Fifo => {
289+ // SAFETY: `inode` is valid for write as it's a new inode.
290+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFIFO as _ , 0 ) } ;
291+ bindings:: S_IFIFO
292+ }
293+ INodeType :: Sock => {
294+ // SAFETY: `inode` is valid for write as it's a new inode.
295+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFSOCK as _ , 0 ) } ;
296+ bindings:: S_IFSOCK
297+ }
298+ INodeType :: Chr ( major, minor) => {
299+ // SAFETY: `inode` is valid for write as it's a new inode.
300+ unsafe {
301+ bindings:: init_special_inode (
302+ inode,
303+ bindings:: S_IFCHR as _ ,
304+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
305+ )
306+ } ;
307+ bindings:: S_IFCHR
308+ }
309+ INodeType :: Blk ( major, minor) => {
310+ // SAFETY: `inode` is valid for write as it's a new inode.
311+ unsafe {
312+ bindings:: init_special_inode (
313+ inode,
314+ bindings:: S_IFBLK as _ ,
315+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
316+ )
317+ } ;
318+ bindings:: S_IFBLK
319+ }
275320 } ;
276321
277322 inode. i_mode = ( params. mode & 0o777 ) | u16:: try_from ( mode) ?;
@@ -306,11 +351,26 @@ impl<T: FileSystem + ?Sized> Drop for NewINode<T> {
306351/// The type of the inode.
307352#[ derive( Copy , Clone ) ]
308353pub enum INodeType {
354+ /// Named pipe (first-in, first-out) type.
355+ Fifo ,
356+
357+ /// Character device type.
358+ Chr ( u32 , u32 ) ,
359+
309360 /// Directory type.
310361 Dir ,
311362
363+ /// Block device type.
364+ Blk ( u32 , u32 ) ,
365+
312366 /// Regular file type.
313367 Reg ,
368+
369+ /// Symbolic link type.
370+ Lnk ,
371+
372+ /// Named unix-domain socket type.
373+ Sock ,
314374}
315375
316376/// Required inode parameters.
@@ -720,6 +780,34 @@ impl<T: FileSystem + ?Sized> Tables<T> {
720780 }
721781 }
722782
783+ const LNK_INODE_OPERATIONS : bindings:: inode_operations = bindings:: inode_operations {
784+ lookup : None ,
785+ get_link : Some ( bindings:: page_get_link) ,
786+ permission : None ,
787+ get_inode_acl : None ,
788+ readlink : None ,
789+ create : None ,
790+ link : None ,
791+ unlink : None ,
792+ symlink : None ,
793+ mkdir : None ,
794+ rmdir : None ,
795+ mknod : None ,
796+ rename : None ,
797+ setattr : None ,
798+ getattr : None ,
799+ listxattr : None ,
800+ fiemap : None ,
801+ update_time : None ,
802+ atomic_open : None ,
803+ tmpfile : None ,
804+ get_acl : None ,
805+ set_acl : None ,
806+ fileattr_set : None ,
807+ fileattr_get : None ,
808+ get_offset_ctx : None ,
809+ } ;
810+
723811 const FILE_ADDRESS_SPACE_OPERATIONS : bindings:: address_space_operations =
724812 bindings:: address_space_operations {
725813 writepage : None ,
0 commit comments