From 9bffc6af1eef90938af00e666b544d38a11e172c Mon Sep 17 00:00:00 2001 From: lhw2002426 <1466397747@qq.com> Date: Tue, 2 Apr 2024 16:38:09 +0800 Subject: [PATCH] add file flush in sys_close and sys_exit --- api/ruxos_posix_api/src/imp/fd_ops.rs | 15 ++++++++++++++- api/ruxos_posix_api/src/imp/fs.rs | 12 ++++++++++-- api/ruxos_posix_api/src/imp/io_mpx/epoll.rs | 4 ++++ api/ruxos_posix_api/src/imp/net.rs | 5 +++++ api/ruxos_posix_api/src/imp/pipe.rs | 4 ++++ api/ruxos_posix_api/src/imp/pthread/mod.rs | 17 +++++++++++++++++ api/ruxos_posix_api/src/imp/stdio.rs | 9 +++++++++ api/ruxos_posix_api/src/imp/task.rs | 17 +++++++++++++++++ modules/ruxfs/src/dev.rs | 5 +++++ modules/ruxfs/src/fs/fatfs.rs | 7 ++++++- 10 files changed, 91 insertions(+), 4 deletions(-) diff --git a/api/ruxos_posix_api/src/imp/fd_ops.rs b/api/ruxos_posix_api/src/imp/fd_ops.rs index bb5ca1e43..97484cc1b 100644 --- a/api/ruxos_posix_api/src/imp/fd_ops.rs +++ b/api/ruxos_posix_api/src/imp/fd_ops.rs @@ -24,6 +24,7 @@ pub const RUX_FILE_LIMIT: usize = 1024; pub trait FileLike: Send + Sync { fn read(&self, buf: &mut [u8]) -> LinuxResult; fn write(&self, buf: &[u8]) -> LinuxResult; + fn flush(&self) -> LinuxResult; fn stat(&self) -> LinuxResult; fn into_any(self: Arc) -> Arc; fn poll(&self) -> LinuxResult; @@ -61,13 +62,25 @@ pub fn close_file_like(fd: c_int) -> LinuxResult { Ok(()) } +pub fn flush_file_like(fd: c_int) -> LinuxResult { + let f = get_file_like(fd)?; + f.flush() +} + +pub fn fd_table_count() -> usize { + FD_TABLE.read().count() +} + /// Close a file by `fd`. pub fn sys_close(fd: c_int) -> c_int { debug!("sys_close <= {}", fd); if (0..=2).contains(&fd) { return 0; // stdin, stdout, stderr } - syscall_body!(sys_close, close_file_like(fd).map(|_| 0)) + syscall_body!(sys_close, { + get_file_like(fd)?.flush()?; + close_file_like(fd).map(|_| 0) + }) } fn dup_fd(old_fd: c_int) -> LinuxResult { diff --git a/api/ruxos_posix_api/src/imp/fs.rs b/api/ruxos_posix_api/src/imp/fs.rs index 65a539467..b95a32053 100644 --- a/api/ruxos_posix_api/src/imp/fs.rs +++ b/api/ruxos_posix_api/src/imp/fs.rs @@ -51,6 +51,10 @@ impl FileLike for File { Ok(self.inner.lock().write(buf)?) } + fn flush(&self) -> LinuxResult { + Ok(self.inner.lock().flush()?) + } + fn stat(&self) -> LinuxResult { let metadata = self.inner.lock().get_attr()?; let ty = metadata.file_type() as u8; @@ -117,6 +121,10 @@ impl FileLike for Directory { Err(LinuxError::EACCES) } + fn flush(&self) -> LinuxResult { + Ok(()) + } + fn stat(&self) -> LinuxResult { let metadata = self.inner.lock().get_attr()?; let ty = metadata.file_type() as u8; @@ -184,7 +192,7 @@ fn flags_to_options(flags: c_int, _mode: ctypes::mode_t) -> OpenOptions { /// has the maximum number of files open. pub fn sys_open(filename: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int { let filename = char_ptr_to_str(filename); - debug!("sys_open <= {:?} {:#o} {:#o}", filename, flags, mode); + info!("sys_open <= {:?} {:#o} {:#o}", filename, flags, mode); syscall_body!(sys_open, { let options = flags_to_options(flags, mode); let file = ruxfs::fops::File::open(filename?, &options)?; @@ -196,7 +204,7 @@ pub fn sys_open(filename: *const c_char, flags: c_int, mode: ctypes::mode_t) -> pub fn sys_openat(fd: usize, path: *const c_char, flags: c_int, mode: ctypes::mode_t) -> c_int { let path = char_ptr_to_str(path); let fd: c_int = fd as c_int; - debug!("sys_openat <= {}, {:?}, {:#o} {:#o}", fd, path, flags, mode); + info!("sys_openat <= {}, {:?}, {:#o} {:#o}", fd, path, flags, mode); syscall_body!(sys_openat, { let options = flags_to_options(flags, mode); if (flags as u32) & ctypes::O_DIRECTORY != 0 { diff --git a/api/ruxos_posix_api/src/imp/io_mpx/epoll.rs b/api/ruxos_posix_api/src/imp/io_mpx/epoll.rs index 68c7b8a50..c5fa600bf 100644 --- a/api/ruxos_posix_api/src/imp/io_mpx/epoll.rs +++ b/api/ruxos_posix_api/src/imp/io_mpx/epoll.rs @@ -123,6 +123,10 @@ impl FileLike for EpollInstance { Err(LinuxError::ENOSYS) } + fn flush(&self) -> LinuxResult { + Ok(()) + } + fn stat(&self) -> LinuxResult { let st_mode = 0o600u32; // rw------- Ok(ctypes::stat { diff --git a/api/ruxos_posix_api/src/imp/net.rs b/api/ruxos_posix_api/src/imp/net.rs index 56cb8b6a1..3af15aea5 100644 --- a/api/ruxos_posix_api/src/imp/net.rs +++ b/api/ruxos_posix_api/src/imp/net.rs @@ -148,6 +148,11 @@ impl FileLike for Socket { self.send(buf) } + ///TODO + fn flush(&self) -> LinuxResult { + Ok(()) + } + fn stat(&self) -> LinuxResult { // not really implemented let st_mode = 0o140000 | 0o777u32; // S_IFSOCK | rwxrwxrwx diff --git a/api/ruxos_posix_api/src/imp/pipe.rs b/api/ruxos_posix_api/src/imp/pipe.rs index 1638d89c8..1477a7ac9 100644 --- a/api/ruxos_posix_api/src/imp/pipe.rs +++ b/api/ruxos_posix_api/src/imp/pipe.rs @@ -181,6 +181,10 @@ impl FileLike for Pipe { } } + fn flush(&self) -> LinuxResult { + Ok(()) + } + fn stat(&self) -> LinuxResult { let st_mode = 0o10000 | 0o600u32; // S_IFIFO | rw------- Ok(ctypes::stat { diff --git a/api/ruxos_posix_api/src/imp/pthread/mod.rs b/api/ruxos_posix_api/src/imp/pthread/mod.rs index 74ce409c7..40784f33d 100644 --- a/api/ruxos_posix_api/src/imp/pthread/mod.rs +++ b/api/ruxos_posix_api/src/imp/pthread/mod.rs @@ -16,6 +16,8 @@ use ruxtask::AxTaskRef; use spin::RwLock; use crate::ctypes; +#[cfg(feature = "fd")] +use crate::imp::fd_ops::{fd_table_count, flush_file_like, RUX_FILE_LIMIT}; pub mod condvar; pub mod mutex; @@ -208,6 +210,21 @@ pub unsafe fn sys_pthread_create( /// Exits the current thread. The value `retval` will be returned to the joiner. pub fn sys_pthread_exit(retval: *mut c_void) -> ! { debug!("sys_pthread_exit <= {:#x}", retval as usize); + #[cfg(feature = "fd")] + { + let mut now_fd_count = 0; + let mut fd_index: usize = 0; + while fd_index < RUX_FILE_LIMIT { + let flush_res = flush_file_like(fd_index.try_into().unwrap()); + if flush_res == Ok(()) { + now_fd_count += 1; + if now_fd_count == fd_table_count() { + break; + } + } + fd_index += 1; + } + } #[cfg(feature = "musl")] { use core::sync::atomic::Ordering; diff --git a/api/ruxos_posix_api/src/imp/stdio.rs b/api/ruxos_posix_api/src/imp/stdio.rs index 5d29c7a66..0f6f46fcd 100644 --- a/api/ruxos_posix_api/src/imp/stdio.rs +++ b/api/ruxos_posix_api/src/imp/stdio.rs @@ -120,6 +120,11 @@ impl super::fd_ops::FileLike for Stdin { Err(LinuxError::EPERM) } + ///TODO + fn flush(&self) -> LinuxResult { + Ok(()) + } + fn stat(&self) -> LinuxResult { let st_mode = 0o20000 | 0o440u32; // S_IFCHR | r--r----- Ok(crate::ctypes::stat { @@ -156,6 +161,10 @@ impl super::fd_ops::FileLike for Stdout { Ok(self.inner.lock().write(buf)?) } + fn flush(&self) -> LinuxResult { + Ok(()) + } + fn stat(&self) -> LinuxResult { let st_mode = 0o20000 | 0o220u32; // S_IFCHR | -w--w---- Ok(crate::ctypes::stat { diff --git a/api/ruxos_posix_api/src/imp/task.rs b/api/ruxos_posix_api/src/imp/task.rs index 4c295f86a..bf764d81e 100644 --- a/api/ruxos_posix_api/src/imp/task.rs +++ b/api/ruxos_posix_api/src/imp/task.rs @@ -7,6 +7,8 @@ * See the Mulan PSL v2 for more details. */ +#[cfg(feature = "fd")] +use crate::imp::fd_ops::{fd_table_count, flush_file_like, RUX_FILE_LIMIT}; use core::ffi::c_int; /// Relinquish the CPU, and switches to another task. @@ -42,6 +44,21 @@ pub fn sys_getpid() -> c_int { /// Exit current task pub fn sys_exit(exit_code: c_int) -> ! { debug!("sys_exit <= {}", exit_code); + #[cfg(feature = "fd")] + { + let mut now_fd_count = 0; + let mut fd_index: usize = 0; + while fd_index < RUX_FILE_LIMIT { + let flush_res = flush_file_like(fd_index.try_into().unwrap()); + if flush_res == Ok(()) { + now_fd_count += 1; + if now_fd_count == fd_table_count() { + break; + } + } + fd_index += 1; + } + } #[cfg(feature = "multitask")] ruxtask::exit(exit_code); #[cfg(not(feature = "multitask"))] diff --git a/modules/ruxfs/src/dev.rs b/modules/ruxfs/src/dev.rs index d0d8ea201..f897c4c76 100644 --- a/modules/ruxfs/src/dev.rs +++ b/modules/ruxfs/src/dev.rs @@ -98,4 +98,9 @@ impl Disk { }; Ok(write_size) } + + ///flush device cache + pub fn do_flush(&mut self) -> DevResult { + self.dev.flush() + } } diff --git a/modules/ruxfs/src/fs/fatfs.rs b/modules/ruxfs/src/fs/fatfs.rs index 102b59afb..9a0f7433d 100644 --- a/modules/ruxfs/src/fs/fatfs.rs +++ b/modules/ruxfs/src/fs/fatfs.rs @@ -8,6 +8,7 @@ */ use alloc::sync::Arc; +use axio::Error; use core::cell::UnsafeCell; use axfs_vfs::{VfsDirEntry, VfsError, VfsNodePerm, VfsResult}; @@ -74,6 +75,10 @@ impl FatFileSystem { impl VfsNodeOps for FileWrapper<'static> { axfs_vfs::impl_vfs_non_dir_default! {} + fn fsync(&self) -> VfsResult { + self.0.lock().flush().map_err(as_vfs_err) + } + fn get_attr(&self) -> VfsResult { let size = self.0.lock().seek(SeekFrom::End(0)).map_err(as_vfs_err)?; let blocks = (size + BLOCK_SIZE as u64 - 1) / BLOCK_SIZE as u64; @@ -272,7 +277,7 @@ impl Write for Disk { Ok(write_len) } fn flush(&mut self) -> Result<(), Self::Error> { - Ok(()) + self.do_flush().map_err(|_| ()) } }