关于Linux的虚拟文件系统有很多解释和书籍部分,包括SOF中的这里。 但是我仍然对结构 dentry和结构 inode之间的关系以及文件名和 Inode 之间的映射感到有些困惑。
我认为 dentry 是文件系统定位 inode 的方式,但它在每个参考中都说我读到 dentry 对象在内存中,所以一旦重新启动机器,如何找到新创建的文件?
因此,当您使用路径/a/b/c创建一个文件,然后想要打开此文件时,文件系统如何找到它? 如果你可以在你的答案中同时引用dentry和Inode对象
文件系统由两个主要的行为块组成:
- 磁盘格式,存储的数据在持久媒体上的表示方式。
- 访问存储数据时进程、内核代码和硬件之间的同步。
像 FAT32 这样的文件系统具有可以在 Windows、Mac 和 Linux 中读取的磁盘格式 - 磁盘格式保持不变,但同步和访问部分因操作系统而异。
文件系统的磁盘格式,如UFS和ext3,实际上大多数Unix培育的文件系统都定义了"inode"和"dentry"的概念。FAT32 和 SMB 则不然。
尽管如此,Linux 和其他内核发现跨不同磁盘格式的通用代码非常有用,因此创建了 VFS 抽象层。这个抽象层只存在于内存中;它不会向各个文件系统指示有关磁盘格式的任何信息。
但是,VFS的抽象(单个文件系统需要实现的API)定义了struct inode
和struct dentry
等数据结构 - 但它们仅存在于内存中。
例如,ext4在内存中inode和dentry到磁盘inode和dentries之间有一个相当直接的映射。它具有相应的struct ext4_inode
(存储在i_private
中)和struct ext4_dir_entry
(存储在d_fsdata
中)。
因此,在 ext4 上,查找/a/b/c
通过以下方式完成:
- 获取根
struct inode
,该根在挂载时已缓存在 VFS 中 - 要求 ext4 从该 inode 加载
a
。 - 索引节点的内容是一个
ext4_dir_entry
s的列表(嗯,可能是一个更复杂的数据结构) - ext4 会找到正确的 - ext4 将查看
ext4_dir_entry
的索引节点编号,并将ext4_inode
加载到 VFS 缓存中的struct inode
中。 - 使用缓存的
struct inode
和ext4_dir_entry
,ext4 将构建一个struct dentry
并将其返回给 VFS。 - VFS 将查看 dentry 的 inode,并要求 ext4 从中加载
b
。 - 该过程重复。
请注意,VFS 的抽象并非 100% 对应于 ext4:
struct dentry
不包含索引节点编号 - 必须加载索引节点struct dentry
缓存索引节点的类型,而ext4_dir_entry
则不缓存。struct dentry
可以是负数,这意味着它会缓存文件不存在的事实,因此,如果您运行ls x; ls x
并且x
不存在,则不会第二次转到磁盘。