-
-
Notifications
You must be signed in to change notification settings - Fork 176
feat(ext4): 添加mknod函数 #1759
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
base: master
Are you sure you want to change the base?
feat(ext4): 添加mknod函数 #1759
Conversation
Signed-off-by: xboHodx <xbohodx2024@gmail.com>
Signed-off-by: xboHodx <xbohodx2024@gmail.com>
Signed-off-by: xboHodx <xbohodx2024@gmail.com>
kernel/src/filesystem/ext4/inode.rs
Outdated
| // 字符设备/块设备需要存储设备号,但 another_ext4 crate 暂不支持 | ||
| // TODO: 修改 another_ext4 使用 i_block[0:1] 存储 dev_t(Linux ext4 标准做法) | ||
| if mode.contains(InodeMode::S_IFCHR) || mode.contains(InodeMode::S_IFBLK) { | ||
| log::error!( | ||
| "ext4::mknod: device nodes not supported (filename='{}', dev={}:{})", | ||
| filename, | ||
| dev_t.major().data(), | ||
| dev_t.minor() | ||
| ); | ||
| return Err(SystemError::ENOSYS); | ||
| } | ||
|
|
||
| let mut guard = self.0.lock(); | ||
| let ext4 = &guard.concret_fs().fs; | ||
| let inode_num = guard.inner_inode_num; | ||
|
|
||
| // 确保当前 inode 是目录 | ||
| if ext4.getattr(inode_num)?.ftype != FileType::Directory { | ||
| return Err(SystemError::ENOTDIR); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
参考下fat?
|
@claude review 下,思考这个更改是否合理。有没有更好的 |
|
Claude finished @fslongjin's task in 11m 11s —— View job Claude 代码审查正在分析 PR #1759 的更改,该 PR 添加了 ext4 文件系统的 mknod 函数。 当前任务列表:
最终审查总结经过全面分析,以下是我的完整审查意见: 1. 当前实现评价优点:
主要问题:
2. 与其他文件系统实现的比较参考了 DragonOS 中多个文件系统的
3. 具体改进建议a. 添加 FIFO 支持(关键缺失)参考 if mode.contains(InodeMode::S_IFIFO) {
// 创建管道 inode
let pipe_inode = LockedPipeInode::new();
pipe_inode.set_fifo(); // 标记为命名管道
// 创建 ext4 inode(底层存储)
let id = ext4.create(inode_num, filename, file_mode)?;
let vfs_inode = LockedExt4Inode::new(...);
// 设置 special_node 存储管道数据
vfs_inode.0.lock().special_node = Some(SpecialNodeData::Pipe(pipe_inode));
return Ok(vfs_inode);
}b. 改进模式转换安全性// 确保只传递 another_ext4 支持的位
let ext4_mode_bits = mode.bits() & 0x1FF; // 标准 Unix 权限位(9位)
let file_mode = another_ext4::InodeMode::from_bits_truncate(ext4_mode_bits as u16);c. 统一错误处理
d. 未来设备节点支持保持当前 // TODO: 需要修改 another_ext4 库以支持设备号存储
// Linux ext4 标准做法:使用 inode->i_block[0:1] 存储 dev_t
// 参见:https://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html#special-inodes4. 更好的实现方式建议重构方案:
5. 结论当前 PR 的合理性:基础合理,但不完整。作为 建议操作:
如果我是代码维护者:我会要求作者至少添加 FIFO 支持后再合并,因为这是 行动建议
最终建议:要求作者补充 FIFO 支持后合并此 PR。设备节点支持可后续实现。 |
- 实现设备节点创建(mknod)和属性获取 - 添加设备号编码/解码工具函数 - 扩展Inode结构支持设备号存储 - 添加相关单元测试 Signed-off-by: xboHodx <xbohodx2024@gmail.com>
Signed-off-by: xboHodx <xbohodx2024@gmail.com>
Signed-off-by: xboHodx <xbohodx2024@gmail.com>
- 添加DeviceNumber::from_linux_dev_t方法解析Linux dev_t格式 - 在ext4 inode中增加special_node字段支持FIFO管道 - 修复设备节点元数据中的dev_id和raw_dev处理 - 更新mknod/mknodat系统调用使用新的dev_t解析方法 Signed-off-by: xboHodx <xbohodx2024@gmail.com>
- 移除不必要的文件打开/关闭操作 - 使用do_newfstatat替代原有实现 Signed-off-by: xboHodx <xbohodx2024@gmail.com>
|
单元测试和集成测试加起来有1300行hhh |
|
@codex review下功能设计是否合理、并且有无并发问题 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f170d43847
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Create device inode (uses create_device_inode which sets device number) | ||
| let mut child = self.create_device_inode(mode, major, minor)?; | ||
|
|
||
| // Link to parent directory | ||
| self.link_inode(&mut parent_ref, &mut child, name)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleanup device inode on link failure to avoid leaks
If another thread creates the same name between the caller’s existence check and this link, link_inode can fail (e.g., EEXIST). In that case the freshly allocated device inode is left on disk with no directory entry, leaking an inode and potentially exhausting the inode table over time. This is a concurrency window introduced by the new mknod path; consider checking for name existence inside Ext4::mknod and/or freeing the inode on error (similar to rollback logic) so failed links don’t orphan device inodes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mknod的父目录在这个过程是被加锁了的,应该不存在并发窗口。见kernel/src/filesystem/ext4/inode.rs:542
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@codex 看看这个呢?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f170d43847
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Create device inode (uses create_device_inode which sets device number) | ||
| let mut child = self.create_device_inode(mode, major, minor)?; | ||
|
|
||
| // Link to parent directory | ||
| self.link_inode(&mut parent_ref, &mut child, name)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Free the allocated inode when linking fails
If link_inode fails (e.g., dir_add_entry hits ENOSPC when it has to append a directory block), this path returns early with an error but the device inode allocated by create_device_inode has already been written to disk and the inode bitmap updated. That leaves an unlinked inode leak and inconsistent free-inode counts for the filesystem. Consider cleaning up (free_inode) on error from link_inode so that mknod behaves transactionally when the directory insert cannot be completed.
Useful? React with 👍 / 👎.
- 新增link_new_inode_or_free方法,在链接失败时自动清理新分配的inode - 在create_file和mknod中使用新方法替代直接调用link_inode Signed-off-by: xboHodx <xbohodx2024@gmail.com>
但是因为another_ext4库不支持创建块设备和字符设备节点,所以暂时没办法完全实现mknod
2026/2/5
Summary
mknod系统调用支持,包括字符设备、块设备、FIFO 等特殊文件类型sys_stat系统调用,修复设备节点元数据返回不正确的问题Changes
1. ext4 设备节点支持 (
another_ext4crate)kernel/crates/another_ext4/src/ext4_defs/inode.rsdevice模块,实现 Linux 兼容的设备号编解码:major < 256 && minor < 256Inode::is_device(),Inode::device(),Inode::set_device()方法FileAttr新增rdev字段存储设备号kernel/crates/another_ext4/src/ext4/alloc.rscreate_device_inode()方法:i_block[0..1](遵循 Linux ext4 标准)kernel/crates/another_ext4/src/ext4/low_level.rsmknod()方法创建设备节点getattr()现在正确返回设备节点的rdev2. VFS 层集成
kernel/src/filesystem/ext4/inode.rsIndexNode::mknod()trait 方法S_IFCHR):调用 ext4 mknod 存储设备号S_IFBLK):调用 ext4 mknod 存储设备号S_IFIFO):创建普通 inode 并关联 pipeS_IFREG):委托给create()special_node字段和special_node()方法,支持 FIFO 的 pipe inodemetadata()返回:dev_id: 正确返回文件系统设备号 (st_dev)raw_dev: 仅对设备节点返回st_rdev3. 系统调用重构
kernel/src/filesystem/vfs/syscall/sys_mknod.rs&sys_mknodat.rsS_IFMT) 和权限位from_linux_dev_t()正确解码用户空间dev_tkernel/src/filesystem/vfs/syscall/sys_stat.rsdo_newfstatat()而非 open/fstat/closekernel/src/driver/base/device/device_number.rsfrom_linux_dev_t()方法:makedev()/major()/minor()编码格式4. 测试
user/apps/c_unitest/test_mknod.c(923 lines)Technical Notes
Linux ext4 设备号存储格式
设备号存储在 i_block[0..1]:
这与常规文件使用 extent tree 是互斥的——设备节点绝不能调用
extent_init()。FIFO 实现
FIFO 在 ext4 中作为普通 inode 存储(无 extent 数据),运行时关联一个
PipeInode实现进程间通信。Test plan
test_mknod测试套件/dev/null,/dev/zero等标准设备节点的 stat 输出