diff --git a/kernel/aster-nix/src/fs/file_handle.rs b/kernel/aster-nix/src/fs/file_handle.rs index d1e99e3d3..b934654a5 100644 --- a/kernel/aster-nix/src/fs/file_handle.rs +++ b/kernel/aster-nix/src/fs/file_handle.rs @@ -54,10 +54,6 @@ pub trait FileLike: Pollable + Send + Sync + Any { return_errno_with_message!(Errno::EINVAL, "resize is not supported"); } - fn flush(&self) -> Result<()> { - Ok(()) - } - fn metadata(&self) -> Metadata { panic!("metadata unsupported"); } @@ -102,11 +98,6 @@ pub trait FileLike: Pollable + Send + Sync + Any { return_errno_with_message!(Errno::ESPIPE, "seek is not supported"); } - fn clean_for_close(&self) -> Result<()> { - self.flush()?; - Ok(()) - } - fn register_observer( &self, observer: Weak>, diff --git a/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs b/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs index b19035e5c..62e5902c1 100644 --- a/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs +++ b/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs @@ -138,11 +138,6 @@ impl FileLike for InodeHandle { Ok(()) } - fn clean_for_close(&self) -> Result<()> { - // Close does not guarantee that the data has been successfully saved to disk. - Ok(()) - } - fn as_device(&self) -> Option> { self.dentry().inode().as_device() } diff --git a/kernel/aster-nix/src/process/exit.rs b/kernel/aster-nix/src/process/exit.rs index dce7a559f..51414efac 100644 --- a/kernel/aster-nix/src/process/exit.rs +++ b/kernel/aster-nix/src/process/exit.rs @@ -40,9 +40,7 @@ pub fn do_exit_group(term_status: TermStatus) { // Close all files then exit the process let files = current.file_table().lock().close_all(); - for file in files { - let _ = file.clean_for_close(); - } + drop(files); // Move children to the init process if !is_init_process(¤t) { diff --git a/kernel/aster-nix/src/syscall/close.rs b/kernel/aster-nix/src/syscall/close.rs index c3e556c80..f7a970017 100644 --- a/kernel/aster-nix/src/syscall/close.rs +++ b/kernel/aster-nix/src/syscall/close.rs @@ -5,10 +5,27 @@ use crate::{fs::file_table::FileDesc, prelude::*}; pub fn sys_close(fd: FileDesc) -> Result { debug!("fd = {}", fd); - let current = current!(); - let mut file_table = current.file_table().lock(); - let _ = file_table.get_file(fd)?; - let file = file_table.close_file(fd).unwrap(); - file.clean_for_close()?; + + let file = { + let current = current!(); + let mut file_table = current.file_table().lock(); + let _ = file_table.get_file(fd)?; + file_table.close_file(fd).unwrap() + }; + + // Cleanup work needs to be done in the `Drop` impl. + // + // We don't mind the races between closing the file descriptor and using the file descriptor, + // because such races are explicitly allowed in the man pages. See the "Multithreaded processes + // and close()" section in . + drop(file); + + // Linux has error codes for the close() system call for diagnostic and remedial purposes, but + // only for a small subset of file systems such as NFS. We currently have no support for such + // file systems, so it's fine to just return zero. + // + // For details, see the discussion at and + // the "Dealing with error returns from close()" section at + // . Ok(SyscallReturn::Return(0)) } diff --git a/kernel/aster-nix/src/syscall/execve.rs b/kernel/aster-nix/src/syscall/execve.rs index 70d2e1671..3365ad1ec 100644 --- a/kernel/aster-nix/src/syscall/execve.rs +++ b/kernel/aster-nix/src/syscall/execve.rs @@ -105,9 +105,7 @@ fn do_execve( // Ensure that the file descriptors with the close-on-exec flag are closed. let closed_files = current.file_table().lock().close_files_on_exec(); - for file in closed_files { - file.clean_for_close()?; - } + drop(closed_files); debug!("load program to root vmar"); let (new_executable_path, elf_load_info) = {