From 07816d4df5a431c193c251fc1ccf988dd8624faa Mon Sep 17 00:00:00 2001
From: pierrecashon <2938806204@qq.com>
Date: Mon, 24 Mar 2025 16:32:42 +0800
Subject: [PATCH 1/2] add mount,umount,fstat,openat

---
 easy-fs/src/efs.rs             |  6 +++
 easy-fs/src/vfs.rs             | 23 +++++++++
 ext4-test-fuse/src/main.rs     | 11 ++++
 ext4/src/dentry.rs             |  1 +
 ext4/src/fs.rs                 | 21 +++++++-
 ext4/src/inode.rs              | 41 ++++++++++++++-
 os/Makefile                    |  3 ++
 os/src/fs/inode.rs             | 11 ++++
 os/src/main.rs                 |  2 +-
 os/src/syscall/fs.rs           | 91 +++++++++++++++++++++++++++++++---
 os/src/syscall/mod.rs          | 23 +++++++--
 user/src/lib.rs                |  2 +-
 vfs-defs/src/file.rs           |  4 +-
 vfs-defs/src/filesystemtype.rs | 18 +++++++
 vfs-defs/src/inode.rs          |  5 ++
 vfs-defs/src/lib.rs            | 46 ++++++++++++++++-
 16 files changed, 289 insertions(+), 19 deletions(-)

diff --git a/easy-fs/src/efs.rs b/easy-fs/src/efs.rs
index 4482421..c7ef431 100644
--- a/easy-fs/src/efs.rs
+++ b/easy-fs/src/efs.rs
@@ -192,6 +192,12 @@ impl FileSystemType for EfsFsType{
         Ok(root_dentry)
         
     }
+    fn umount(self:Arc<Self>,
+            path:&str,
+            _flags:MountFlags
+        )->SysResult<()> {
+        Ok(())
+    }
 }
 
 ///
diff --git a/easy-fs/src/vfs.rs b/easy-fs/src/vfs.rs
index 4c4dd5a..d7ff161 100644
--- a/easy-fs/src/vfs.rs
+++ b/easy-fs/src/vfs.rs
@@ -37,6 +37,29 @@ impl Inode for EfsInode{
     fn get_meta(&self) -> &InodeMeta {
         &self.meta
     }
+    fn get_attr(&self)->SysResult<vfs_defs::Kstat> {
+        Ok(vfs_defs::Kstat{
+                st_dev: 0,
+    st_ino: 0,
+    st_mode: 0,
+    st_nlink: 0,
+    st_uid: 0,
+    st_gid: 0,
+    st_rdev: 0,
+    __pad: 0,
+    st_size: 0,
+    st_blksize: 0,
+    __pad2: 0,
+    st_blocks: 0,
+    st_atime_sec: 0,
+    st_atime_nsec: 0,
+    st_mtime_sec: 0,
+    st_mtime_nsec: 0,
+    st_ctime_sec: 0,
+    st_ctime_nsec: 0,
+    unused: 0,
+        })
+    }
     /// Clear the data in current inode
     fn clear(&self) {
         let (mut inner,mut meta) = self.lock_inner();
diff --git a/ext4-test-fuse/src/main.rs b/ext4-test-fuse/src/main.rs
index b77a665..6d68118 100644
--- a/ext4-test-fuse/src/main.rs
+++ b/ext4-test-fuse/src/main.rs
@@ -100,6 +100,17 @@ fn easy_fs_pack() -> std::io::Result<()> {
             name_with_ext
         })
         .collect();
+   
+    {   let mnt = root_dentry.create("mnt",DiskInodeType::Directory).unwrap();
+        let mut host_file = File::open(format!("{}{}", src_path, "mnt/test_mount")).unwrap();
+        let mut all_data: Vec<u8> = Vec::new();
+        host_file.read_to_end(&mut all_data).unwrap();
+        // create a file in ext4
+        let den =mnt.create("test_mount",DiskInodeType::File).unwrap();
+        let inode = den.get_inode().unwrap().get_meta().ino;
+        // write data to ext4
+        sb.ext4fs.ext4_file_write(inode as u64, 0, all_data.as_slice());
+    }
     for app in apps {
         // load app data from host file system
         println!("{}",app);
diff --git a/ext4/src/dentry.rs b/ext4/src/dentry.rs
index 3f4c4f6..8abeb38 100644
--- a/ext4/src/dentry.rs
+++ b/ext4/src/dentry.rs
@@ -42,6 +42,7 @@ impl Dentry for Ext4Dentry{
             }
         }
         let child_inode = Ext4Inode::new(InodeMeta::new(child_ino.unwrap() as usize, sblock),);
+        child_inode.set_type(_type);
         child_dir.set_inode(Arc::new(child_inode));
         Ok(child_dir)
     }
