Linux文件系统基础之inode和dentry
inode(节点)和dentry(目录项)在VFS和实体的文件系统(ext2、ext3等)中都是比较重要的概念。首先看一下虚拟文件系统的标准定义:虚拟文件系统(英语:Virtual file system,缩写为VFS),又称虚拟文件切换系统(virtual filesystem switch),是操作系统的文件系统虚拟层,在其下是实体的文件系统。虚拟文件系统的主要功用在于让上层的软件,能够用单一的方式,来跟底层不同的文件系统沟通。在操作系统与之下的各种文件系统之间,虚拟文件系统提供了标准的操作接口,让操作系统能够很快的支持新的文件系统。
VFS在Linux系统中的结构为:
在教科书上面,一般是这样描述inode的:inode是内核文件对象的元数据。inode中不包括文件的数据和文件名字信息。inode中只包含数据块的位置信息,数据结构相对稳定,其中没有数据和文件名等变长数据,可以固定其大小,进而可以实现将整个文件系统中的inode按照一定的组织方式来集中存储在硬盘起始的一个,文件系统加载时,可以方便查找即可。
inode仅仅只是保存了文件对象的属性信息,包括:权限、属组、数据块的位置、时间戳等信息。但是并没有包含文件名,文件在文件系统的目录树中所处的位置信息。那么内核又是怎么管理文件系统的目录树呢?
dentry在内核中起到了连接不同的文件对象inode的作用,进而起到了维护文件系统目录树的作用。dentry是一个纯粹的内存结构,由文件系统在提供文件访问的过程中在内存中直接建立。dentry中包含了文件名,文件的inode号等信息。
对于POSIX标准定义了文件系统的inode。VFS接口即是符合POSIX标准的,实体文件系统只要能对接上VFS,即可符合POSIX标准。因此,一般而言我们研究VFS文件系统即可了解大部分文件系统的结构。而在VFS中,定义了规范化的inode结构和dentry。
在读取一个文件时,总是从根目录开始读取,每一个目录或者文件,在VFS中,都是一个文件对象,每一个文件对象都有唯一的一个inode与之对应。根目录的inode号为0,在superblock里,可以很快根据inode号索引到具体的inode,因此读取到的第一个inode就是根目录的。读取到了该目录后,内核对象会为该文件对象建立一个dentry,并将其缓存起来,方便下一次读取时直接从内存中取。而目录本身也是一个文件,目录文件的内容即是该目录下的文件的名字与inode号,目录文件的内容就像一张表,记录的文件名与其inode no.之间的映射关系。根据路径即可找到当前需要读取的下一级文件的名字和inode,同时继续为该文件建立dentry,dentry结构是一种含有指向父节点和子节点指针的双向结构,多个这样的双向结构构成一个内存里面的树状结构,也就是文件系统的目录结构在内存中的缓存了。有了这个缓存,我们在访问文件系统时,通常都非常快捷。
有了inode和dentry,也就非常容易理解文件的连接了。我们知道软连接,是一个特殊的文件,该文件通过内容指向目标文件。因此软连接有自己的inode,有自己的内容。其内容记录的是目标文件的inode号和自身的名字。软连接是一种特殊的文件。而硬链接则不一样,硬链接是文件的别名,硬链接不是一个完整的文件对象,硬链接只是将自己的名字写在上级目录的内容(文件名与inode no.的映射表)中。而其inode号即是目标文件的inode。这样硬连接与目标文件一起共用一个inode,使用引用计数来管理硬连接。