feat(filesystem): 完善 rename 系统调用实现 (#1540)

- 在 kernfs 中处理重命名到自身的特殊情况
- 在 renameat2 系统调用中添加权限检查
- 从测试黑名单中移除已实现的测试项
- 在测试白名单中添加 munmap_test

Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
LoGin 2025-12-23 18:21:25 +08:00 committed by GitHub
parent 4617e967ae
commit b71a265aff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 40 additions and 13 deletions

View File

@ -226,12 +226,29 @@ impl IndexNode for KernFSInode {
fn move_to(
&self,
_old_name: &str,
_target: &Arc<dyn IndexNode>,
_new_name: &str,
old_name: &str,
target: &Arc<dyn IndexNode>,
new_name: &str,
_flags: RenameFlags,
) -> Result<(), SystemError> {
// 应当通过kernfs的其它方法来操作文件而不能从用户态直接调用此方法。
// 处理重命名到自身的特殊情况
// 如果源目录和目标目录是同一个 inode且文件名相同则直接返回成功
// 这符合 Linux 的 rename 语义:重命名到自身是一个空操作
if let Some(target_kernfs) = target.clone().downcast_arc::<KernFSInode>() {
// 使用 Arc::ptr_eq 比较两个 Arc 是否指向同一个对象
// 通过 self_ref.upgrade() 获取 Arc<KernFSInode>
let self_arc = self.self_ref.upgrade().ok_or(SystemError::ENOENT)?;
let target_arc = target_kernfs
.self_ref
.upgrade()
.ok_or(SystemError::ENOENT)?;
if Arc::ptr_eq(&self_arc, &target_arc) && old_name == new_name {
return Ok(());
}
}
// 其他情况返回 ENOSYSsysfs/kernfs 不支持真正的重命名操作)
return Err(SystemError::ENOSYS);
}

View File

@ -1,3 +1,4 @@
use crate::filesystem::vfs::permission::PermissionMask;
use crate::filesystem::vfs::syscall::RenameFlags;
use crate::filesystem::vfs::utils::is_ancestor;
use crate::filesystem::vfs::utils::rsplit_path;
@ -83,6 +84,23 @@ pub fn do_renameat2(
// 这会把同目录/向上移动的合法情况误判为 ENOTEMPTY。
// 非空目录覆盖应由具体文件系统在 move_to/rename 实现中返回 ENOTEMPTY。
// 权限检查:根据 Linux 语义rename 需要对源父目录和目标父目录都拥有写+搜索权限
let cred = pcb.cred();
// 检查源父目录的写+搜索权限(需要删除旧目录项)
let old_parent_metadata = old_parent_inode.metadata()?;
cred.inode_permission(
&old_parent_metadata,
(PermissionMask::MAY_WRITE | PermissionMask::MAY_EXEC).bits(),
)?;
// 检查目标父目录的写+搜索权限(需要创建新目录项)
let new_parent_metadata = new_parent_inode.metadata()?;
cred.inode_permission(
&new_parent_metadata,
(PermissionMask::MAY_WRITE | PermissionMask::MAY_EXEC).bits(),
)?;
old_parent_inode.move_to(old_filename, &new_parent_inode, new_filename, flags)?;
return Ok(0);
}

View File

@ -1,9 +0,0 @@
RenameTest.DirectoryOverwritesDirectoryLinkCount
# 权限相关未实现
RenameTest.FailsWhenOldParentNotWritable
RenameTest.FailsWhenNewParentNotWritable
RenameTest.OverwriteFailsWhenNewParentNotWritable
RenameTest.FileDoesNotExistWhenNewParentNotExecutable
# 相关系统调用未实现
RenameTest.SysfsFileToSelf
RenameTest.SysfsDirectoryToSelf

View File

@ -63,6 +63,7 @@ prctl_test
# 内存管理测试
mmap_test
munmap_test
brk_test
mincore_test
madvise_test