diff --git a/ext4/src/fs.rs b/ext4/src/fs.rs
index 2714a64..6b5e6ad 100644
--- a/ext4/src/fs.rs
+++ b/ext4/src/fs.rs
@@ -4,7 +4,7 @@ use system_result::SysResult;
 use device::BlockDevice;
 use crate::{dentry::Ext4Dentry, superblock::Ext4Superblock, Ext4Inode};
 use alloc::string::{String,ToString};
-
+const MODULE_LEVEL:log::Level = log::Level::Trace;
 pub struct Ext4ImplFsType{
     inner:FileSystemTypeInner
 }
@@ -33,15 +33,32 @@ impl FileSystemType for Ext4ImplFsType{
         let root_inode = Arc::new(Ext4Inode::new(InodeMeta::new(root_ino, superblock.clone())));
         root_inode.set_type(vfs_defs::DiskInodeType::Directory);
         let root_dentry;
+        let abs_mount_path;
+        let mut path = String::new();
         if parent.is_none(){
             root_dentry = Arc::new(Ext4Dentry::new(DentryInner::new(name.to_string(), superblock.clone(),None)));
+            abs_mount_path = "/";
         }
         else{
+            path = parent.as_ref().unwrap().path()+name;
+            abs_mount_path = path.as_str();
             root_dentry = Arc::new(Ext4Dentry::new(DentryInner::new(name.to_string(), superblock.clone(),Some(Arc::downgrade(&parent.unwrap())))));
         }
+        log_debug!("abs_m_path:{}",abs_mount_path);
         root_dentry.set_inode(root_inode);
         superblock.set_root_dentry(root_dentry.clone());
-        self.add_superblock("/", superblock);
+        self.add_superblock(&abs_mount_path, superblock);
         Ok(root_dentry)
     }
+    fn umount(self:Arc<Self>,
+            path:&str,
+            _flags:vfs_defs::MountFlags
+        )->SysResult<()> {
+        let r = self.remove_superblock(path);
+        log_debug!("umount_path:{}",path);
+        if let Err(e) = r{
+            return Err(e);
+        }
+        Ok(())
+    }
 }
\ No newline at end of file
diff --git a/ext4/src/inode.rs b/ext4/src/inode.rs
index a5e37d2..63bbff4 100644
--- a/ext4/src/inode.rs
+++ b/ext4/src/inode.rs
@@ -1,6 +1,9 @@
-use vfs_defs::{Inode,InodeMeta};
+use ext4_rs::Ext4Error;
+use vfs_defs::{Inode,InodeMeta, Kstat};
 use super::Ext4Superblock;
 use system_result::SysError;
+use ext4_rs::Errno;
+const MODULE_LEVEL:log::Level = log::Level::Trace;
 pub struct Ext4Inode{
     meta:InodeMeta,
 }
