Skip to content

refactor(vfs/syscall): 重构部分vfs下的系统调用 #1236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
551925e
refactor(vfs/syscall): 重构部分vfs下的系统调用
kaleidoscope416 Jul 22, 2025
aa0982e
迁移sys_utimes系统调用
dolzhuying Jul 23, 2025
f1c5bc3
迁移futimesat和utimensat系统调用
dolzhuying Jul 23, 2025
aed7ac3
迁移fchown
dolzhuying Jul 23, 2025
a2b6b94
迁移fchownat
dolzhuying Jul 23, 2025
3e0c65c
refactor(vfs/syscall):迁移lchown
dolzhuying Jul 23, 2025
bedd410
refactor(vfs/syscall):迁移chown
dolzhuying Jul 23, 2025
62de25e
refactor(vfs/syscall):迁移fchmod
dolzhuying Jul 23, 2025
381cfd1
refactor(vfs/syscall):迁移fchmodat
dolzhuying Jul 23, 2025
4a4b666
refactor(vfs/syscall):迁移chmod
dolzhuying Jul 23, 2025
5dab2c8
refactor(vfs/syscall):迁移faccessat和faccessat2
dolzhuying Jul 23, 2025
9401f22
refactor(vfs/syscall):迁移access
dolzhuying Jul 24, 2025
b3bd7be
refactor(vfs/syscall):迁移readlink和readlinkat
dolzhuying Jul 24, 2025
fd4d4e5
refactor(vfs/syscall):迁移dup,dup2,dup3,fcntl
dolzhuying Jul 24, 2025
d750b40
refactor(vfs/syscall):迁移ftruncate
dolzhuying Jul 24, 2025
c0fdf50
refactor(vfs/syscall):迁移mknod
dolzhuying Jul 24, 2025
edb735a
refactor(vfs/syscall):迁移newfstatat
dolzhuying Jul 24, 2025
a78a042
refactor(vfs/syscall):迁移statx
dolzhuying Jul 24, 2025
d59a852
refactor(vfs/syscall):迁移statfs
dolzhuying Jul 24, 2025
a316633
refactor(vfs/syscall):迁移fstatfs
dolzhuying Jul 24, 2025
4153d13
refactor(vfs/syscall):迁移newfstat
dolzhuying Jul 24, 2025
a4c66f8
refactor(vfs/syscall):make fmt
dolzhuying Jul 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions kernel/src/filesystem/vfs/syscall/dup2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use system_error::SystemError;

use crate::{
filesystem::vfs::file::{FileDescriptorVec, FileMode},
libs::rwlock::RwLockWriteGuard,
};

pub fn do_dup2(
oldfd: i32,
newfd: i32,
fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>,
) -> Result<usize, SystemError> {
do_dup3(oldfd, newfd, FileMode::empty(), fd_table_guard)
}

pub fn do_dup3(
oldfd: i32,
newfd: i32,
flags: FileMode,
fd_table_guard: &mut RwLockWriteGuard<'_, FileDescriptorVec>,
) -> Result<usize, SystemError> {
// 确认oldfd, newid是否有效
if !(FileDescriptorVec::validate_fd(oldfd) && FileDescriptorVec::validate_fd(newfd)) {
return Err(SystemError::EBADF);
}

if oldfd == newfd {
// 若oldfd与newfd相等
return Ok(newfd as usize);
}
let new_exists = fd_table_guard.get_file_by_fd(newfd).is_some();
if new_exists {
// close newfd
if fd_table_guard.drop_fd(newfd).is_err() {
// An I/O error occurred while attempting to close fildes2.
return Err(SystemError::EIO);
}
}

let old_file = fd_table_guard
.get_file_by_fd(oldfd)
.ok_or(SystemError::EBADF)?;
let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;

if flags.contains(FileMode::O_CLOEXEC) {
new_file.set_close_on_exec(true);
} else {
new_file.set_close_on_exec(false);
}
// 申请文件描述符,并把文件对象存入其中
let res = fd_table_guard
.alloc_fd(new_file, Some(newfd))
.map(|x| x as usize);
return res;
}
17 changes: 17 additions & 0 deletions kernel/src/filesystem/vfs/syscall/faccessat2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use system_error::SystemError;

