feat(filesystem): 完善 rename 系统调用实现 (#1540)
- 在 kernfs 中处理重命名到自身的特殊情况 - 在 renameat2 系统调用中添加权限检查 - 从测试黑名单中移除已实现的测试项 - 在测试白名单中添加 munmap_test Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
4617e967ae
commit
b71a265aff
|
|
@ -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(());
|
||||
}
|
||||
}
|
||||
|
||||
// 其他情况返回 ENOSYS(sysfs/kernfs 不支持真正的重命名操作)
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
RenameTest.DirectoryOverwritesDirectoryLinkCount
|
||||
# 权限相关未实现
|
||||
RenameTest.FailsWhenOldParentNotWritable
|
||||
RenameTest.FailsWhenNewParentNotWritable
|
||||
RenameTest.OverwriteFailsWhenNewParentNotWritable
|
||||
RenameTest.FileDoesNotExistWhenNewParentNotExecutable
|
||||
# 相关系统调用未实现
|
||||
RenameTest.SysfsFileToSelf
|
||||
RenameTest.SysfsDirectoryToSelf
|
||||
|
|
@ -63,6 +63,7 @@ prctl_test
|
|||
|
||||
# 内存管理测试
|
||||
mmap_test
|
||||
munmap_test
|
||||
brk_test
|
||||
mincore_test
|
||||
madvise_test
|
||||
|
|
|
|||
Loading…
Reference in New Issue