ext2是Linux早期比较流行的文件系统,很多文件系统(NTFS、FAT32等)的设计都源自于它。只要掌握了ext2文件系统,其他文件系统大同小异。
ext2文件系统的布局如下:
文件系统中存储的最小单位是块(Block),一个块究竟多大实在格式化时确定的,例如mke2fs的-b选项可以设定块大小为1024、2048或4096字节。
启动块(Boot Block)
大小就是1kB,由PC标准规定,用来存储磁盘分区的信息和启动信息,任何文件系统都不能使用该块。(如果这个块损坏,整个文件系统也就启动不起来了)。
超级块(Super Block)
描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等。超级块在每个块组的开头都有一份拷贝。
块组描述符表(GDT,Group Desctriptor Table)
由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,包括inode表哪里开始,数据块从哪里开始,空闲的inode和数据块还有多少个等。块组描述符表在每个块组的开头也都有一份拷贝,这些信息是非常重要的,因此它们都有多份拷贝。
块位图(Block Bitmap)
块位图就是用来描述整个块组中哪些块已用哪些块空闲的,本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。
inode位图(inode Bitmap)
和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用。
inode表(inode Table)
文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等信息存在inode中,每个文件都有一个inode。
数据块(Data Block)
常规文件:文件的数据存储在数据块中。
目录:该目录下的所有文件名和目录名存储在数据块中。(注意:文件名保存在它所在目录的数据块中,其他信息都保存在该文件的inode中)。
符号链接:如果目标路径名较短则直接保存在inode中以便更快地查找,否则分配一个数据块来保存。
设备文件、FIFO和socket等特殊文件:没有数据块,设备文件的主设备号和次设备号保存在inode中(用ls -al /dev查看该目录下的设备文件时,可以发现原来打印文件大小的位置,换成了主次设备号)。通过设备号,系统会去找它的驱动,然后运行起来。
对于一个文件来说,除了它的数据保存在数据块中,其他信息都保存在自己的inode表中。比较邪门的是,inode表和数据块都不保存文件的名字,它的名字保存在目录的数据块中(当然目录也有自己的inode表),这也就是执行vim .命令时,看到的是当前目录下的文件名和目录名的原因。在这些文件名或目录名前面,存储着找到这些文件或目录的inode地址(其中.前面存储的就是这个目录自己的inode地址,..存储它上一级目录的inode地址),而inode表里又存储着文件或目录数据块的起始地址和长度等信息。这样反复横跨inode表和数据块,来寻找最终的文件内容。
对于目录来说,目录的数据块中存储的就是文件名及其这些文件名的inode地址。
其他文件系统会通过虚拟文件系统的方法,凑出和ext2相同的东西,这个其实就可以称为协议了。
假设一个路径是/opt/file,则查找顺序是:
1.读出inode表中第2项,也就是根目录的inode,从中找出根目录数据块的位置
2.从根目录的数据块中找出文件名为opt的记录,从记录中读出它的inode号
3.读出opt目录的inode,从中找出它的数据块的位置
4.从opt目录的数据块中找出文件名为file的记录,从记录中读出它的inode号
5.读出file文件的inode
关于软硬链接:
软链接:
$ ln -s ./text.txt ts //ts是./test.txt的软连接(ts -> ./test.txt),假设text.txt有6个字节,ttt却有10个字节,说明ts中存储的是./text.txt这10个字节(存储的是路径),也说明软连接出来的文件,和原文件是两个完全不同的文件
硬链接:
$ ln ./text.txt tl //tl是./test.txt的硬连接。建立完硬连接后,text.txt文件的硬连接数加1,即inode表中还存储了它的硬连接数(有几个文件名,就有几个硬连接数)。text.txt和tl是完全相同的文件,是相同的inode表。
$ mkdir -p a/b //在当前目录下,建立a目录,a目录下建立b目录。b的硬连接数是2,这是因为a目录下的b,b目录下的.都指向目录b的inode表(创建一个目录,至少是2个硬连接);a的硬连接数是3,因为a目录下的.,b目录下的..,a的父目录下的a。