11use core:: sync:: atomic:: { AtomicU32 , AtomicU64 , Ordering } ;
22
3- use crate :: kernel:: mem:: { PageCache , PageCacheBackend } ;
3+ use crate :: kernel:: mem:: { CachePage , CachePageStream , PageCache , PageCacheBackend } ;
44use crate :: {
55 io:: { Buffer , ByteBuffer , Stream } ,
66 kernel:: {
@@ -83,7 +83,7 @@ impl Vfs for Ext4Fs {
8383 }
8484
8585 fn is_read_only ( & self ) -> bool {
86- true
86+ false
8787 }
8888}
8989
@@ -257,12 +257,12 @@ impl FileInode {
257257}
258258
259259impl PageCacheBackend for FileInode {
260- fn read_page ( & self , page : & mut crate :: kernel :: mem :: CachePage , offset : usize ) -> KResult < usize > {
260+ fn read_page ( & self , page : & mut CachePage , offset : usize ) -> KResult < usize > {
261261 self . read_direct ( page, offset)
262262 }
263263
264- fn write_page ( & self , page : & crate :: kernel :: mem :: CachePage , offset : usize ) -> KResult < usize > {
265- todo ! ( )
264+ fn write_page ( & self , page : & mut CachePageStream , offset : usize ) -> KResult < usize > {
265+ self . write_direct ( page , offset )
266266 }
267267
268268 fn size ( & self ) -> usize {
@@ -296,12 +296,6 @@ impl Inode for FileInode {
296296 fn write ( & self , stream : & mut dyn Stream , offset : WriteOffset ) -> KResult < usize > {
297297 let _lock = Task :: block_on ( self . rwsem . write ( ) ) ;
298298
299- let vfs = self . vfs . upgrade ( ) . ok_or ( EIO ) ?;
300- let ext4fs = vfs. as_any ( ) . downcast_ref :: < Ext4Fs > ( ) . unwrap ( ) ;
301-
302- let mut temp_buf = vec ! [ 0u8 ; 4096 ] ;
303- let mut total_written = 0 ;
304-
305299 let mut store_new_end = None ;
306300 let offset = match offset {
307301 WriteOffset :: Position ( offset) => offset,
@@ -312,6 +306,31 @@ impl Inode for FileInode {
312306 }
313307 } ;
314308
309+ let total_written = Task :: block_on ( self . page_cache . write ( stream, offset) ) ?;
310+ let cursor_end = offset + total_written;
311+ if let Some ( store_end) = store_new_end {
312+ * store_end = cursor_end;
313+ }
314+
315+ let mtime = Instant :: now ( ) ;
316+ * self . mtime . lock ( ) = mtime;
317+ self . size . store ( cursor_end as u64 , Ordering :: Relaxed ) ;
318+
319+ // TODO: change this with some update strategy such as LRU
320+ let _ = Task :: block_on ( self . page_cache . fsync ( ) ) ;
321+
322+ Ok ( total_written)
323+ }
324+
325+ fn write_direct ( & self , stream : & mut dyn Stream , offset : usize ) -> KResult < usize > {
326+ //let _lock = Task::block_on(self.rwsem.write());
327+
328+ let vfs = self . vfs . upgrade ( ) . ok_or ( EIO ) ?;
329+ let ext4fs = vfs. as_any ( ) . downcast_ref :: < Ext4Fs > ( ) . unwrap ( ) ;
330+
331+ let mut temp_buf = vec ! [ 0u8 ; 4096 ] ;
332+ let mut total_written = 0 ;
333+
315334 while let Some ( data) = stream. poll_data ( & mut temp_buf) ? {
316335 let written = ext4fs
317336 . inner
@@ -323,18 +342,10 @@ impl Inode for FileInode {
323342 }
324343 }
325344
326- if let Some ( store_end) = store_new_end {
327- * store_end = offset + total_written;
328- }
329- let mtime = Instant :: now ( ) ;
330- * self . mtime . lock ( ) = mtime;
331- let new_size = ( offset + total_written) as u64 ;
332- self . size
333- . store ( offset as u64 + total_written as u64 , Ordering :: Relaxed ) ;
334345 ext4fs. modify_inode_stat (
335346 self . ino as u32 ,
336- Some ( new_size ) ,
337- mtime. since_epoch ( ) . as_secs ( ) as u32 ,
347+ Some ( self . size ( ) as u64 ) ,
348+ self . mtime . lock ( ) . since_epoch ( ) . as_secs ( ) as u32 ,
338349 ) ;
339350
340351 Ok ( total_written)
0 commit comments