Browse Source

refactor(vfs): refactor some fs syscalls to syscall-table (#1177)

* refactor(vfs/syscall): 把sys_open加到调用表

Signed-off-by: longjin <longjin@DragonOS.org>

* refactor(vfs): 将文件系统相关系统调用拆分为独立模块

将 `close`、`fstat`、`lstat` 和 `stat` 系统调用从 `mod.rs` 中拆分为独立的模块

Signed-off-by: longjin <longjin@DragonOS.org>

* refactor(vfs): 将ioctl系统调用处理逻辑移至独立模块

将ioctl系统调用的处理逻辑从`mod.rs`中提取到独立的`sys_ioctl.rs`模块中,以提高代码的可维护性和可读性。

Signed-off-by: longjin <longjin@DragonOS.org>

* refactor(vfs): 重构stat相关系统调用实现

将sys_fstat、sys_lstat和sys_stat的实现统一改为调用Syscall::newfstat,移除重复代码

Signed-off-by: longjin <longjin@DragonOS.org>

* refactor(vfs): 将do_open函数提取到open_utils模块

将sys_open.rs中的do_open函数提取到新建的open_utils模块,并在多处调用处更新引用路径。

Signed-off-by: longjin <longjin@DragonOS.org>

---------

Signed-off-by: longjin <longjin@DragonOS.org>
LoGin 1 week ago
parent
commit
a56444e1ad

+ 1 - 1
kernel/src/filesystem/vfs/open.rs

@@ -150,7 +150,7 @@ pub fn ksys_fchown(fd: i32, uid: usize, gid: usize) -> Result<usize, SystemError
     return result;
 }
 
