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>
This commit is contained in:
LoGin 2025-05-24 23:17:26 +08:00 committed by GitHub
parent aa394c1f6f
commit a56444e1ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 427 additions and 130 deletions

View File

@ -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,

View File

@ -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(),

View File

@ -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,
);
}

View File

@ -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)
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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;