@@ -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}
@@ -269,6 +274,46 @@ impl<T: FileSystem + ?Sized> NewINode<T> {
269274 unsafe { bindings:: mapping_set_large_folios ( inode. i_mapping ) } ;
270275 bindings:: S_IFREG
271276 }
277+ INodeType :: Lnk => {
278+ inode. i_op = & Tables :: < T > :: LNK_INODE_OPERATIONS ;
279+ inode. i_data . a_ops = & Tables :: < T > :: FILE_ADDRESS_SPACE_OPERATIONS ;
280+
281+ // SAFETY: `inode` is valid for write as it's a new inode.
282+ unsafe { bindings:: inode_nohighmem ( inode) } ;
283+ bindings:: S_IFLNK
284+ }
285+ INodeType :: Fifo => {
286+ // SAFETY: `inode` is valid for write as it's a new inode.
287+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFIFO as _ , 0 ) } ;
288+ bindings:: S_IFIFO
289+ }
290+ INodeType :: Sock => {
291+ // SAFETY: `inode` is valid for write as it's a new inode.
292+ unsafe { bindings:: init_special_inode ( inode, bindings:: S_IFSOCK as _ , 0 ) } ;
293+ bindings:: S_IFSOCK
294+ }
295+ INodeType :: Chr ( major, minor) => {
296+ // SAFETY: `inode` is valid for write as it's a new inode.
297+ unsafe {
298+ bindings:: init_special_inode (
299+ inode,
300+ bindings:: S_IFCHR as _ ,
301+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
302+ )
303+ } ;
304+ bindings:: S_IFCHR
305+ }
306+ INodeType :: Blk ( 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_IFBLK as _ ,
312+ bindings:: MKDEV ( major, minor & bindings:: MINORMASK ) ,
313+ )
314+ } ;
315+ bindings:: S_IFBLK
316+ }
272317 } ;
273318
274319 inode. i_mode = ( params. mode & 0o777 ) | u16:: try_from ( mode) ?;
@@ -303,11 +348,26 @@ impl<T: FileSystem + ?Sized> Drop for NewINode<T> {
303348/// The type of the inode.
304349#[ derive( Copy , Clone ) ]
305350pub enum INodeType {
351+ /// Named pipe (first-in, first-out) type.
352+ Fifo ,
353+
354+ /// Character device type.
355+ Chr ( u32 , u32 ) ,
356+
306357 /// Directory type.
307358 Dir ,
308359
360+ /// Block device type.
361+ Blk ( u32 , u32 ) ,
362+
309363 /// Regular file type.
310364 Reg ,
365+
366+ /// Symbolic link type.
367+ Lnk ,
368+
369+ /// Named unix-domain socket type.
370+ Sock ,
311371}
312372
313373/// Required inode parameters.
@@ -717,6 +777,34 @@ impl<T: FileSystem + ?Sized> Tables<T> {
717777 }
718778 }
719779
780+ const LNK_INODE_OPERATIONS : bindings:: inode_operations = bindings:: inode_operations {
781+ lookup : None ,
782+ get_link : Some ( bindings:: page_get_link) ,
783+ permission : None ,
784+ get_inode_acl : None ,
785+ readlink : None ,
786+ create : None ,
787+ link : None ,
788+ unlink : None ,
789+ symlink : None ,
790+ mkdir : None ,
791+ rmdir : None ,
792+ mknod : None ,
793+ rename : None ,
794+ setattr : None ,
795+ getattr : None ,
796+ listxattr : None ,
797+ fiemap : None ,
798+ update_time : None ,
799+ atomic_open : None ,
800+ tmpfile : None ,
801+ get_acl : None ,
802+ set_acl : None ,
803+ fileattr_set : None ,
804+ fileattr_get : None ,
805+ get_offset_ctx : None ,
806+ } ;
807+
720808 const FILE_ADDRESS_SPACE_OPERATIONS : bindings:: address_space_operations =
721809 bindings:: address_space_operations {
722810 writepage : None ,
0 commit comments