@@ -443,27 +443,17 @@ impl WasiOutputStream for VfsOutputStream {
443443 return Ok ( ( ) ) ;
444444 }
445445
446- let mut guard = self . node . write ( ) . unwrap ( ) ;
447- match & mut guard. kind {
448- VfsNodeKind :: File { content } => {
449- let offset = self . offset . load ( Ordering :: SeqCst ) as usize ;
450- let nbyte = buf. len ( ) ;
451- let new_end = offset. saturating_add ( nbyte) ;
452- let old_len = content. len ( ) ;
453-
454- if new_end > old_len {
455- let growth = new_end - old_len;
456- self . limiter
457- . grow ( growth)
458- . map_err ( |_| StreamError :: Trap ( ErrorCode :: InsufficientMemory . into ( ) ) ) ?;
459- content. resize ( new_end, 0 ) ;
460- }
461-
462- content[ offset..offset + nbyte] . copy_from_slice ( & buf) ;
463- self . offset . fetch_add ( nbyte as u64 , Ordering :: SeqCst ) ;
446+ match perform_write (
447+ & self . node ,
448+ self . offset . load ( Ordering :: SeqCst ) as usize ,
449+ & buf,
450+ & self . limiter ,
451+ ) {
452+ Ok ( nbyte) => {
453+ self . offset . fetch_add ( nbyte, Ordering :: SeqCst ) ;
464454 Ok ( ( ) )
465455 }
466- VfsNodeKind :: Directory { .. } => Err ( StreamError :: Trap ( ErrorCode :: IsDirectory . into ( ) ) ) ,
456+ Err ( e ) => Err ( StreamError :: Trap ( e . into ( ) ) ) ,
467457 }
468458 }
469459
@@ -734,43 +724,7 @@ impl<'a> filesystem::types::HostDescriptor for VfsCtxView<'a> {
734724 } ;
735725 }
736726
737- let mut guard = node. write ( ) . unwrap ( ) ;
738- match & mut guard. kind {
739- VfsNodeKind :: File { content } => {
740- let offset = offset as usize ;
741- let nbyte = buffer. len ( ) ;
742-
743- // Calculate new file size after write
744- let new_end = offset. saturating_add ( nbyte) ;
745- let old_len = content. len ( ) ;
746-
747- // Per POSIX: "On a regular file, if the position of the last byte written
748- // is greater than or equal to the length of the file, the length of the
749- // file shall be set to this position plus one."
750- if new_end > old_len {
751- let growth = new_end - old_len;
752-
753- // Check memory limits before growing
754- self . vfs_state
755- . limiter
756- . grow ( growth)
757- . map_err ( |_| FsError :: trap ( ErrorCode :: InsufficientMemory ) ) ?;
758-
759- // Extend the file with zeros up to offset if necessary
760- content. resize ( new_end, 0 ) ;
761- }
762-
763- // Per POSIX: "The write() function shall attempt to write nbyte bytes from
764- // the buffer pointed to by buf to the file associated with the open file
765- // descriptor"
766- // "the actual writing of data shall proceed from the position in the file
767- // indicated by the file offset"
768- content[ offset..offset + nbyte] . copy_from_slice ( & buffer) ;
769-
770- Ok ( nbyte as Filesize )
771- }
772- VfsNodeKind :: Directory { .. } => Err ( FsError :: trap ( ErrorCode :: IsDirectory ) ) ,
773- }
727+ perform_write ( & node, offset as usize , & buffer, & self . vfs_state . limiter )
774728 }
775729
776730 async fn read_directory (
@@ -1196,6 +1150,35 @@ impl<'a> filesystem::preopens::Host for VfsCtxView<'a> {
11961150 }
11971151}
11981152
1153+ /// Helper function to perform write operation
1154+ fn perform_write (
1155+ node : & SharedVfsNode ,
1156+ offset : usize ,
1157+ buffer : & [ u8 ] ,
1158+ limiter : & Limiter ,
1159+ ) -> FsResult < Filesize > {
1160+ let mut guard = node. write ( ) . unwrap ( ) ;
1161+ match & mut guard. kind {
1162+ VfsNodeKind :: File { content } => {
1163+ let nbyte = buffer. len ( ) ;
1164+ let new_end = offset. saturating_add ( nbyte) ;
1165+ let old_len = content. len ( ) ;
1166+
1167+ if new_end > old_len {
1168+ let growth = new_end - old_len;
1169+ limiter
1170+ . grow ( growth)
1171+ . map_err ( |_| FsError :: trap ( ErrorCode :: InsufficientMemory ) ) ?;
1172+ content. resize ( new_end, 0 ) ;
1173+ }
1174+
1175+ content[ offset..offset + nbyte] . copy_from_slice ( buffer) ;
1176+ Ok ( nbyte as Filesize )
1177+ }
1178+ VfsNodeKind :: Directory { .. } => Err ( FsError :: trap ( ErrorCode :: IsDirectory ) ) ,
1179+ }
1180+ }
1181+
11991182/// Extension trait for [`Resource`].
12001183trait ResourceExt {
12011184 /// Resource type.
0 commit comments