@@ -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}
@@ -275,6 +280,46 @@ impl<T: FileSystem + ?Sized> NewINode<T> {
275280 unsafe { bindings:: mapping_set_large_folios ( inode. i_mapping ) } ;
276281 bindings:: S_IFREG
277282 }
283+ INodeType :: Lnk => {
284+ inode. i_op = & Tables :: < T > :: LNK_INODE_OPERATIONS ;
285+ inode. i_data . a_ops = & Tables :: < T > :: FILE_ADDRESS_SPACE_OPERATIONS ;
286+
287+ // SAFETY: `inode` is valid for write as it's a new inode.
288+ unsafe { bindings:: inode_nohighmem ( inode) } ;
289+ bindings:: S_IFLNK
290+ }
291+ INodeType :: Fifo => {
292+ // SAFETY: `inode` is valid for write as it's a new inode.
293+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFIFO as _ , 0 ) } ;
294+ bindings:: S_IFIFO
295+ }
296+ INodeType :: Sock => {
297+ // SAFETY: `inode` is valid for write as it's a new inode.
298+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFSOCK as _ , 0 ) } ;
299+ bindings:: S_IFSOCK
300+ }
301+ INodeType :: Chr ( major, minor) => {
302+ // SAFETY: `inode` is valid for write as it's a new inode.
303+ unsafe {
304+ bindings:: init_special_inode (
305+ inode,
306+ bindings:: S_IFCHR as _ ,
307+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
308+ )
309+ } ;
310+ bindings:: S_IFCHR
311+ }
312+ INodeType :: Blk ( major, minor) => {
313+ // SAFETY: `inode` is valid for write as it's a new inode.
314+ unsafe {
315+ bindings:: init_special_inode (
316+ inode,
317+ bindings:: S_IFBLK as _ ,
318+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
319+ )
320+ } ;
321+ bindings:: S_IFBLK
322+ }
278323 } ;
279324
280325 inode. i_mode = ( params. mode & 0o777 ) | u16:: try_from ( mode) ?;
@@ -309,11 +354,26 @@ impl<T: FileSystem + ?Sized> Drop for NewINode<T> {
309354/// The type of the inode.
310355#[ derive( Copy , Clone ) ]
311356pub enum INodeType {
357+ /// Named pipe (first-in, first-out) type.
358+ Fifo ,
359+
360+ /// Character device type.
361+ Chr ( u32 , u32 ) ,
362+
312363 /// Directory type.
313364 Dir ,
314365
366+ /// Block device type.
367+ Blk ( u32 , u32 ) ,
368+
315369 /// Regular file type.
316370 Reg ,
371+
372+ /// Symbolic link type.
373+ Lnk ,
374+
375+ /// Named unix-domain socket type.
376+ Sock ,
317377}
318378
319379/// Required inode parameters.
@@ -723,6 +783,34 @@ impl<T: FileSystem + ?Sized> Tables<T> {
723783 }
724784 }
725785
786+ const LNK_INODE_OPERATIONS : bindings:: inode_operations = bindings:: inode_operations {
787+ lookup : None ,
788+ get_link : Some ( bindings:: page_get_link) ,
789+ permission : None ,
790+ get_inode_acl : None ,
791+ readlink : None ,
792+ create : None ,
793+ link : None ,
794+ unlink : None ,
795+ symlink : None ,
796+ mkdir : None ,
797+ rmdir : None ,
798+ mknod : None ,
799+ rename : None ,
800+ setattr : None ,
801+ getattr : None ,
802+ listxattr : None ,
803+ fiemap : None ,
804+ update_time : None ,
805+ atomic_open : None ,
806+ tmpfile : None ,
807+ get_acl : None ,
808+ set_acl : None ,
809+ fileattr_set : None ,
810+ fileattr_get : None ,
811+ get_offset_ctx : None ,
812+ } ;
813+
726814 const FILE_ADDRESS_SPACE_OPERATIONS : bindings:: address_space_operations =
727815 bindings:: address_space_operations {
728816 writepage : None ,
0 commit comments