有关于Linux文件系统的发展历史可以参考http://e2fsprogs.sourceforge.net/ext2intro.html
虚拟文件系统VFS
Linux支持多种不同类型的文件系统:网络文件系统NFS,磁盘文件系统Extfs,特殊文件系统proc、tmpfs等。为了更方便的在系统中集成多个不同的文件系统,Linux实现了一层叫做Virtual File System的layer,其在系统中的层次结构如下图。
VFS直接处理文件操作相关的系统调用,然后根据文件系统类型将这些调用重定向到底层文件系统的接口,底层文件系统再通过buffer cache向设备发起I/O请求(仅限于块I/O,字符设备的I/O没有buffer cache参与)。
VFS定义了文件系统基本操作的函数集合,底层的文件系统(Ext2fs...)都要实现这个函数集合。kernel维护着一张记录了所有支持的文件系统类型的表,在这张表里面,记录了每个文件系统类型的名字和mount时要执行的函数的指针,当文件系统被mount到某个挂载点时,这个mount函数就会被执行,它会读取磁盘上的superblock,初始化一些数据,并且将mount后的文件系统描述符返回给VFS,VFS则通过这个文件系统描述符来访问底层文件系统。
Ext2fs
实际上Ext2fs之前还有Extfs,但是这个版本问题比较多,并且缺乏很多的基本特性支持(比如3个时间戳),没有得到广泛使用,所以我们直接从Ext2fs开始学习。
Ext2fs基本概念
Inode
Ext2fs中,每个文件都用如下图所示的inode结构来描述,用户空间操作的对象是文件路径和名称,系统kernel把路径名称解析成inode,通过inode号来访问它代表的文件。
转存失败重新上传取消
转存失败重新上传取消
转存失败重新上传取消
Mode:包含两个数据,文件类型(普通文件/目录/字符设备/块设备/符号链接/管道)和用户访问权限信息(0660)。
Owner info:文件属组信息。
Size:文件长度,单位是byte。
Timestamps:文件访问和修改的时间戳。
Links count:这个项在上图中没有体现,它记录了这个inode存在多少个链接,创建新文件时,其inode的links count应该为1,文件被删除后,这个inode的links count就变为0。
Data Blocks:指向真实的文件数据块,因为大文件可能会分配很多的block,直接在inode中保存所有的数据块指针将会比较困难,也会浪费掉很多空间,毕竟系统中大文件的数量是占少数的,所以设计了间接块指针(Indirect blocks)和二级块指针(Double blocks)来指向真实数据块。
实际上还应该包含了inode号。
目录
在Ext2fs中,目录被看做一种特殊文件,也用一个inode来描述,目录的data block中保存了目录下的所有内容,每条内容叫做一个entry,结构如下:
每条entry都保存了inode号、entry的长度、文件名长度、文件类型,并且都是4字节对齐。
特别地,每个目录下有两个特殊的子目录,'.'和'..',分别代表当前目录和上一级目录,这两个目录文件其实是硬链接。其中'..'有一个重要的作用:FS checker(可以把文件系统umount后手动执行e2fsck看看)在检查文件系统的时候,就会使用’..‘来检查目录是否可以追溯到挂载根目录,如果检查失败,目录便会被链接到挂载根目录下面的lost+found。
链接
为了方便系统内文件共享,Linux支持了两种基本的链接文件:硬链接和软链接(也叫符号链接)。
硬链接并不是一个独立的文件,不占用inode,只是在目录下创建了一条entry,其中inode号保存的是目标文件的inode号,访问硬链接时,文件系统通过inode将访问操作重定向到目标文件,实现了文件共享,所以硬链接就是多个文件名直接指向同一个inode,用stat命令也能看到其inode号就是目标文件的inode号,它的特点:
- 不能跨文件系统。
- 目标文件必须先存在(inode存在且link count不为0)。
- 只能对普通文件创建硬链接,目录不行。
- 删除一个硬链接文件并不影响其他有相同 inode 号的文件。
软链接是一个独立的文件,拥有自己的inode,其数据块存放的是目标文件的名称,访问软链接时,kernel先访问软链接的内容,拿到目标文件名,并重新启动路径解析,获取到目标文件inode号再向文件系统发起访问。软链接的特点:
- 可以跨文件系统。
- 文件和目录都可以。
- 可对不存在的文件或目标创建软链接。
- 软链接有自己文件属性和权限。
- 创建软链接时,链接计数 i_nlink 不会增加;
- 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。
- 软链接的目标文件也可以是软链接,其解析过程是递归的。
注意:软链接创建时目标文件的路径指向使用绝对路径比较好,使用相对路径创建的软链接被移动后该软链接文件将成为一个死链接,因为链接数据块中记录的也是相对路径指向。
下面这个图清晰描述了硬链接和软连接之间的区别:
Ext2fs基本结构
在创建文件系统的时候,Ext2fs将设备(磁盘或者分区)划分成1K、2K或者4K的block,然后通过Block group来管理,Ext2fs/Ext3fs/Ext4fs的结构差不多(Ext2fs主要是少了日志功能相关的内容),大致如下图所示:
Super Block
Super Block是文件系统最重要的数据,它从设备开始位置偏移1024字节的地方开始存储,占用1个block。如果block的大小是1KB,那么Super Block就存放在block-1。如果block的大小是4KB,那Super block就存放在block-0。
在Ext2fs的第一个版本(reverson0),每个Block Group都会存储一份Super Block的一份副本,因为对空间浪费比较严重,后来的版本就只在部分Blo