linux文件系统体系结构通过使用一组通用的API函数,实现了对不同具体文件系统的抽象化。
一、文件系统的体系结构
图1中显示了用户空间和内核中与文件系统相关的主要组件之间的关系
图1文件系统的体系结构
用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C 库(glibc),它们为文件系统调用(打开、读取、写和关闭)提供用户接口。系统调用接口的作用就像是交换器,它将系统调用从用户空间发送到内核空间中的适当端点。
VFS 是底层文件系统的主要接口。这个组件导出一组接口,然后将它们抽象到各个文件系统,各个文件系统的行为可能差异很大。有两个针对文件系统对象的缓存(inode 和 dentry)。它们缓存最近使用过的文件系统对象。
二、文件系统的主要结构
文件系统中主要有四种数据结构,分别是超级块对象(superblock)、索引节点对象(inode)、目录项对象(dentry )和文件对象(file)。
超级块对象(super_block):存储一个已安装的文件系统的控制信息(文件系统的状态、文件系统类型、块大小、区块数、索引节点数、脏标志、操作方法),它代表一个已安装的文件系统;每次一个实际的文件系统被安装时,内核会从磁盘的特定位置(磁盘的超级块位置)读取一些控制信息来填充内存中的超级块对象。
索引节点对象(inode):存储了文件和目录的相关信息(和文件本身是两个不同的概念。它包含的是诸如文件的大小、拥有者、创建时间、磁盘位置、文件操作方法、脏标示等和文件相关的信息),代表一个实质的文件,在磁盘保存有该对象。当一个文件首次被访问时,内核会在内存中组装相应的索引节点对象,以便向内核提供对一个文件进行操作时所必需的全部信息。
目录项对象(dentry):它代表一个目录项(包括该目录对象对应的索引节点,子目录链表,父目录目录项对象,与它同级的目录的目录项对象链表,使用计数,缓存标志),是路径的一个组成部分(注:路径中的每个组成部分都由一个索引节点对象表示)。该对象只存放在内存中。
文件对象(file):是已打开的文件在内存中的表示(包括相应的目录项对象、使用计数、访问模式、当前偏移量、操作方法等),主要用于建立进程和磁盘上的文件的对应关系。它由sys_open() 现场创建。
当三个不同的进程打开相同的文件时,其中两个使用相同路径,如图2所示。
图2进程与file、dentry,inode,super_block的关系
这种情况下, 三个进程都拥有自己的file对象,其中两个使用相同路径的共用一个dentry对象,这两个dentry对象指向同一个inode对象,对应唯一的一个超级块对象,和同一个磁盘文件。
其他主要的数据结构还有:
file_system_type:用于描述具体的文件系统的类型信息,所以被Linux支持的文件系统,都有且仅有一个file_system_type结构而不管它有零个或多个实例被安装到系统中。如ext2,ext3,NFS。
安装点(vfsmount):当一个文件系统被实际安装,就有一个vfsmount结构体被创建,这个结构体对应一个安装点。与超级块一样(即与超级块是一一对应的),但没有存放在磁盘中。它包括安装点的相关信息,如位置和安装标志等。
三、文件系统的使用
(1) 文件系统的创建(mkfs.xxx)
即是存储设备建立文件系统的过程,一般也被称为格式化或初始化,通过一些初始化工具来进行。一般的情况下每个类型的操作系统都有这方面的工具,也有多功能的第三方工具。在Linux中有 mkfs系列工具
[root@RedHat ~]# mkfs. mkfs.cramfs mkfs.ext3 mkfs.ext4dev mkfs.vfat mkfs.ext2 mkfs.ext4 mkfs.msdos
(2)文件系统的挂载(mount):
这一过程可简单描述为:将某一设备(dev_name)上某一文件系统(file_system_type)安装到VFS目录树上的某一安装点(dir_name)。
(3) 其他操作:目录操作,目录创建、目录删除等操作,及其文件操作等。
后续会慢慢分析相关技术点。