@@ -110,7 +110,7 @@ impl Inode {
110110 get_block_cache ( new_inode_block_id as usize , Arc :: clone ( & self . block_device ) )
111111 . lock ( )
112112 . modify ( new_inode_block_offset, |new_inode : & mut DiskInode | {
113- new_inode. initialize ( DiskInodeType :: File ) ;
113+ new_inode. initialize ( DiskInodeType :: File , new_inode_id ) ;
114114 } ) ;
115115 self . modify_disk_inode ( |root_inode| {
116116 // append file in the dirent
@@ -183,4 +183,93 @@ impl Inode {
183183 } ) ;
184184 block_cache_sync_all ( ) ;
185185 }
186+ /// is dir?
187+ pub fn is_dir ( & self ) -> bool {
188+ self . read_disk_inode ( |disk_inode| {
189+ disk_inode. is_dir ( )
190+ } )
191+ }
192+ /// is file?
193+ pub fn is_file ( & self ) -> bool {
194+ self . read_disk_inode ( |disk_inode|{
195+ disk_inode. is_file ( )
196+ } )
197+ }
198+ /// get nlink
199+ pub fn nlink ( & self , inode_id : u32 ) -> u32 {
200+ let _fs = self . fs . lock ( ) ;
201+ self . read_disk_inode ( |disk_inode| {
202+ let file_count = ( disk_inode. size as usize ) / DIRENT_SZ ;
203+ let mut dirent = DirEntry :: empty ( ) ;
204+ let mut count = 0 ;
205+ for i in 0 ..file_count {
206+ assert_eq ! (
207+ disk_inode. read_at( DIRENT_SZ * i, dirent. as_bytes_mut( ) , & self . block_device, ) ,
208+ DIRENT_SZ ,
209+ ) ;
210+ if dirent. inode_id ( ) == inode_id {
211+ count += 1 ;
212+ }
213+ }
214+ count
215+ } )
216+ }
217+ /// ino
218+ pub fn ino ( & self ) -> u32 {
219+ self . read_disk_inode ( |disk_inode| {
220+ disk_inode. ino ( )
221+ } )
222+ }
223+ /// Link new inode to current inode
224+ pub fn linkat ( & self , old_name : & str , new_name : & str ) -> isize {
225+ if let Some ( inode_id) = self . read_disk_inode ( |disk_inode| {
226+ self . find_inode_id ( old_name, disk_inode)
227+ } ) {
228+ let mut fs = self . fs . lock ( ) ;
229+ let ( new_inode_block_id, new_inode_block_offset) = fs. get_disk_inode_pos ( inode_id as u32 ) ;
230+ get_block_cache ( new_inode_block_id as usize , Arc :: clone ( & self . block_device ) )
231+ . lock ( )
232+ . modify ( new_inode_block_offset, |new_inode : & mut DiskInode | {
233+ new_inode. initialize ( DiskInodeType :: File , inode_id) ;
234+ } ) ;
235+ self . modify_disk_inode ( |disk_inode| {
236+ let file_count = ( disk_inode. size as usize ) / DIRENT_SZ ;
237+ let new_size = ( file_count + 1 ) * DIRENT_SZ ;
238+ // increase size
239+ self . increase_size ( new_size as u32 , disk_inode, & mut fs) ;
240+ let dirent = DirEntry :: new ( new_name, inode_id as u32 ) ;
241+ disk_inode. write_at (
242+ file_count * DIRENT_SZ ,
243+ dirent. as_bytes ( ) ,
244+ & self . block_device ,
245+ ) ;
246+ } ) ;
247+ block_cache_sync_all ( ) ;
248+ 0
249+ } else {
250+ -1
251+ }
252+ }
253+ /// Un Link inode
254+ pub fn unlinkat ( & self , name : & str ) -> isize {
255+ self . modify_disk_inode ( |root_inode| {
256+ let file_count = ( root_inode. size as usize ) / DIRENT_SZ ;
257+ let mut dirent = DirEntry :: empty ( ) ;
258+ for i in 0 ..file_count {
259+ assert_eq ! (
260+ root_inode. read_at( DIRENT_SZ * i, dirent. as_bytes_mut( ) , & self . block_device, ) ,
261+ DIRENT_SZ ,
262+ ) ;
263+ if dirent. name ( ) == name {
264+ root_inode. write_at (
265+ i * DIRENT_SZ ,
266+ DirEntry :: empty ( ) . as_bytes ( ) ,
267+ & self . block_device
268+ ) ;
269+ return 0 ;
270+ }
271+ }
272+ -1
273+ } )
274+ }
186275}
0 commit comments