1. 要查找文件,首先查找文件所在目录。例如查找/usr/bin/ls文件,那么首先知道bin目录“信息”, 查询bin目录,首先知道usr目录“信息”,这样形成一个递归过程。但是递归过程必需一个终结条件,否则会存在鸡生蛋还是蛋生鸡问题。其实终结条件是“/”根“信息”,必须默认知道。
下面讨论一下,具体文件系统ext2(3,4)。上面所指”信息“,其实就是磁盘文件系统中inode节点,记住一个inode节点对应磁盘上一个文件,因为inode节点是唯一描述文件属性信息(大小,位置,时间等等)。另外在该文件系统中,目录也是文件,也有对应inode节点。回到上面问题,那么默认“/”根“目录inode节点是什么呢?根目录inode节点号”EXT2_ROOT_INO“(2)。注意inode 计数是从 1 开始的。
2. 上面是一次查找过程,但是第二次查找同样需要从磁盘再次读取。我们知道从磁盘读取信息性能很差,所以就想到可以缓存inode节点信息在内存中。另外还有一个问题,目录是一个文件,它的存放内容至少包括文件名,目录名。这样需要读取其内容,比较要查找文件和目录名。又涉及到读磁盘操作,性能存在改进。我们可以把第一次查询的文件名和目录名,把其构建数据结构dentry, 并缓存到内存中, 这些构建数据结构称之为”目录项“。 这样拥有了inode缓存和dentry缓存,接下来从两者缓存中查找/usr/bin/ls文件。当查找时,依次在目录项缓存中查找比较"/" “usr” "bin" "ls"字符串, 成功后,从目录项数据结构中,获取指向inode指针,这样就可以容易而快速定位到文件。
由文件名,得到目录项,有目录项知道inode,由inode得到磁盘数据。
struct dentry {
struct inode *d_inode;
}
struct inode {struct address_space *i_mapping;//
struct address_space i_data;
}
上面存在另外问题,如果每次从磁盘上读取数据,性能有待改进,所以希望建立缓存,称之为页缓存,上面数据结构struct address_space 描述磁盘数据缓冲。