@@ -84,7 +84,6 @@ impl INode {
8484 let block_size = filesystem. superblock . block_size ( ) ;
8585
8686 let mut progress = 0 ;
87-
8887 let count = core:: cmp:: min ( inode. size_lower as usize - offset, buffer. len ( ) ) ;
8988
9089 while progress < count {
@@ -113,7 +112,43 @@ impl INode {
113112 Ok ( count)
114113 }
115114
116- /// Allocates and appends a new block to the inode.
115+ pub fn write ( & self , offset : usize , buffer : & [ u8 ] ) -> super :: Result < usize > {
116+ let filesystem = self . fs . upgrade ( ) . unwrap ( ) ;
117+ let block_size = filesystem. superblock . block_size ( ) ;
118+
119+ let mut progress = 0 ;
120+ let count = buffer. len ( ) ;
121+
122+ while progress < count {
123+ let block = ( offset + progress) / block_size;
124+ let loc = ( offset + progress) % block_size;
125+
126+ let mut chunk = count - progress;
127+
128+ if chunk > block_size - loc {
129+ chunk = block_size - loc;
130+ }
131+
132+ let mut block_index = self . get_block ( block) . unwrap ( ) as usize ;
133+
134+ if block_index == 0 {
135+ block_index = self . append_block ( ) . unwrap ( ) ;
136+ }
137+
138+ filesystem
139+ . block
140+ . write (
141+ ( block_index * block_size) + loc,
142+ & buffer[ progress..progress + chunk] ,
143+ )
144+ . expect ( "inode: write failed" ) ;
145+
146+ progress += chunk;
147+ }
148+
149+ Ok ( count)
150+ }
151+
117152 pub fn append_block ( & self ) -> Option < usize > {
118153 let fs = self . fs . upgrade ( ) . expect ( "ext2: filesystem was dropped" ) ;
119154 let block_size = fs. superblock . block_size ( ) ;
@@ -215,7 +250,11 @@ impl INode {
215250
216251 {
217252 let mut inode = ext2_inode. inode . write ( ) ;
253+ * * inode = disk:: INode :: default ( ) ;
254+
218255 inode. set_file_type ( typ) ;
256+ inode. set_permissions ( 0o755 ) ;
257+
219258 inode. hl_count += 1 ;
220259 }
221260
@@ -334,6 +373,18 @@ impl INodeInterface for INode {
334373 Ok ( count)
335374 }
336375
376+ fn write_at ( & self , offset : usize , usr_buffer : & [ u8 ] ) -> super :: Result < usize > {
377+ if !self . metadata ( ) ?. is_file ( ) {
378+ return Err ( FileSystemError :: NotSupported ) ;
379+ }
380+
381+ self . write ( offset, usr_buffer)
382+ }
383+
384+ fn truncate ( & self , _size : usize ) -> super :: Result < ( ) > {
385+ Ok ( ( ) )
386+ }
387+
337388 fn touch ( & self , parent : DirCacheItem , name : & str ) -> super :: Result < DirCacheItem > {
338389 let inode = self . make_inode ( name, FileType :: File ) ?;
339390 Ok ( DirEntry :: new ( parent, inode, name. to_string ( ) ) )
0 commit comments