我们的磁盘很大,我们日常存储删除的文件又非常多,磁盘一个是扇区512字节它们用来存数据,能存进去还能读出来,那么这么多文件是如何被找到的呢?
这就需要一个复杂的文件系统。
本文章以ext2文件系统为例做具体讲解(ext4原理类似)
首先我们需要先把文件系统组成搞清楚。
结构图:
我们知道,一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种
mkfs命令)格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写
一些管理存储布局的信息
linux把磁盘分成了若干个block,block需要是512的整数倍,默认是4096字节,意味着有8个物理扇区。
(1)启动块(boot block)
是约定好的1024字节。启动块是由PC标准规定的,用来存储磁盘分区信息和启动信息(记录分了几个区,每个区起始位置装什么操作系统等)任何文件系统都不能使用启动块。
启动块之后才是ext2文件系统的开始,ext2文件系统将整个分区划成若干个同样大小的块组(Block Group)
为了讨论方便,我们这里把一个块认为为1024B(实际为4096字节)
(2)超级块(Super Block)
描述整个分区的文件系统信息,例如块大小、文件系统版本
号、上次mount的时间等等。超级块在每个块组的开头都有一份拷贝。
(3)块组描述符表(GDT,Group Descriptor Table)
由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符(Group Descriptor)存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等。和超级块类似,块组描述符表在每个块组的开头也都有一份拷贝,这些信息是非常重要的,一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝。
(4)块位图(Block Bitmap)
那么如何知道哪些块已经用来存储文件数据或其它描述信息,哪些块仍然空闲可用呢?
块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。
为什么用df命令统计整个磁盘的已用空间非常快呢?
因为只需要查看每个块组的块位图
即可,而不需要搜遍整个分区。相反,用du命令查看一个较大目录的已用空间就非常慢,因
为不可避免地要搜遍整个目录的所有文件。
(5)inode位图(inode Bitmap)
和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用。
inodebitmap位图标标识用了还是没用。
(6)inode表(inode Table)
文件的文件属性和文件内容是分开存储的。
一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l命令看到的那些信息,这些信息存在inode中而不是数据块中。
每个文件都有一个inode,一个块组中的所有inode组成了inode表
(7)数据块(Data Block)
根据不同的文件类型有以下几种情况:
对于常规文件,文件的数据存储在数据块中。
对于目录,该目录下的所有文件名和目录名存储在数据块中,注意文件名保存在它所在
目录的数据块中,除文件名之外,ls -l命令看到的其它信息都保存在该文件的inode中。注
意这个概念:目录也是一种文件,是一种特殊类型的文件。
对于符号链接,如果目标路径名较短则直接保存在inode中以便更快地查找,如果目标
路径名较长则分配一个数据块来保存。
设备文件、FIFO和socket等特殊文件没有数据块,设备文件的主设备号和次设备号保存
在inode中。
了解了结构之后
我们可以开始讨论一个普通文件怎么存进磁盘的呢?
一个文件要申请inode,首先GDT检索然后跳到inode位图看哪的inode空闲
把stat存到inode,下一步,开始写文件内容,inode128字节分成两部分,文件属性和数据块指针数据块占60字节,所以有15个指针可指向数据块,内容写入数据块后,相应的块位图中bit翻转成1。
如果存的文件过大,会不会导致数据块指针不够用?
这里ext2文件系统中,最后三个指针,才用间接寻址,分别才用一级指针、二级指针、三级指针,把指向的相应数据块变成好多指针,继续指向其他数据块。
通过三级寻址文件之后,一个文件可以保存16G(假设1个block为1k)(ext4下会更大,上升到
T的单位)
总览图:
我们删除一个文件发生了什么?
简单来说,仅仅是释放数据块block bit map置0,inodebitmap置0,所以删除很快,而数据内容在磁盘还在相应的数据块。
认真看文章的同学可能会发现我们的遗留问题
文件名存在哪?
答案是存在目录中
目录当中称为记录项,一个目录一般情况下是4096字节,相当于目录申请了一个块目录中存着记录项。
编码 文件类型
0 Unknown
1 Regular file
2 Directory
3 Character device
4 Block device
5 Named pipe
6 Socket
7 Symbolic link
一般的寻址过程,找到目录的数据块,匹配记录项,文件名,找到inode编号,再接着上文中存储的步骤。
那么目录也是文件,它怎么被找到呢?
答案是:从根目录开始
规定根目录的inode必须为2
如图
本文需要慢慢理解,不清楚的地方欢迎讨论。