实现了sys_rename (#578)

* 基本实现了rename的系统调用

* 实现相对路径的mv

* confilct resolve

* make fmt

* 更改校验位置,
 增加了SYS_RENAMEAT与SYS_RENAMEAT2两个系统调用,其实现与SYS_RENAME基本一致

* 删除了fat中的link

* fix

* 修改注释格式,删除管道文件判断

* 1
This commit is contained in:
TTaq 2024-03-18 14:47:59 +08:00 committed by GitHub
parent c3c7344451
commit 9e481b3bfe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 255 additions and 8 deletions

View File

@ -895,6 +895,55 @@ impl FATDir {
return Err(SystemError::EPERM);
}
}
/// @brief 跨目录,重命名一个目录项
///
pub fn rename_across(
&self,
fs: Arc<FATFileSystem>,
target: &FATDir,
old_name: &str,
new_name: &str,
) -> Result<FATDirEntry, SystemError> {
// 判断源目录项是否存在
let old_dentry: FATDirEntry = if let FATDirEntryOrShortName::DirEntry(dentry) =
self.check_existence(old_name, None, fs.clone())?
{
dentry
} else {
// 如果目标目录项不存在,则返回错误
return Err(SystemError::ENOENT);
};
let short_name = if let FATDirEntryOrShortName::ShortName(s) =
target.check_existence(new_name, None, fs.clone())?
{
s
} else {
// 如果目标目录项存在,那么就返回错误
return Err(SystemError::EEXIST);
};
let old_short_dentry: Option<ShortDirEntry> = old_dentry.short_dir_entry();
if let Some(se) = old_short_dentry {
// 删除原来的目录项
self.remove(fs.clone(), old_dentry.name().as_str(), false)?;
// 创建新的目录项
let new_dentry: FATDirEntry = target.create_dir_entries(
new_name,
&short_name,
Some(se),
se.attributes,
fs.clone(),
)?;
return Ok(new_dentry);
} else {
// 不允许对根目录项进行重命名
return Err(SystemError::EPERM);
}
}
}
impl FileAttributes {

View File

@ -1641,6 +1641,78 @@ impl IndexNode for LockedFATInode {
}
}
fn move_to(
&self,
old_name: &str,
target: &Arc<dyn IndexNode>,
new_name: &str,
) -> Result<(), SystemError> {
let old_id = self.metadata().unwrap().inode_id;
let new_id = target.metadata().unwrap().inode_id;
// 若在同一父目录下
if old_id == new_id {
let mut guard = self.0.lock();
let old_inode: Arc<LockedFATInode> = guard.find(old_name)?;
// 对目标inode上锁以防更改
let old_inode_guard: SpinLockGuard<FATInode> = old_inode.0.lock();
let fs = old_inode_guard.fs.upgrade().unwrap();
// 从缓存删除
let _nod = guard.children.remove(&old_name.to_uppercase());
let old_dir = match &guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
kerror!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
// 检查文件是否存在
// old_dir.check_existence(old_name, Some(false), guard.fs.upgrade().unwrap())?;
old_dir.rename(fs, old_name, new_name)?;
} else {
let mut old_guard = self.0.lock();
let other: &LockedFATInode = target
.downcast_ref::<LockedFATInode>()
.ok_or(SystemError::EPERM)?;
let new_guard = other.0.lock();
let old_inode: Arc<LockedFATInode> = old_guard.find(old_name)?;
// 对目标inode上锁以防更改
let old_inode_guard: SpinLockGuard<FATInode> = old_inode.0.lock();
let fs = old_inode_guard.fs.upgrade().unwrap();
// 从缓存删除
let _nod = old_guard.children.remove(&old_name.to_uppercase());
let old_dir = match &old_guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
kerror!("FATFS: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
let new_dir = match &new_guard.inode_type {
FATDirEntry::File(_) | FATDirEntry::VolId(_) => {
return Err(SystemError::ENOTDIR);
}
FATDirEntry::Dir(d) => d,
FATDirEntry::UnInit => {
kerror!("FATFA: param: Inode_type uninitialized.");
return Err(SystemError::EROFS);
}
};
// 检查文件是否存在
old_dir.check_existence(old_name, Some(false), old_guard.fs.upgrade().unwrap())?;
old_dir.rename_across(fs, new_dir, old_name, new_name)?;
}
return Ok(());
}
fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
let guard: SpinLockGuard<FATInode> = self.0.lock();
if guard.metadata.file_type != FileType::Dir {

View File

@ -195,7 +195,7 @@ impl IndexNode for KernFSInode {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn move_(
fn move_to(
&self,
_old_name: &str,
_target: &Arc<dyn IndexNode>,
@ -366,6 +366,11 @@ impl IndexNode for KernFSInode {
.unwrap()
.write(callback_data, &buf[..len], offset);
}
fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> {
// 待实现
Err(SystemError::ENOSYS)
}
}
impl KernFSInode {

View File

@ -636,6 +636,7 @@ impl IndexNode for LockedProcFSInode {
if inode.metadata.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
// 不允许删除当前文件夹,也不允许删除上一个目录
if name == "." || name == ".." {
return Err(SystemError::ENOTEMPTY);
@ -643,14 +644,17 @@ impl IndexNode for LockedProcFSInode {
// 获得要删除的文件的inode
let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?;
// 减少硬链接计数
to_delete.0.lock().metadata.nlinks -= 1;
// 在当前目录中删除这个子目录项
inode.children.remove(name);
return Ok(());
}
fn move_(
fn move_to(
&self,
_old_name: &str,
_target: &Arc<dyn IndexNode>,

View File

@ -374,7 +374,7 @@ impl IndexNode for LockedRamFSInode {
return Ok(());
}
fn move_(
fn move_to(
&self,
old_name: &str,
target: &Arc<dyn IndexNode>,
@ -539,4 +539,20 @@ impl IndexNode for LockedRamFSInode {
fn special_node(&self) -> Option<super::vfs::SpecialNodeData> {
return self.0.lock().special_node.clone();
}
/// # 用于重命名内存中的文件或目录
fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> {
let old_inode: Arc<dyn IndexNode> = self.find(_old_name)?;
// 在新的目录下创建一个硬链接
self.link(_new_name, &old_inode)?;
// 取消现有的目录下的这个硬链接
if let Err(err) = self.unlink(_old_name) {
// 如果取消失败,那就取消新的目录下的硬链接
self.unlink(_new_name)?;
return Err(err);
}
return Ok(());
}
}

View File

@ -255,7 +255,6 @@ pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> {
}
let pcb = ProcessManager::current_pcb();
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
let inode: Result<Arc<dyn IndexNode>, SystemError> =
inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES);

View File

@ -287,7 +287,7 @@ pub trait IndexNode: Any + Sync + Send + Debug {
///
/// @return 成功: Ok()
/// 失败: Err(错误码)
fn move_(
fn move_to(
&self,
_old_name: &str,
_target: &Arc<dyn IndexNode>,
@ -297,6 +297,23 @@ pub trait IndexNode: Any + Sync + Send + Debug {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
/// # 修改文件名
///
///
/// ## 参数
///
/// - _old_name: 源文件路径
/// - _new_name: 目标文件路径
///
/// ## 返回值
/// - Ok(返回值类型): 返回值的说明
/// - Err(错误值类型): 错误的说明
///
fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
/// @brief 寻找一个名为Name的inode
///
/// @param name 要寻找的inode的名称

View File

@ -253,13 +253,13 @@ impl IndexNode for MountFSInode {
}
#[inline]
fn move_(
fn move_to(
&self,
old_name: &str,
target: &Arc<dyn IndexNode>,
new_name: &str,
) -> Result<(), SystemError> {
return self.inner_inode.move_(old_name, target, new_name);
return self.inner_inode.move_to(old_name, target, new_name);
}
fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {

View File

@ -602,6 +602,51 @@ impl Syscall {
return do_unlink_at(AtFlags::AT_FDCWD.bits(), pathname).map(|v| v as usize);
}
/// # 修改文件名
///
///
/// ## 参数
///
/// - oldfd: 源文件描述符
/// - filename_from: 源文件路径
/// - newfd: 目标文件描述符
/// - filename_to: 目标文件路径
/// - flags: 标志位
///
///
/// ## 返回值
/// - Ok(返回值类型): 返回值的说明
/// - Err(错误值类型): 错误的说明
///
pub fn do_renameat2(
oldfd: i32,
filename_from: *const u8,
newfd: i32,
filename_to: *const u8,
_flags: u32,
) -> Result<usize, SystemError> {
let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN)).unwrap();
let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN)).unwrap();
// 文件名过长
if filename_from.len() > MAX_PATHLEN as usize || filename_to.len() > MAX_PATHLEN as usize {
return Err(SystemError::ENAMETOOLONG);
}
//获取pcb文件节点
let pcb = ProcessManager::current_pcb();
let (_old_inode_begin, old_remain_path) = user_path_at(&pcb, oldfd, &filename_from)?;
let (_new_inode_begin, new_remain_path) = user_path_at(&pcb, newfd, &filename_to)?;
//获取父目录
let (old_filename, old_parent_path) = rsplit_path(&old_remain_path);
let old_parent_inode = ROOT_INODE()
.lookup_follow_symlink(old_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
let (new_filename, new_parent_path) = rsplit_path(&new_remain_path);
let new_parent_inode = ROOT_INODE()
.lookup_follow_symlink(new_parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
old_parent_inode.move_to(old_filename, &new_parent_inode, new_filename)?;
return Ok(0);
}
/// @brief 根据提供的文件描述符的fd复制对应的文件结构体并返回新复制的文件结构体对应的fd
pub fn dup(oldfd: i32) -> Result<usize, SystemError> {
let binding = ProcessManager::current_pcb().fd_table();

View File

@ -24,7 +24,7 @@ use crate::{
arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch},
driver::base::block::SeekFrom,
filesystem::vfs::{
fcntl::FcntlCommand,
fcntl::{AtFlags, FcntlCommand},
file::FileMode,
syscall::{ModeType, PosixKstat, SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET},
MAX_PATHLEN,
@ -107,6 +107,35 @@ impl Syscall {
res
}
SYS_RENAME => {
let oldname: *const u8 = args[0] as *const u8;
let newname: *const u8 = args[1] as *const u8;
Self::do_renameat2(
AtFlags::AT_FDCWD.bits(),
oldname,
AtFlags::AT_FDCWD.bits(),
newname,
0,
)
}
SYS_RENAMEAT => {
let oldfd = args[0] as i32;
let oldname: *const u8 = args[1] as *const u8;
let newfd = args[2] as i32;
let newname: *const u8 = args[3] as *const u8;
Self::do_renameat2(oldfd, oldname, newfd, newname, 0)
}
SYS_RENAMEAT2 => {
let oldfd = args[0] as i32;
let oldname: *const u8 = args[1] as *const u8;
let newfd = args[2] as i32;
let newname: *const u8 = args[3] as *const u8;
let flags = args[4] as u32;
Self::do_renameat2(oldfd, oldname, newfd, newname, flags)
}
SYS_OPENAT => {
let dirfd = args[0] as i32;
let path: &CStr = unsafe { CStr::from_ptr(args[1] as *const c_char) };
@ -1030,6 +1059,17 @@ impl Syscall {
)
}
SYS_FADVISE64 => {
// todo: 这个系统调用还没有实现
Err(SystemError::ENOSYS)
}
SYS_NEWFSTATAT => {
// todo: 这个系统调用还没有实现
Err(SystemError::ENOSYS)
}
SYS_SCHED_YIELD => Self::sched_yield(),
_ => panic!("Unsupported syscall ID: {}", syscall_num),