77 * See the Mulan PSL v2 for more details.
88 */
99
10+ use alloc:: string:: String ;
1011use alloc:: sync:: Arc ;
1112use core:: {
12- ffi:: { c_char, c_int, c_long, c_void, CStr } ,
13+ ffi:: { c_char, c_int, c_long, c_ulong , c_void, CStr } ,
1314 str,
1415} ;
1516
16- use ruxfs:: { api:: FileType , fops:: lookup, FilePerm } ;
17+ use ruxfs:: { api:: FileType , fops:: lookup, FilePerm , MountPoint } ;
1718
1819use axerrno:: { LinuxError , LinuxResult } ;
1920use axio:: { Error , SeekFrom } ;
@@ -23,7 +24,7 @@ use ruxfs::{
2324 AbsPath , DirEntry , Directory , File , RelPath ,
2425} ;
2526
26- use crate :: ctypes;
27+ use crate :: { ctypes, utils :: char_ptr_to_str } ;
2728use ruxtask:: fs:: { add_file_like, get_file_like, get_umask} ;
2829
2930use super :: stdio:: { Stdin , Stdout } ;
@@ -256,6 +257,12 @@ pub unsafe fn sys_newfstatat(
256257 }
257258 let node = fops:: lookup( & path) ?;
258259 let st = RuxStat :: from( node. get_attr( ) ?) ;
260+
261+ // TODO: remove this initialization when fields are fully implemented
262+ unsafe {
263+ core:: ptr:: write_bytes( kst, 0 , 1 ) ;
264+ }
265+
259266 unsafe {
260267 ( * kst) . st_dev = st. st_dev;
261268 ( * kst) . st_ino = st. st_ino;
@@ -278,7 +285,7 @@ pub fn sys_getcwd(buf: *mut c_char, size: usize) -> c_int {
278285 if buf. is_null( ) {
279286 return Err ( LinuxError :: EINVAL ) ;
280287 }
281- let dst = unsafe { core:: slice:: from_raw_parts_mut( buf as * mut u8 , size as _) } ;
288+ let dst: & mut [ u8 ] = unsafe { core:: slice:: from_raw_parts_mut( buf as _ , size as _) } ;
282289 let cwd = fops:: current_dir( ) ?;
283290 let cwd = cwd. as_bytes( ) ;
284291 if cwd. len( ) < size {
@@ -547,7 +554,7 @@ pub unsafe fn sys_getdents64(fd: c_int, dirp: *mut LinuxDirent64, count: ctypes:
547554
548555 let name = entry. name_as_bytes( ) ;
549556 let name_len = name. len( ) ;
550- let entry_size = DIRENT64_FIXED_SIZE + name_len + 1 ;
557+ let entry_size = ( DIRENT64_FIXED_SIZE + name_len + 1 + 7 ) & ! 7 ; // align to 8 bytes
551558
552559 // buf not big enough to hold the entry
553560 if written + entry_size > count {
@@ -562,7 +569,7 @@ pub unsafe fn sys_getdents64(fd: c_int, dirp: *mut LinuxDirent64, count: ctypes:
562569 unsafe { & mut * ( buf. as_mut_ptr( ) . add( written) as * mut LinuxDirent64 ) } ;
563570 // set fixed-size fields
564571 dirent. d_ino = 1 ;
565- dirent. d_off = offset as i64 ;
572+ dirent. d_off = ( offset + 1 ) as i64 ;
566573 dirent. d_reclen = entry_size as u16 ;
567574 dirent. d_type = entry. entry_type( ) as u8 ;
568575 // set file name
@@ -632,6 +639,85 @@ pub fn sys_chdir(path: *const c_char) -> c_int {
632639 } )
633640}
634641
642+ pub const MS_NODEV : u32 = 2 ;
643+ pub const MS_NOSUID : u32 = 4 ;
644+
645+ /// umount a filesystem at a specific location in the filesystem tree
646+ pub fn sys_umount2 ( target : * const c_char , flags : c_int ) -> c_int {
647+ info ! (
648+ "sys_umount2 <= target: {:?}, flags: {:#x}" ,
649+ char_ptr_to_str( target) ,
650+ flags
651+ ) ;
652+ syscall_body ! ( sys_umount2, {
653+ let target = char_ptr_to_str( target) ?;
654+ let dir = ruxtask:: current( )
655+ . fs
656+ . lock( )
657+ . as_mut( )
658+ . unwrap( )
659+ . root_dir
660+ . clone( ) ;
661+ dir. umount( & AbsPath :: new( target) ) ;
662+ Ok ( 0 )
663+ } )
664+ }
665+
666+ /// mount a filesystem at a specific location in the filesystem tree
667+ pub fn sys_mount (
668+ source : * const c_char ,
669+ raw_target : * const c_char ,
670+ filesystemtype : * const c_char ,
671+ mountflags : c_ulong ,
672+ data : * const c_void ,
673+ ) -> c_int {
674+ info ! (
675+ "sys_mount <= source: {:?}, target: {:?}, filesystemtype: {:?}, mountflags: {:#x}, data: {:p}" ,
676+ char_ptr_to_str( source) ,
677+ char_ptr_to_str( raw_target) ,
678+ char_ptr_to_str( filesystemtype) ,
679+ mountflags,
680+ data
681+ ) ;
682+ syscall_body ! ( sys_mount, {
683+ let f1 = MS_NODEV ; //ctypes::MS_NODEV;
684+ let f2 = MS_NOSUID ; //ctypes::MS_NOSUID;
685+ info!(
686+ "mount flags: {:#x}, f1: {:#}, f2: {:#}, flag: {:#}" ,
687+ mountflags,
688+ f1,
689+ f2,
690+ f1 | f2
691+ ) ;
692+ if mountflags != ( f1 | f2) . into( ) {
693+ warn!( "mount flags not supported: {:#x}" , mountflags) ;
694+ }
695+
696+ let target = char_ptr_to_str( raw_target) ?;
697+ let target = String :: from( target) ;
698+ let dir = ruxtask:: current( )
699+ . fs
700+ . lock( )
701+ . as_mut( )
702+ . unwrap( )
703+ . root_dir
704+ . clone( ) ;
705+ let vfsops = ruxfuse:: fuse:: fusefs( ) ;
706+ info!( "mounting filesystem at {}" , target) ;
707+ dir. mount( MountPoint {
708+ path: target,
709+ fs: vfsops,
710+ } ) ?;
711+ Ok ( 0 )
712+ } )
713+ }
714+
715+ /// perform a memory barrier operation.
716+ pub fn sys_membarrier ( cmd : c_int , flags : c_int ) -> c_int {
717+ info ! ( "sys_membarrier <= cmd: {}, flags: {}" , cmd, flags) ;
718+ syscall_body ! ( sys_membarrier, Ok ( 0 ) )
719+ }
720+
635721/// from char_ptr get path_str
636722fn char_ptr_to_path_str < ' a > ( ptr : * const c_char ) -> LinuxResult < & ' a str > {
637723 if ptr. is_null ( ) {
0 commit comments