两个问题
问题 1
Ext4Inode 杂糅了 inode 和 dentry ,把两类本应分层的数据放在了一起:
- inode:
inner_inode_num、page_cache、元数据读写入口
- dentry:
dname、parent、children 名字缓存
结果是 LockedExt4Inode 这把锁同时覆盖“文件对象状态”和“目录项关系状态”,但又不是按真实 inode 号全局唯一,因此既不像纯 inode 锁,也不像纯 dentry 锁,语义会混杂。
问题 2
linux 中,同一目录下的目录项修改操作要互斥,即create/mkdir/link/unlink/rmdir/rename不能并发改同一个父目录目录项集合,这就需要 i_rwsem 这个 inode 锁;
而DragonOS 使用 Arc<LockedExt4Inode> ,但是这玩意在以下情况是不同的:
- 磁盘上本来就有两个硬链接名(同父目录或不同父目录),分别第一次被
find()
- 同一个父目录 inode 出现了多个 LockedExt4Inode 实例时,每个实例有各自独立 children 缓存;从不同父实例出发查同一子项,会各自 new 出不同子对象
所以不能用来代替 i_rwsem。
修复方向:
- 直接锁磁盘 inode号(linux 中的
inode->i_ino),使用 another_ext4 提供的 inode 号,vfs 的 inode 号是 LockedExt4Inode 的而不是磁盘上的 inode 的。这样的话还得记录文件系统,因为不同文件系统可能有相同的 inode 号。最终考虑 (fs_identity, inner_inode_num) 到锁的映射
- 修改
LockedExt4Inode,使其能够代表磁盘 inode 的唯一对象。
两个问题
问题 1
Ext4Inode杂糅了inode和dentry,把两类本应分层的数据放在了一起:inner_inode_num、page_cache、元数据读写入口dname、parent、children名字缓存结果是
LockedExt4Inode这把锁同时覆盖“文件对象状态”和“目录项关系状态”,但又不是按真实 inode 号全局唯一,因此既不像纯 inode 锁,也不像纯 dentry 锁,语义会混杂。问题 2
linux 中,同一目录下的目录项修改操作要互斥,即create/mkdir/link/unlink/rmdir/rename不能并发改同一个父目录目录项集合,这就需要
i_rwsem这个 inode 锁;而DragonOS 使用
Arc<LockedExt4Inode>,但是这玩意在以下情况是不同的:find()所以不能用来代替
i_rwsem。修复方向:
inode->i_ino),使用 another_ext4 提供的 inode 号,vfs 的 inode 号是LockedExt4Inode的而不是磁盘上的 inode 的。这样的话还得记录文件系统,因为不同文件系统可能有相同的 inode 号。最终考虑(fs_identity, inner_inode_num)到锁的映射LockedExt4Inode,使其能够代表磁盘 inode 的唯一对象。