@@ -18,6 +21,42 @@ impl Inode for Ext4Inode{
     fn get_meta(&self) -> &InodeMeta {
         &self.meta
     }
+    fn get_attr(&self)->system_result::SysResult<Kstat> {
+        let sb = self.get_meta().superblock.upgrade().unwrap().downcast_arc::<Ext4Superblock>().map_err(|_| SysError::ENOENT)?;
+        let r = sb.ext4fs.fuse_getattr(self.get_meta().ino as u64);
+        if let Err(e) = r{
+            let err = match e.error(){
+                Errno::ENOENT=>SysError::ENOENT,
+                _ => SysError::EINVAL,
+            };
+            Err(err)
+        }
+        else{
+            let attr = r.unwrap();
+            Ok(Kstat{
+                st_dev: 0,
+                st_ino: attr.ino,
+                st_mode: 0,
+                st_nlink: attr.nlink,
+                st_uid: attr.uid,
+                st_gid: attr.gid,
+                st_rdev: attr.rdev as u64,
+                __pad: 0,
+                st_size: attr.size,
+                st_blksize: attr.blksize,
+                __pad2: 0,
+                st_blocks: attr.blocks,
+                st_atime_sec: attr.atime as u64,
+                st_atime_nsec: attr.atime as u64,
+                st_mtime_sec: attr.mtime as u64,
+                st_mtime_nsec: attr.mtime as u64,
+                st_ctime_sec: attr.ctime as u64,
+                st_ctime_nsec: attr.ctime as u64,
+                unused: 0,
+            })
+        }
+
+    }
     fn load_from_disk(&self) {
         
     }
diff --git a/os/Makefile b/os/Makefile
index 75f671a..6a3c8d9 100644
--- a/os/Makefile
+++ b/os/Makefile
@@ -161,6 +161,9 @@ debug: build
 gdbserver: build
 	@$(QEMU_EXEC) -s -S
 
+test-gdbserver: testbuild
+	@$(QEMU_EXEC) -s -S
+
 gdbclient:
 	@riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'
 
diff --git a/os/src/fs/inode.rs b/os/src/fs/inode.rs
index 4d789f5..cd8c201 100644
--- a/os/src/fs/inode.rs
+++ b/os/src/fs/inode.rs
@@ -197,6 +197,17 @@ fn path_to_dirent_(path:&str,
     }
     while let Some(new_path) = skipelem(current,name){
         current = new_path;
+        if name == "."{
+            continue;
+        }
+        if name == ".."{
+            if let Some(father) = dentry.get_father(){
+                dentry = father;
+                continue;
+            }else{
+                return None;
+            }
+        }
         if to_father && current.len() == 0 {
             return Some(dentry);
         }
diff --git a/os/src/main.rs b/os/src/main.rs
index 29874bd..91dceb2 100644
--- a/os/src/main.rs
+++ b/os/src/main.rs
@@ -116,7 +116,7 @@ impl ArchInterface for ArchInterfaceImpl {
                 let args = ctx.args();
                 // get system call return value
                 // info!("syscall: {}", ctx[TrapFrameArgs::SYSCALL]);
-                let result = syscall(ctx[TrapFrameArgs::SYSCALL], [args[0], args[1], args[2]]);
+                let result = syscall(ctx[TrapFrameArgs::SYSCALL], [args[0], args[1], args[2],args[3],args[4]]);
                 // cx is changed during sys_exec, so we have to call it again
                 ctx[TrapFrameArgs::RET] = result as usize;
             }
diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs
index 9bed6de..6f3c863 100644
--- a/os/src/syscall/fs.rs
+++ b/os/src/syscall/fs.rs
@@ -1,9 +1,16 @@
 //! File and filesystem-related syscalls
 use crate::fs::open_file;
 use crate::fs::make_pipe;
+use crate::fs::path_to_dentry;
+use crate::fs::path_to_father_dentry;
 use crate::mm::{translated_refmut,translated_byte_buffer, translated_str};
 use crate::task::{current_task, current_user_token};
+use device::BLOCK_DEVICE;
+use vfs_defs::Kstat;
+use vfs_defs::MountFlags;
 use vfs_defs::{OpenFlags,UserBuffer};
+use vfs::FILE_SYSTEMS;
+use alloc::string::String;
 //
 use crate::config::PAGE_SIZE;
 use crate::mm::frame_alloc_more;
@@ -18,6 +25,7 @@ use alloc::sync::Arc;
 use alloc::vec::Vec;
 //
 //const HEAP_MAX: usize = 0;
+pub const AT_FDCWD: isize = -100;
 
 pub fn sys_write(fd: usize, buf: *mut u8, len: usize) -> isize {
     let token = current_user_token();
@@ -59,18 +67,35 @@ pub fn sys_read(fd: usize, buf: *mut u8, len: usize) -> isize {
     }
 }
 
-pub fn sys_open(path: *const u8, flags: u32) -> isize {
+pub fn sys_openat(pfd:isize,path: *const u8, flags: u32,_mode:u32) -> isize {
     let task = current_task().unwrap();
     let token = current_user_token();
     let path = translated_str(token, path);
-    if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) {
-        let mut inner = task.inner_exclusive_access();
-        let fd = inner.alloc_fd();
-        inner.fd_table[fd] = Some(inode);
-        fd as isize
-    } else {
-        -1
+    if path.chars().next() == Some('/') || pfd == AT_FDCWD{
+        if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) {
+            let mut inner = task.inner_exclusive_access();
+            let fd = inner.alloc_fd();
+            inner.fd_table[fd] = Some(inode);
+            return fd as isize;
+        } else {
+            return -1;
+        }
+    }
+    let mut inner = task.inner_exclusive_access();
+    if let Some(file) = &inner.fd_table[pfd as usize]{
+        let father_path = file.get_dentry().path();
+        let child_path = father_path+&path;
+        if let Some(inode) = open_file(child_path.as_str(), OpenFlags::from_bits(flags).unwrap()) {
+            let fd = inner.alloc_fd();
+            inner.fd_table[fd] = Some(inode);
+            return fd as isize;
+        } else {
+            return -1;
+        }
+
     }
+    return -1;
+
 }
 
 pub fn sys_close(fd: usize) -> isize {
@@ -195,4 +220,54 @@ pub fn sys_brk(mut new_brk:  usize) -> isize {
 
         0
     }
+}
+
+pub fn sys_mount(_special:*const u8,dir:*const u8,fstype:*const u8,_flags:u32,_data:*const u8)->isize{
+    let token = current_user_token();
+    let dir = translated_str(token, dir);
+    let fstype = translated_str(token, fstype);
+    let ext4fstype = FILE_SYSTEMS.lock().find_fs(&String::from("Ext4")).unwrap();
+    if fstype == "vfat"{
+        let mut name = String::new();
+        let parent = path_to_father_dentry(dir.as_str(), &mut name);
+        let device = BLOCK_DEVICE.get().unwrap().clone();
+        let r = ext4fstype.mount(name.as_str(), parent, MountFlags::empty(), Some(device));
+        if r.is_err(){
+            return -1;
+        }
+        return 0;
+    }
+    else{
+        return -1;
+    }
+}
+
+pub fn sys_umount(special:*const u8,_flags:u32)->isize{
+    let token = current_user_token();
+    let path = translated_str(token, special);
+    let ext4fstype = FILE_SYSTEMS.lock().find_fs(&String::from("Ext4")).unwrap();
+    if let Some(dentry) = path_to_dentry(&path){
+        if let Err(_e) = ext4fstype.umount(dentry.path().as_str(), MountFlags::empty()){
+            return -1;
+        }
+        return 0;
+    }
+    return -1;
+
+}
+
+pub fn sys_fstat(fd:usize,kst:*mut Kstat)->isize{
+    let token = current_user_token();
+    let task = current_task().unwrap();
+    if let Some(file) = task.inner_exclusive_access().fd_table[fd].clone() {
+        let r = file.get_dentry().get_inode().unwrap().get_attr();
+        if r.is_err(){
+            return -1;
+        }    
+        let kst = translated_refmut(token, kst);
+        let attr = r.unwrap();
+        *kst = attr;
+        return 0;
+    }
+    return -1;
 }
\ No newline at end of file
diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs
index 54c69b5..4ce9e53 100644
--- a/os/src/syscall/mod.rs
+++ b/os/src/syscall/mod.rs
@@ -13,11 +13,14 @@ const SYSCALL_CHDIR: usize = 9;
 const SYSCALL_UNLINK: usize = 18;
 const SYSCALL_LINK: usize = 19;
 const SYSCALL_MKDIR: usize = 20;
-const SYSCALL_OPEN: usize = 56;
+const SYSCALL_UMOUNT: usize = 39;
+const SYSCALL_MOUNT: usize = 40;
+const SYSCALL_OPENAT: usize = 56;
 const SYSCALL_CLOSE: usize = 57;
 const SYSCALL_PIPE: usize = 59;
 const SYSCALL_READ: usize = 63;
 const SYSCALL_WRITE: usize = 64;
+const SYSCALL_FSTAT: usize = 80;
 const SYSCALL_EXIT: usize = 93;
 const SYSCALL_YIELD: usize = 124;
 const SYSCALL_GET_TIME: usize = 169;
@@ -35,7 +38,7 @@ use process::*;
 const MODULE_LEVEL:log::Level = log::Level::Trace;
 
 /// handle syscall exception with `syscall_id` and other arguments
-pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
+pub fn syscall(syscall_id: usize, args: [usize; 5]) -> isize {
    // println!("syscallid:{}",syscall_id);
     let mut result:isize = 0;
     match syscall_id {
@@ -55,8 +58,8 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
             result = sys_mkdir(args[0] as *const u8);
             log_debug!("syscall_mkdir result:{}",result);
         }
-        SYSCALL_OPEN => {
-            result = sys_open(args[0] as *const u8, args[1] as u32);
+        SYSCALL_OPENAT => {
+            result = sys_openat(args[0] as isize,args[1] as *const u8, args[2] as u32,args[3] as u32);
             log_debug!("syscall_open result:{}",result);
         },
         SYSCALL_CLOSE => {
@@ -108,6 +111,18 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
             result = sys_brk(args[0]);
             log_debug!("syscall_pipe result:{}",result);
         },
+        SYSCALL_MOUNT => {
+            result = sys_mount(args[0] as *const u8,args[1] as *const u8,args[2] as *const u8,args[3] as u32,args[4] as *const u8,);
+            log_debug!("syscall_mount result:{}",result);
+        },
+        SYSCALL_UMOUNT => {
+            result = sys_umount(args[0] as *const u8,args[1] as u32);
+            log_debug!("syscall_umount result:{}",result);
+        },
+        SYSCALL_FSTAT => {
+            result = sys_fstat(args[0],args[1] as *mut vfs_defs::Kstat);
+            log_debug!("syscall_umount result:{}",result);
+        },
         _ => panic!("Unsupported syscall_id: {}", syscall_id),
     }
     result
diff --git a/user/src/lib.rs b/user/src/lib.rs
index fc926b3..5a71876 100644
--- a/user/src/lib.rs
+++ b/user/src/lib.rs
@@ -78,7 +78,7 @@ bitflags! {
         const RDONLY = 0;
         const WRONLY = 1 << 0;
         const RDWR = 1 << 1;
-        const CREATE = 1 << 9;
+        const CREATE = 1 << 6;
         const TRUNC = 1 << 10;
     }
 }
diff --git a/vfs-defs/src/file.rs b/vfs-defs/src/file.rs
index 65f9fb2..aac9504 100644
--- a/vfs-defs/src/file.rs
+++ b/vfs-defs/src/file.rs
@@ -15,9 +15,11 @@ bitflags! {
         ///Read & Write
         const RDWR = 1 << 1;
         ///Allow create
-        const CREATE = 1 << 9;
+        const CREATE = 1 << 6;
         ///Clear file and return an empty one
         const TRUNC = 1 << 10;
+        ///
+        const DIRECTORY = 1 << 16;
     }
 }
 impl OpenFlags {
diff --git a/vfs-defs/src/filesystemtype.rs b/vfs-defs/src/filesystemtype.rs
index 3ae4dc6..4bd4164 100644
--- a/vfs-defs/src/filesystemtype.rs
+++ b/vfs-defs/src/filesystemtype.rs
@@ -44,10 +44,28 @@ pub trait FileSystemType: Send + Sync  {
             unimplemented!()
     }
     ///
+    fn umount(self:Arc<Self>,
+        path:&str,
+        _flags:MountFlags
+    )->SysResult<()>;
+    ///
     fn add_superblock(&self, abs_mount_path: &str, superblock: Arc<dyn SuperBlock>) {
         self.get_inner()
             .superblocks
             .lock()
             .insert(abs_mount_path.to_string(), superblock);
     }
+    ///
+    fn remove_superblock(&self,abs_mount_path: &str)->SysResult<()>{
+        if let Some(_sb) = self.get_inner()
+            .superblocks
+            .lock()
+            .remove(abs_mount_path){
+            Ok(())
+        }
+        else{
+            Err(SysError::ENOENT)
+        }
+        
+    }
 }
diff --git a/vfs-defs/src/inode.rs b/vfs-defs/src/inode.rs
index fab6781..4fae35e 100644
--- a/vfs-defs/src/inode.rs
+++ b/vfs-defs/src/inode.rs
@@ -1,6 +1,9 @@
 use spin::{Mutex, MutexGuard};
 use alloc::sync::{Weak,Arc};
 use downcast_rs::{impl_downcast, DowncastSync};
+use system_result::SysResult;
+use crate::Kstat;
+
 use super::SuperBlock;
 /// Type of a disk inode
 #[derive(Clone, Copy)]
@@ -74,6 +77,8 @@ pub trait Inode: Send + Sync+ DowncastSync {
     ///
     fn get_meta(&self) -> &InodeMeta;
     ///
+    fn get_attr(&self)->SysResult<Kstat>;
+    ///
     fn get_size(&self) -> u32 {//这要改
         self.get_meta().inner.lock().size
     }
diff --git a/vfs-defs/src/lib.rs b/vfs-defs/src/lib.rs
index 66300aa..ad11d7b 100644
--- a/vfs-defs/src/lib.rs
+++ b/vfs-defs/src/lib.rs
@@ -13,4 +13,48 @@ pub use filesystemtype::{FileSystemType,FileSystemTypeInner,MountFlags};
 pub use dentry::{Dentry,DentryInner,DentryState};
 pub use superblock::{SuperBlock,SuperBlockInner};
 pub use inode::{Inode,InodeMeta,InodeMetaInner,DiskInodeType,InodeState};
-pub use file::{File,FileInner,OpenFlags,UserBuffer,UserBufferIterator};
\ No newline at end of file
+pub use file::{File,FileInner,OpenFlags,UserBuffer,UserBufferIterator};
+
+#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
+#[repr(C)]
+///
+pub struct Kstat {
+    ///
+    pub st_dev: u64,
+    ///
+    pub st_ino: u64,
+    ///
+    pub st_mode: u32,
+    ///
+    pub st_nlink: u32,
+    ///
+    pub st_uid: u32,
+    ///
+    pub st_gid: u32,
+    ///
+    pub st_rdev: u64,
+    ///
+    pub __pad: u64,
+    ///
+    pub st_size: u64,
+    ///
+    pub st_blksize: u32,
+    ///
+    pub __pad2: u32,
+    ///
+    pub st_blocks: u64,
+    ///
+    pub st_atime_sec: u64,
+    ///
+    pub st_atime_nsec: u64,
+    ///
+    pub st_mtime_sec: u64,
+    ///
+    pub st_mtime_nsec: u64,
+    ///
+    pub st_ctime_sec: u64,
+    ///
+    pub st_ctime_nsec: u64,
+    ///
+    pub unused: u64,
+}
\ No newline at end of file
-- 
GitLab


From b028751cee7432d5a221384482b0823e79fdec21 Mon Sep 17 00:00:00 2001
From: pierrecashon <2938806204@qq.com>
Date: Mon, 24 Mar 2025 20:48:36 +0800
Subject: [PATCH 2/2] =?UTF-8?q?=E6=B6=88=E9=99=A4=E5=86=B2=E7=AA=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 os/src/syscall/fs.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs
index 6f3c863..55db4a5 100644
--- a/os/src/syscall/fs.rs
+++ b/os/src/syscall/fs.rs
@@ -5,12 +5,12 @@ use crate::fs::path_to_dentry;
 use crate::fs::path_to_father_dentry;
 use crate::mm::{translated_refmut,translated_byte_buffer, translated_str};
 use crate::task::{current_task, current_user_token};
+use alloc::string::String;
 use device::BLOCK_DEVICE;
 use vfs_defs::Kstat;
 use vfs_defs::MountFlags;
 use vfs_defs::{OpenFlags,UserBuffer};
 use vfs::FILE_SYSTEMS;
-use alloc::string::String;
 //
 use crate::config::PAGE_SIZE;
 use crate::mm::frame_alloc_more;
@@ -23,6 +23,7 @@ use crate::mm::MapType;
 use arch::addr::{PhysPage, VirtAddr, VirtPage};
 use alloc::sync::Arc;
 use alloc::vec::Vec;
+use core::ptr;
 //
 //const HEAP_MAX: usize = 0;
 pub const AT_FDCWD: isize = -100;
-- 
GitLab