-pub(super) fn do_sys_open(
+pub fn do_sys_open(
     dfd: i32,
     path: &str,
     o_flags: FileMode,

+ 13 - 91
kernel/src/filesystem/vfs/syscall/mod.rs

@@ -3,6 +3,7 @@ use crate::filesystem::vfs::FileSystemMakerData;
 use core::mem::size_of;
 
 use alloc::{string::String, sync::Arc, vec::Vec};
+
 use log::warn;
 use system_error::SystemError;
 
@@ -35,8 +36,19 @@ use super::{
     VFS_MAX_FOLLOW_SYMLINK_TIMES,
 };
 
+mod open_utils;
+mod sys_close;
+#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
+mod sys_fstat;
+mod sys_ioctl;
+#[cfg(target_arch = "x86_64")]
+mod sys_lstat;
+#[cfg(target_arch = "x86_64")]
+mod sys_open;
 mod sys_read;
 mod sys_readv;
+#[cfg(target_arch = "x86_64")]
+mod sys_stat;
 mod sys_write;
 mod sys_writev;
 
@@ -425,33 +437,6 @@ bitflags! {
 }
 
 impl Syscall {
-    /// @brief 为当前进程打开一个文件
-    ///
-    /// @param path 文件路径
-    /// @param o_flags 打开文件的标志位
-    ///
-    /// @return 文件描述符编号,或者是错误码
-    pub fn open(
-        path: *const u8,
-        o_flags: u32,
-        mode: u32,
-        follow_symlink: bool,
-    ) -> Result<usize, SystemError> {
-        let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
-            .into_string()
-            .map_err(|_| SystemError::EINVAL)?;
-
-        let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
-        let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
-        return do_sys_open(
-            AtFlags::AT_FDCWD.bits(),
-            &path,
-            open_flags,
-            mode,
-            follow_symlink,
-        );
-    }
-
     pub fn openat(
         dirfd: i32,
         path: *const u8,
@@ -468,40 +453,6 @@ impl Syscall {
         return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
     }
 
-    /// @brief 关闭文件
-    ///
-    /// @param fd 文件描述符编号
-    ///
-    /// @return 成功返回0,失败返回错误码
-    pub fn close(fd: usize) -> Result<usize, SystemError> {
-        let binding = ProcessManager::current_pcb().fd_table();
-        let mut fd_table_guard = binding.write();
-        let _file = fd_table_guard.drop_fd(fd as i32)?;
-        drop(fd_table_guard);
-        Ok(0)
-    }
-
-    /// @brief 发送命令到文件描述符对应的设备,
-    ///
-    /// @param fd 文件描述符编号
-    /// @param cmd 设备相关的请求类型
-    ///
-    /// @return Ok(usize) 成功返回0
-    /// @return Err(SystemError) 读取失败,返回posix错误码
-    pub fn ioctl(fd: usize, cmd: u32, data: usize) -> Result<usize, SystemError> {
-        let binding = ProcessManager::current_pcb().fd_table();
-        let fd_table_guard = binding.read();
-
-        let file = fd_table_guard
-            .get_file_by_fd(fd as i32)
-            .ok_or(SystemError::EBADF)?;
-
-        // drop guard 以避免无法调度的问题
-        drop(fd_table_guard);
-        let r = file.inode().ioctl(cmd, data, &file.private_data.lock());
-        return r;
-    }
-
     /// @brief 调整文件操作指针的位置
     ///
     /// @param fd 文件描述符编号
@@ -1211,38 +1162,9 @@ impl Syscall {
         return Err(SystemError::EBADF);
     }
 
-    #[inline(never)]
-    pub fn fstat(fd: i32, user_stat_ptr: usize) -> Result<usize, SystemError> {
-        Self::newfstat(fd, user_stat_ptr)
-    }
-
-    pub fn stat(path: *const u8, user_stat_ptr: usize) -> Result<usize, SystemError> {
-        let fd = Self::open(
-            path,
-            FileMode::O_RDONLY.bits(),
-            ModeType::empty().bits(),
-            true,
-        )?;
-        let r = Self::fstat(fd as i32, user_stat_ptr);
-        Self::close(fd).ok();
-        return r;
-    }
-
-    pub fn lstat(path: *const u8, user_stat_ptr: usize) -> Result<usize, SystemError> {
-        let fd = Self::open(
-            path,
-            FileMode::O_RDONLY.bits(),
-            ModeType::empty().bits(),
-            false,
-        )?;
-        let r = Self::fstat(fd as i32, user_stat_ptr);
-        Self::close(fd).ok();
-        return r;
-    }
-
     pub fn statfs(path: *const u8, user_statfs: *mut PosixStatfs) -> Result<usize, SystemError> {
         let mut writer = UserBufferWriter::new(user_statfs, size_of::<PosixStatfs>(), true)?;
-        let fd = Self::open(
+        let fd = open_utils::do_open(
             path,
             FileMode::O_RDONLY.bits(),
             ModeType::empty().bits(),

+ 39 - 0
kernel/src/filesystem/vfs/syscall/open_utils.rs

@@ -0,0 +1,39 @@
+use system_error::SystemError;
+
+use crate::{
+    filesystem::vfs::{fcntl::AtFlags, file::FileMode, open::do_sys_open, MAX_PATHLEN},
+    syscall::user_access::check_and_clone_cstr,
+};
+
+use super::ModeType;
+
+/// Performs the actual file opening operation.
+///
+/// # Arguments
+/// * `path` - Pointer to the path string
+/// * `o_flags` - File opening flags
+/// * `mode` - File mode/permissions
+/// * `follow_symlink` - Whether to follow symbolic links
+///
+/// # Returns
+/// File descriptor on success, or error code on failure.
+pub(super) fn do_open(
+    path: *const u8,
+    o_flags: u32,
+    mode: u32,
+    follow_symlink: bool,
+) -> Result<usize, SystemError> {
+    let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
+        .into_string()
+        .map_err(|_| SystemError::EINVAL)?;
+
+    let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
+    let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
+    return do_sys_open(
+        AtFlags::AT_FDCWD.bits(),
+        &path,
+        open_flags,
+        mode,
+        follow_symlink,
+    );
+}

+ 54 - 0
kernel/src/filesystem/vfs/syscall/sys_close.rs

@@ -0,0 +1,54 @@
+//! System call handler for closing files.
+
+use alloc::string::ToString;
+
+use crate::arch::syscall::nr::SYS_CLOSE;
+use crate::process::ProcessManager;
+use crate::syscall::table::FormattedSyscallParam;
+use crate::syscall::table::Syscall;
+use alloc::vec::Vec;
+use system_error::SystemError;
+
+/// Handler for the `close` system call.
+pub struct SysCloseHandle;
+
+impl Syscall for SysCloseHandle {
+    /// Returns the number of arguments this syscall takes (1).
+    fn num_args(&self) -> usize {
+        1
+    }
+
+    /// Handles the close syscall by extracting arguments and calling `do_close`.
+    fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
+        let fd = Self::fd(args);
+        do_close(fd)
+    }
+    /// Formats the syscall arguments for display/debugging purposes.
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![FormattedSyscallParam::new("fd", Self::fd(args).to_string())]
+    }
+}
+
+impl SysCloseHandle {
+    /// Extracts the file descriptor (fd) argument from syscall parameters.
+    fn fd(args: &[usize]) -> i32 {
+        args[0] as i32
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_CLOSE, SysCloseHandle);
+
+/// Close a file descriptor
+///
+/// # Arguments
+/// - `fd`: The file descriptor to close
+///
+/// # Returns
+/// Returns Ok(0) on success, or Err(SystemError) on failure
+pub(super) fn do_close(fd: i32) -> Result<usize, SystemError> {
+    let binding = ProcessManager::current_pcb().fd_table();
+    let mut fd_table_guard = binding.write();
+    let _file = fd_table_guard.drop_fd(fd)?;
+    drop(fd_table_guard);
+    Ok(0)
+}

+ 47 - 0
kernel/src/filesystem/vfs/syscall/sys_fstat.rs

@@ -0,0 +1,47 @@
+//! System call handler for opening files.
+
+use system_error::SystemError;
+
+use crate::arch::syscall::nr::SYS_FSTAT;
+use crate::syscall::table::FormattedSyscallParam;
+use crate::syscall::table::Syscall;
+
+use alloc::string::ToString;
+use alloc::vec::Vec;
+
+pub struct SysFstatHandle;
+
+impl Syscall for SysFstatHandle {
+    /// Returns the number of arguments this syscall takes.
+    fn num_args(&self) -> usize {
+        2
+    }
+
+    fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
+        let fd = Self::fd(args);
+        let usr_kstat = Self::usr_kstat(args);
+        crate::syscall::Syscall::newfstat(fd, usr_kstat)
+    }
+
+    /// Formats the syscall arguments for display/debugging purposes.
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![
+            FormattedSyscallParam::new("fd", Self::fd(args).to_string()),
+            FormattedSyscallParam::new("statbuf", format!("{:#x}", Self::usr_kstat(args))),
+        ]
+    }
+}
+
+impl SysFstatHandle {
+    /// Extracts the fd argument from syscall parameters.
+    fn fd(args: &[usize]) -> i32 {
+        args[0] as i32
+    }
+
+    /// Extracts the usr_kstat argument from syscall parameters.
+    fn usr_kstat(args: &[usize]) -> usize {
+        args[1]
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_FSTAT, SysFstatHandle);

+ 77 - 0
kernel/src/filesystem/vfs/syscall/sys_ioctl.rs

@@ -0,0 +1,77 @@
+//! System call handler for ioctls.
+
+use crate::arch::syscall::nr::SYS_IOCTL;
+use crate::process::ProcessManager;
+use crate::syscall::table::FormattedSyscallParam;
+use crate::syscall::table::Syscall;
+use system_error::SystemError;
+
+use alloc::string::ToString;
+use alloc::vec::Vec;
+
+/// Handler for the `ioctl` system call.
+pub struct SysIoctlHandle;
+
+impl Syscall for SysIoctlHandle {
+    /// Returns the number of arguments this syscall takes (3).
+    fn num_args(&self) -> usize {
+        3
+    }
+
+    /// Sends a command to the device corresponding to the file descriptor.
+    ///
+    /// # Arguments
+    ///
+    /// * `fd` - File descriptor number
+    /// * `cmd` - Device-dependent request code
+    ///
+    /// # Returns
+    ///
+    /// * `Ok(usize)` - On success, returns 0
+    /// * `Err(SystemError)` - On failure, returns a POSIX error code
+    fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
+        let fd = Self::fd(args);
+        let cmd = Self::cmd(args);
+        let data = Self::data(args);
+
+        let binding = ProcessManager::current_pcb().fd_table();
+        let fd_table_guard = binding.read();
+
+        let file = fd_table_guard
+            .get_file_by_fd(fd as i32)
+            .ok_or(SystemError::EBADF)?;
+
+        // drop guard 以避免无法调度的问题
+        drop(fd_table_guard);
+        let r = file.inode().ioctl(cmd, data, &file.private_data.lock());
+        return r;
+    }
+
+    /// Formats the syscall arguments for display/debugging purposes.
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![
+            FormattedSyscallParam::new("fd", Self::fd(args).to_string()),
+            FormattedSyscallParam::new("cmd", format!("{:#x}", Self::cmd(args))),
+            FormattedSyscallParam::new("data", format!("{:#x}", Self::data(args))),
+        ]
+    }
+}
+
+impl SysIoctlHandle {
+    /// Extracts the file descriptor argument from syscall parameters.
+    fn fd(args: &[usize]) -> usize {
+        args[0]
+    }
+
+    /// Extracts the command argument from syscall parameters.
+    fn cmd(args: &[usize]) -> u32 {
+        args[1] as u32
+    }
+
+    /// Extracts the data argument from syscall parameters.
+    fn data(args: &[usize]) -> usize {
+        args[2]
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_IOCTL, SysIoctlHandle);

+ 64 - 0
kernel/src/filesystem/vfs/syscall/sys_lstat.rs

@@ -0,0 +1,64 @@
+//! System call handler for opening files.
+
+use system_error::SystemError;
+
+use defer::defer;
+
+use crate::arch::syscall::nr::SYS_LSTAT;
+use crate::filesystem::vfs::file::FileMode;
+use crate::filesystem::vfs::syscall::sys_close::do_close;
+use crate::filesystem::vfs::ModeType;
+use crate::syscall::table::FormattedSyscallParam;
+use crate::syscall::table::Syscall;
+
+use alloc::vec::Vec;
+
+pub struct SysLstatHandle;
+
+impl Syscall for SysLstatHandle {
+    /// Returns the number of arguments this syscall takes.
+    fn num_args(&self) -> usize {
+        2
+    }
+
+    fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
+        let path = Self::path(args);
+        let usr_kstat = Self::usr_kstat(args);
+
+        let fd = super::open_utils::do_open(
+            path,
+            FileMode::O_RDONLY.bits(),
+            ModeType::empty().bits(),
+            false,
+        )?;
+
+        defer!({
+            do_close(fd as i32).ok();
+        });
+        crate::syscall::Syscall::newfstat(fd as i32, usr_kstat)?;
+
+        return Ok(0);
+    }
+
+    /// Formats the syscall arguments for display/debugging purposes.
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![
+            FormattedSyscallParam::new("path", format!("{:#x}", Self::path(args) as usize)),
+            FormattedSyscallParam::new("statbuf", format!("{:#x}", Self::usr_kstat(args))),
+        ]
+    }
+}
+
+impl SysLstatHandle {
+    /// Extracts the path argument from syscall parameters.
+    fn path(args: &[usize]) -> *const u8 {
+        args[0] as *const u8
+    }
+
+    /// Extracts the usr_kstat argument from syscall parameters.
+    fn usr_kstat(args: &[usize]) -> usize {
+        args[1]
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_LSTAT, SysLstatHandle);

+ 57 - 0
kernel/src/filesystem/vfs/syscall/sys_open.rs

@@ -0,0 +1,57 @@
+//! System call handler for opening files.
+
+use system_error::SystemError;
+
+use crate::arch::syscall::nr::SYS_OPEN;
+use crate::syscall::table::FormattedSyscallParam;
+use crate::syscall::table::Syscall;
+
+use alloc::string::ToString;
+use alloc::vec::Vec;
+
+/// Handler for the `open` system call.
+pub struct SysOpenHandle;
+
+impl Syscall for SysOpenHandle {
+    /// Returns the number of arguments this syscall takes (3).
+    fn num_args(&self) -> usize {
+        3
+    }
+
+    /// Handles the open syscall by extracting arguments and calling `do_open`.
+    fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
+        let path = Self::path(args);
+        let flags = Self::flags(args);
+        let mode = Self::mode(args);
+
+        super::open_utils::do_open(path, flags, mode, true)
+    }
+
+    /// Formats the syscall arguments for display/debugging purposes.
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![
+            FormattedSyscallParam::new("path", format!("{:#x}", Self::path(args) as usize)),
+            FormattedSyscallParam::new("flags", Self::flags(args).to_string()),
+            FormattedSyscallParam::new("mode", Self::mode(args).to_string()),
+        ]
+    }
+}
+
+impl SysOpenHandle {
+    /// Extracts the path argument from syscall parameters.
+    fn path(args: &[usize]) -> *const u8 {
+        args[0] as *const u8
+    }
+
+    /// Extracts the flags argument from syscall parameters.
+    fn flags(args: &[usize]) -> u32 {
+        args[1] as u32
+    }
+
+    /// Extracts the mode argument from syscall parameters.
+    fn mode(args: &[usize]) -> u32 {
+        args[2] as u32
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_OPEN, SysOpenHandle);

+ 65 - 0
kernel/src/filesystem/vfs/syscall/sys_stat.rs

@@ -0,0 +1,65 @@
+//! System call handler for opening files.
+
+use system_error::SystemError;
+
+use defer::defer;
+
+use crate::arch::syscall::nr::SYS_STAT;
+use crate::filesystem::vfs::file::FileMode;
+use crate::filesystem::vfs::syscall::sys_close::do_close;
+use crate::filesystem::vfs::ModeType;
+use crate::syscall::table::FormattedSyscallParam;
+use crate::syscall::table::Syscall;
+
+use alloc::vec::Vec;
+
+pub struct SysStatHandle;
+
+impl Syscall for SysStatHandle {
+    /// Returns the number of arguments this syscall takes.
+    fn num_args(&self) -> usize {
+        2
+    }
+
+    fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
+        let path = Self::path(args);
+        let usr_kstat = Self::usr_kstat(args);
+
+        let fd = super::open_utils::do_open(
+            path,
+            FileMode::O_RDONLY.bits(),
+            ModeType::empty().bits(),
+            true,
+        )?;
+
+        defer!({
+            do_close(fd as i32).ok();
+        });
+
+        crate::syscall::Syscall::newfstat(fd as i32, usr_kstat)?;
+
+        return Ok(0);
+    }
+
+    /// Formats the syscall arguments for display/debugging purposes.
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![
+            FormattedSyscallParam::new("path", format!("{:#x}", Self::path(args) as usize)),
+            FormattedSyscallParam::new("statbuf", format!("{:#x}", Self::usr_kstat(args))),
+        ]
+    }
+}
+
+impl SysStatHandle {
+    /// Extracts the path argument from syscall parameters.
+    fn path(args: &[usize]) -> *const u8 {
+        args[0] as *const u8
+    }
+
+    /// Extracts the usr_kstat argument from syscall parameters.
+    fn usr_kstat(args: &[usize]) -> usize {
+        args[1]
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_STAT, SysStatHandle);

+ 10 - 1
kernel/src/net/syscall.rs

@@ -7,8 +7,11 @@ use system_error::SystemError;
 
 use crate::{
     filesystem::vfs::{
+        fcntl::AtFlags,
         file::{File, FileMode},
         iov::{IoVec, IoVecs},
+        open::do_sys_open,
+        syscall::ModeType,
         FileType,
     },
     libs::spinlock::SpinLockGuard,
@@ -591,7 +594,13 @@ impl SockAddr {
                         .to_str()
                         .map_err(|_| SystemError::EINVAL)?;
 
-                    let fd = Syscall::open(path.as_ptr(), FileMode::O_RDWR.bits(), 0o755, true)?;
+                    let fd = do_sys_open(
+                        AtFlags::AT_FDCWD.bits(),
+                        path,
+                        FileMode::O_RDWR,
+                        ModeType::S_IWUGO | ModeType::S_IRUGO,
+                        true,
+                    )?;
 
                     let binding = ProcessManager::current_pcb().fd_table();
                     let fd_table_guard = binding.read();

+ 0 - 37
kernel/src/syscall/mod.rs

@@ -116,14 +116,6 @@ impl Syscall {
             SYS_PUT_STRING => {
                 Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32)
             }
-            #[cfg(target_arch = "x86_64")]
-            SYS_OPEN => {
-                let path = args[0] as *const u8;
-                let flags = args[1] as u32;
-                let mode = args[2] as u32;
-
-                Self::open(path, flags, mode, true)
-            }
 
             #[cfg(target_arch = "x86_64")]
             SYS_RENAME => {
@@ -164,10 +156,6 @@ impl Syscall {
 
                 Self::openat(dirfd, path, flags, mode, true)
             }
-            SYS_CLOSE => {
-                let fd = args[0];
-                Self::close(fd)
-            }
 
             SYS_LSEEK => {
                 let fd = args[0] as i32;
@@ -202,13 +190,6 @@ impl Syscall {
                 Self::pwrite(fd, buf, len, offset)
             }
 
-            SYS_IOCTL => {
-                let fd = args[0];
-                let cmd = args[1];
-                let data = args[2];
-                Self::ioctl(fd, cmd as u32, data)
-            }
-
             #[cfg(target_arch = "x86_64")]
             SYS_FORK => Self::fork(frame),
             #[cfg(target_arch = "x86_64")]
@@ -664,12 +645,6 @@ impl Syscall {
 
             SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
 
-            #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
-            SYS_FSTAT => {
-                let fd = args[0] as i32;
-                Self::fstat(fd, args[1])
-            }
-
             SYS_FCNTL => {
                 let fd = args[0] as i32;
                 let cmd: Option<FcntlCommand> =
@@ -767,18 +742,6 @@ impl Syscall {
 
             SYS_SET_TID_ADDRESS => Self::set_tid_address(args[0]),
 
-            #[cfg(target_arch = "x86_64")]
-            SYS_LSTAT => {
-                let path = args[0] as *const u8;
-                Self::lstat(path, args[1])
-            }
-
-            #[cfg(target_arch = "x86_64")]
-            SYS_STAT => {
-                let path = args[0] as *const u8;
-                Self::stat(path, args[1])
-            }
-
             SYS_STATFS => {
                 let path = args[0] as *const u8;
                 let statfs = args[1] as *mut PosixStatfs;