feat(fadvise64): 实现fadvise64系统调用和页面缓存管理功能#1439
feat(fadvise64): 实现fadvise64系统调用和页面缓存管理功能#1439fslongjin merged 9 commits intoDragonOS-Community:masterfrom
Conversation
xboHodx
commented
Dec 5, 2025
- 新增fadvise64系统调用实现
- 添加页面缓存范围写回和驱逐功能
- 改进预读机制,支持随机访问模式
- 扩展文件访问模式标志管理
- 新增fadvise64系统调用实现 - 添加页面缓存范围写回和驱逐功能 - 改进预读机制,支持随机访问模式 - 扩展文件访问模式标志管理
|
@claude review this pr in Chinese |
|
Claude finished @fslongjin's task —— View job 代码审查:feat(fadvise64) 系统调用实现待办事项清单:
代码审查反馈总体评价这是一个设计良好的PR,实现了 主要问题1. sys_fadvise64.rs 中的问题a) 错误的文件注释 (第1行) //! System call handler for the brk system call.
应该改为 b) 边界检查逻辑需要澄清 (第107-109行) if len < 0 || inode.page_cache().is_none() {
return Err(SystemError::EINVAL);
}根据POSIX规范, c) endbyte 计算可能有问题 (第118-121行) let mut endbyte = offset as u64 + len as u64;
if len == 0 || endbyte < len as u64 {
endbyte = i64::MAX as u64;
}
let mut endbyte = offset.checked_add(len).ok_or(SystemError::EINVAL)? as u64;
if len == 0 {
endbyte = u64::MAX; // 或文件大小
}d) 未使用的导入 (第3行) e) DontNeed 处理的页索引计算 (第153行) let start_index = (offset as usize + MMArch::PAGE_SIZE - 1) >> MMArch::PAGE_SHIFT;可以简化为: let start_index = page_align_up(offset as usize) >> MMArch::PAGE_SHIFT;2. page_cache.rs 中的问题a) 魔法数字需要解释 (第359行) if Arc::strong_count(page) <= 3 {为什么是3?需要添加注释说明每个引用的来源(例如:1个page_cache引用,1个当前guard引用等)。 b) 缺少参数验证 3. 代码风格和可读性a) 复杂的条件表达式 (sys_fadvise64.rs 第156-163行) if (endbyte as usize & !(MMArch::PAGE_SIZE - 1)) != !(MMArch::PAGE_SIZE - 1)
&& endbyte != inode.metadata()?.size as u64 - 1
{
// ...
}建议提取为辅助函数或添加详细注释。 b) 日志和调试代码 建议的改进
测试建议
总结这个PR实现了核心功能,代码质量良好。建议在合并前修复上述问题,特别是:
这些改进将提高代码的可维护性和健壮性。 审查完成 ✅ |
- 在FileDescriptorVec中新增get_file_by_fd_not_raw方法 - 修改sys_fadvise64使用新方法进行权限检查
|
@claude review this pr in Chinese |
|
Claude finished @fslongjin's task —— View job Claude正在处理 @fslongjin 的任务 待办事项清单
代码审查反馈总体评价这是一个设计良好的PR,成功实现了 主要问题1. sys_fadvise64.rs 中的问题a) 复杂条件表达式需要注释 (第154-162行) if (endbyte & !(MMArch::PAGE_SIZE - 1)) != !(MMArch::PAGE_SIZE - 1)
&& endbyte != inode.metadata()?.size as usize - 1
{
if end_index == 0 {
return Ok(0);
}
end_index -= 1;
}这个条件判断逻辑复杂,意图是"如果要驱逐的最后一页不是整页,则需要保留"。建议提取为辅助函数或添加详细注释说明。 b) 边界情况处理需要澄清 (第105-107行) if len < 0 || inode.page_cache().is_none() {
return Err(SystemError::EINVAL);
}根据POSIX规范, 2. page_cache.rs 中的问题a) 缺少参数验证 b) 锁粒度过细 3. 系统调用集成问题a) 遗留的存根实现 ( SYS_FADVISE64 => {
// todo: 这个系统调用还没有实现
Err(SystemError::ENOSYS)
}这个存根实现仍然存在,虽然系统调用表宏可能覆盖它,但为了代码清晰性,应该移除或更新这个存根。 4. 代码风格和可读性a) 日志和调试代码 b) 错误处理一致性 建议的改进
测试建议
总结这个PR实现了核心功能,代码质量良好。主要改进点在于:
建议在合并前修复上述问题,特别是参数验证和遗留存根清理,这些改进将提高代码的健壮性和可维护性。 审查完成 ✅ |
这个地方应当用 |
| let mut ra_state = file.ra_state.lock().clone(); | ||
| force_page_cache_readahead(&page_cache, &inode, &mut ra_state, start_page, page_num)?; | ||
| *file.ra_state.lock() = ra_state; |
There was a problem hiding this comment.
如果仅仅是为了这个需求,那么ra_state不应该pub,而是应该封装成函数来操作。
并且如果并发的对同一file结构体进行了这个操作。那么ra_state可能就是不正确的。
| PosixFadviseFlag::Sequential => { | ||
| file.set_ra_pages(MAX_READAHEAD * 2); | ||
| file.remove_mode_flags(FileMode::FMODE_RANDOM); | ||
| } |
There was a problem hiding this comment.
这两个操作不是原子的,中间会有个并发窗口,这样是否会造成问题?或许可以考虑封装成函数来处理set_ra_flag + remove_mode_flags 这一套操作。
There was a problem hiding this comment.
fadvise64这个系统调用没必要保证原子性,因为它只是建议,这里发生并发冲突可能会导致效率不高,但不会产生损害。linux中也没有保证原子性
这个我写错了,应该写 |
- 将File结构体的ra_state字段改为私有并提供get/set方法 - 在sys_fadvise64中使用新的访问方法 - 修复fadvise64中页边界检查逻辑 - 移除syscall模块中未实现的fadvise64 stub