use crate::filesystem::vfs::{open::do_faccessat, syscall::ModeType};

pub fn do_faccessat2(
dirfd: i32,
pathname: *const u8,
mode: u32,
flags: u32,
) -> Result<usize, SystemError> {
return do_faccessat(
dirfd,
pathname,
ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?,
flags,
);
}
72 changes: 72 additions & 0 deletions kernel/src/filesystem/vfs/syscall/link_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::filesystem::vfs::syscall::AtFlags;
use crate::filesystem::vfs::utils::rsplit_path;
use crate::filesystem::vfs::utils::user_path_at;
use crate::filesystem::vfs::FileType;
use crate::filesystem::vfs::IndexNode;
use crate::filesystem::vfs::SystemError;
use crate::filesystem::vfs::VFS_MAX_FOLLOW_SYMLINK_TIMES;
use crate::process::ProcessManager;
use alloc::sync::Arc;
/// **创建硬连接的系统调用**
///
/// ## 参数
///
/// - 'oldfd': 用于解析源文件路径的文件描述符
/// - 'old': 源文件路径
/// - 'newfd': 用于解析新文件路径的文件描述符
/// - 'new': 新文件将创建的路径
/// - 'flags': 标志位,仅以位或方式包含AT_EMPTY_PATH和AT_SYMLINK_FOLLOW
///
///
pub fn do_linkat(
oldfd: i32,
old: &str,
newfd: i32,
new: &str,
flags: AtFlags,
) -> Result<usize, SystemError> {
// flag包含其他未规定值时返回EINVAL
if !(AtFlags::AT_EMPTY_PATH | AtFlags::AT_SYMLINK_FOLLOW).contains(flags) {
return Err(SystemError::EINVAL);
}
// TODO AT_EMPTY_PATH标志启用时,进行调用者CAP_DAC_READ_SEARCH或相似的检查
let symlink_times = if flags.contains(AtFlags::AT_SYMLINK_FOLLOW) {
0_usize
} else {
VFS_MAX_FOLLOW_SYMLINK_TIMES
};
let pcb = ProcessManager::current_pcb();

// 得到源路径的inode
let old_inode: Arc<dyn IndexNode> = if old.is_empty() {
if flags.contains(AtFlags::AT_EMPTY_PATH) {
// 在AT_EMPTY_PATH启用时,old可以为空,old_inode实际为oldfd所指文件,但该文件不能为目录。
let binding = pcb.fd_table();
let fd_table_guard = binding.read();
let file = fd_table_guard
.get_file_by_fd(oldfd)
.ok_or(SystemError::EBADF)?;
let old_inode = file.inode();
old_inode
} else {
return Err(SystemError::ENONET);
}
} else {
let (old_begin_inode, old_remain_path) = user_path_at(&pcb, oldfd, old)?;
old_begin_inode.lookup_follow_symlink(&old_remain_path, symlink_times)?
};

// old_inode为目录时返回EPERM
if old_inode.metadata().unwrap().file_type == FileType::Dir {
return Err(SystemError::EPERM);
}

// 得到新创建节点的父节点
let (new_begin_inode, new_remain_path) = user_path_at(&pcb, newfd, new)?;
let (new_name, new_parent_path) = rsplit_path(&new_remain_path);
let new_parent =
new_begin_inode.lookup_follow_symlink(new_parent_path.unwrap_or("/"), symlink_times)?;

// 被调用者利用downcast_ref判断两inode是否为同一文件系统
return new_parent.link(new_name, &old_inode).map(|_| 0);
}
Loading