From 0fd24ff92e30f34d19d6161641de7b98214c2106 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 2 Mar 2019 23:16:11 +0800 Subject: [PATCH] impl sys_f(data)sync, sys_(f)truncate, sys_(un)link --- kernel/src/fs/file.rs | 19 ++++++++++++- kernel/src/syscall/fs.rs | 57 +++++++++++++++++++++++++++++++++++++-- kernel/src/syscall/mod.rs | 11 ++++---- 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index f10a3af..b599911 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -66,7 +66,24 @@ impl FileHandle { Ok(self.offset) } - pub fn info(&self) -> Result { + pub fn set_len(&mut self, len: u64) -> Result<()> { + if !self.options.write { + return Err(FsError::InvalidParam); // FIXME: => EBADF + } + self.inode.resize(len as usize)?; + Ok(()) + } + + pub fn sync_all(&mut self) -> Result<()> { + self.inode.sync() + } + + pub fn sync_data(&mut self) -> Result<()> { + // TODO: add sync_data to VFS + self.inode.sync() + } + + pub fn metadata(&self) -> Result { self.inode.metadata() } diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 58f5ad3..331a213 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -139,7 +139,7 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult { return Err(SysError::EFAULT); } let file = proc.get_file(fd)?; - let stat = Stat::from(file.info()?); + let stat = Stat::from(file.metadata()?); // TODO: handle symlink unsafe { stat_ptr.write(stat); } Ok(0) @@ -175,6 +175,33 @@ pub fn sys_lseek(fd: usize, offset: i64, whence: u8) -> SysResult { Ok(offset as isize) } +pub fn sys_fsync(fd: usize) -> SysResult { + info!("fsync: fd: {}", fd); + process().get_file(fd)?.sync_all()?; + Ok(0) +} + +pub fn sys_fdatasync(fd: usize) -> SysResult { + info!("fdatasync: fd: {}", fd); + process().get_file(fd)?.sync_data()?; + Ok(0) +} + +pub fn sys_truncate(path: *const u8, len: usize) -> SysResult { + let mut proc = process(); + let path = unsafe { proc.memory_set.check_and_clone_cstr(path) } + .ok_or(SysError::EFAULT)?; + info!("truncate: path: {:?}, len: {}", path, len); + proc.lookup_inode(&path)?.resize(len)?; + Ok(0) +} + +pub fn sys_ftruncate(fd: usize, len: usize) -> SysResult { + info!("ftruncate: fd: {}, len: {}", fd, len); + process().get_file(fd)?.set_len(len as u64)?; + Ok(0) +} + pub fn sys_getdents64(fd: usize, buf: *mut LinuxDirent64, buf_size: usize) -> SysResult { info!("getdents64: fd: {}, ptr: {:?}, buf_size: {}", fd, buf, buf_size); let mut proc = process(); @@ -182,7 +209,7 @@ pub fn sys_getdents64(fd: usize, buf: *mut LinuxDirent64, buf_size: usize) -> Sy return Err(SysError::EFAULT); } let file = proc.get_file(fd)?; - let info = file.info()?; + let info = file.metadata()?; if info.type_ != FileType::Dir { return Err(SysError::ENOTDIR); } @@ -263,6 +290,32 @@ pub fn sys_mkdir(path: *const u8, mode: usize) -> SysResult { Ok(0) } +pub fn sys_link(oldpath: *const u8, newpath: *const u8) -> SysResult { + let mut proc = process(); + let oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath) } + .ok_or(SysError::EFAULT)?; + let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath) } + .ok_or(SysError::EFAULT)?; + info!("link: oldpath: {:?}, newpath: {:?}", oldpath, newpath); + + let (new_dir_path, new_file_name) = split_path(&newpath); + let inode = proc.lookup_inode(&oldpath)?; + let new_dir_inode = proc.lookup_inode(new_dir_path)?; + new_dir_inode.link(new_file_name, &inode)?; + Ok(0) +} + +pub fn sys_unlink(path: *const u8) -> SysResult { + let mut proc = process(); + let path = unsafe { proc.memory_set.check_and_clone_cstr(path) } + .ok_or(SysError::EFAULT)?; + info!("unlink: path: {:?}", path); + + let (dir_path, file_name) = split_path(&path); + let dir_inode = proc.lookup_inode(dir_path)?; + dir_inode.unlink(file_name)?; + Ok(0) +} impl Process { fn get_file(&mut self, fd: usize) -> Result<&mut FileHandle, SysError> { diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index b082cc1..b1a28d9 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -69,15 +69,16 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 061 => sys_wait(args[0], args[1] as *mut i32), // TODO: wait4 062 => sys_kill(args[0]), // 072 => sys_fcntl(), -// 074 => sys_fsync(), -// 076 => sys_trunc(), -// 077 => sys_ftrunc(), + 074 => sys_fsync(args[0]), + 075 => sys_fdatasync(args[0]), + 076 => sys_truncate(args[0] as *const u8, args[1]), + 077 => sys_ftruncate(args[0], args[1]), 079 => sys_getcwd(args[0] as *mut u8, args[1]), 080 => sys_chdir(args[0] as *const u8), 082 => sys_rename(args[0] as *const u8, args[1] as *const u8), 083 => sys_mkdir(args[0] as *const u8, args[1]), -// 086 => sys_link(), -// 087 => sys_unlink(), + 086 => sys_link(args[0] as *const u8, args[1] as *const u8), + 087 => sys_unlink(args[0] as *const u8), 096 => sys_get_time(), // TODO: sys_gettimeofday // 097 => sys_getrlimit(), // 098 => sys_getrusage(),