说到文件系统的布局,就需要先从磁盘的逻辑结构说起。
1、磁盘的逻辑结构
这里说的磁盘逻辑结构不是指磁盘的物理结构,诸如磁道、磁臂和旋转这一类,这里的逻辑结构是指,磁盘给了一段物理空间,那么用户总要对这个物理空间进行划分,即所谓的逻辑空间,那么一块磁盘在逻辑空间上布局如下图所示:
从图上我们可以总结出,一块磁盘的开始区域是主引导记录又称为MBR表,它由三个部分组成:硬盘主引导程序(BootLoader)、硬盘分区表DPT(Disk Partition table)和魔数(Magic Number),记录硬盘的一些最基本的信息,如果MBR表一旦损坏无法修复,硬盘的将难以修改。
其次则是分区表,分区我们都经常听说,也就是按照硬盘的逻辑空间将硬盘分为不同的区域,类似我们windows系统上的C盘,D盘这些。分区分为主分区和扩展分区,扩展分区又可以继续分区。由于分区表的大小限制,主分区和扩展分区不能超过4个,超过4个的分区右扩展分区进行扩展。
如果想更加了解硬盘的一些组织结构,参考此博客硬盘的结构和介绍,硬盘MBR详细介绍(超详细彩图)
2、文件系统与硬盘分区的关系
在了解了硬盘的逻辑结构之后,下面我们来看下文件系统的逻辑结构,签名分析了文件系统是在硬盘之上建立的,那么二者又有何关系呢??
一般来说,一个分区就是只能被格式化成为一个文件系统,格式化指的就是挂载步骤。具体来说,由于文件系统的类型不同,磁盘在逻辑上划分了不同的分区,那么各个分区是可以独立挂载各自的文件系统的,例如windows系统上,已经分区了CDEF盘,他们使用的是windows自带的文件系统,此时我们挂载一个U盘上去,U盘成功显示的是G盘,此时G盘使用的是U盘自带的fat32的文件系统。
更深入的探讨,如果想在某块硬盘上挂文件系统,那么首先需要将此文件系统格式化成为想要的文件系统,然后将此文件系统进行挂载,注意挂载到指定的目录下,后序会将挂载步骤需要注意什么?
3、文件系统的布局
文件系统的布局如博客linux文件系统详解插图所示:
一个文件系统挂载在某一个分区上,那么文件系统格式化就有自己的逻辑空间大小,将此逻辑空间按照上述进行布局。
整体上看分为两个部分:一个部分是引导块、一个部分是数据块组
引导块:为磁盘分区的第一个块,记录文件系统分区的一些信息,,引导加载当前分区的程序和数据被保存在这个块中。一般占用2kB,
数据块组:由于文件中块的大小很小,那么如果去整个分区中管理数据组块,那么会消耗大量的元数据管理,操作起来也即为复杂。因此,文件系统提出了数据块组的概念,实际是一个多层的概念,便于管理。将分区数据再次划分为不同的数据块组,每个数据块组单元地位相同,数据写入先选定数据块组,在选取数据块组内部的数据块的位置。
4、数据块组的布局
同样是这张图,一个数据块组中分为图上的7个部分。
超级块: 记录此文件系统的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;由于super block很重要 ,在每个 block group都会存一份进行备份,一般来说,第一个数据块中是原始超级块,其它数据块组中都是超级块的备份。
块组描述符表: 块组描述符(Group Descriptor)存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等。和超级块类似,块组描述符表在每个块组的开头也都有一份拷贝
**预留块组描述符表:**和快组描述符是一样的,只不过是预留的,值得注意的是块组描述符表由很多块组描述符组成,整个分区分成多少个块组就对应有多少块组描述符,在每个快组上都有保存,和超级块一样的备份策略。
**块位图:**块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。
innode节点位图: 和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用。
innode节点表:一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,这些信息存在inode中而不是数据块中,而是由innode来存储。每个文件都有一个inode,一个块组中的所有inode组成了inode表,inode表占多少个块在格式化时就要决定并写入块组描述符中。值得注意的是,innode存放数据的描述信息,但是文件的目录信息是由数据块存放的。
**数据块:**对于常规文件,文件的数据存储在数据块中,对于目录,该目录下的所有文件名和目录名存储在数据块中,文件名保存在它所在目录的数据块中,除文件名之外,ls -l命令看到的其它信息都保存在该文件的inode中,目录也是一种文件,是一种特殊类型的文件。其实文件名和文件类型都是在目录中存放,而文件的其他元数据信息则是在Inode中存放。
5、一个文件的查找过程
大体如下表所示:
读取过程如下,例如读取路径为/etc/profile/pid.sh
- 首先找到/etc/profile/目录文件对应的inode文件,找到目录文件的innode之后,就可以找到目录文件存放的数据块,该数据块中存放有各种文件名,以及对应文件存放innode的位置信息。
- 根据文件名pid.sh找到其数据块对应的innode的地方
- 通过读取innode块的相关信息,找到该文件内容所在的数据块号
- 最后根据数据块号读取数据块的内容