Linux文件:文件系统究竟是什么?如何管理文件?
- 前言
- 一、磁盘结构、存储策略
- 1.1 磁盘存储结构
- 1.2 磁盘存储策略
- 1.3 磁盘的逻辑存储结构
- 二、如何管理磁盘文件
- 三、如何管理组
- 3.1 每个组保存的数据种类
- 3.2 如何管理数据
- 1、节点表(inode Table)
- 2、inode Bitmap
- 3、Data blocks
- 4. Block Bitmap
- 5. Group Descriptor Table
- 6. 超级块(Super Block)
- 四、目录、文件名和inode映射关系
- 五、挂载
- 5.1格式化
- 5.2 挂载
- 六、操作系统查找、打开、创建文件过程
- 6.1 查找文件
- 6.2 打开文件
- 6.3 创建文件
- 七、软硬链接
- 7.1 软硬链接创建 及 软硬链接的区别
- 7.2 软连接和硬链接是啥?
前言
文件系统用于管理打开的文件(即加载到内存)和未被打开的文件(即磁盘中)。并且计算机中,绝大部分文件时未被打开,存放在磁盘中的!
一、磁盘结构、存储策略
1.1 磁盘存储结构
磁盘在计算机中被用于存储数据。其中磁盘会被分为多个盘面,每个盘面存在多个同心磁道。而每个磁道会存在很多扇形的扇区。扇区是磁盘的最小存储单元,一般为512Byte。但操作系统一般是每次直接读4Kb。
1.2 磁盘存储策略
如果我们需要像一个扇区中写入数据,如何寻址定位呢?
磁盘采用的是CHS定位法:
- C:
Cylinder
。即数据存储在那个柱面,或者说那个磁道。 - H
Head
,即磁头。磁盘存在多个盘面,每个磁头对应一个盘面。 - S:
Sector
,即扇区。
当我们确定好待写入区域的盘面,磁道,扇区后,即可准确定位。我们可以向一个扇区写入,就可以向多个扇区写入;也可以连续多个连续扇区写入,当然也可以随机写入!!
1.3 磁盘的逻辑存储结构
由于磁盘存在多个盘面,我们可以把每个盘面当作数组元素。而每一个盘面存在多个磁道,我们可以将磁道作为盘面数组的数组元素。而每个磁道又由多个扇区组成,同上。最后可以将磁盘盘面抽象为下图的线性空间!!
我们将磁盘抽象成一块线性空间后,操作系统可以按扇区进行存储。但一个扇区较小,通常操作系统都是基于文件系统,以文件块(一般为4KB)为单位进行存储!!!最后将磁盘抽象以4KB为单位的数组块。
最后将对磁盘的管理,在OS层面上转化为对数组的增删查改!!每个块都存在存在一个下标位置,我们将该下标称为逻辑块地址(Logical block address
)。由于盘面、轨道以及扇区的大小都是固定的,所以当我们得到逻辑块地址后通过转换可以知道数据在那个盘面、那个轨道、那个扇区。即间接通过CSH定位法找到扇区!!
二、如何管理磁盘文件
常识告诉我们仅通过中央政府来管理一个国家非常困难。所以我国设立了很多地方政府,省份,单独管理。同样直接管理一个省依旧困难,所以我国逐渐细分,设立了市、县、乡…
同样,磁盘一般为600G往上,非常大。由操作系统直接管理,不仅困难,而且不利于用户使用。所以我们对磁盘进行分区。但分区后还是太大,所以每个区还会被细分为多个组。
由于所磁盘文件的管理方法是相同的,所以我们仅需管理好一个组后将管理经验迁移。最后将如何管理整个磁盘,转换为如何管理一个组!!
- 假设现在有一块400G的磁盘,假设每一个分区大小为100G。每一分区被分为50组,即每个组的大小为2G。
三、如何管理组
3.1 每个组保存的数据种类
每个组存储的数据无非就两种:文件信息和管理文件的数据。而文件=内容+属性。文件是数据,属性也是数据。并且在Linux中,数据信息和属性信息是分开存储的!
3.2 如何管理数据
通常一个块组中会存在如下字段:
tips:
Boot Block
只存在于第一个分区的开始位置,其中包含引导加载程序,是计算机开机时加载操作系统的核心。Boot Block
中包含了操作系统的内核镜像相关信息、文件系统的类型和初始结构、内核数据在磁盘的大致位置等信息。当计算机启动时,基础IO系统(BIOS)会对磁盘自检,将Boot Block
中的引导加载程序记载到内存。完成后,控制器会交给引导加载系统。该系统会根据Boot Block
存放的操作系统相关数据信息,将操作系统加载到内存!!!- inode是啥?
上述最前面的数字就是inode
。一般情况下,每个文件都会有inode
,并且每个文件只有一个。在整个分区中,inode
具有唯一性。并且在Linux文件,操作系统识别文件和文件名无关,之和inode
有关。
1、节点表(inode Table)
inode Table
也被称为节点表。每一个成员inode
是一个结构体,即struct inode inode_Table[N]。其中存放文件的各种属性:如文件大小、拥有者、所属组、权限、ACM时间、和一个应用计数int ret_count用于表明有多少个文件名的映射关系。其中还存在一个数组,用于标记存放文件数据块的编号。并且inode
大小是固定的,为128字节!! 由于inode的大小固定,所以我们很容易通过相对量或偏移量来确定具体的inode!!
节点表中的下标保存的通常是inode
在组内的偏移量,通常在组的开始都存在一个start_inode_number
。而当前文件的真实inode
则是组起始start_inode_number
+ 偏移量!
2、inode Bitmap
inode本质上就是下标。我们需要为新的文件分配inode,我们在给新文件分配inode前需要得到整个组中inode的使用情况!而inode Bitmap则是用于标记inode。
inode Bitmap
也被称为inode位图
。通过位图思想,每个bit表示一个inode
是否空闲可用。0可用,1已经被使用!
3、Data blocks
Data blocks
用于存放文件内容。通常是以4KB为单元仅需存储。
在节点表中存在一个block[N]
数组,用于映射数据块,通常大小为15。但有时15(即15*4KB)的空间无法将文件全部存下。
所以一般0~12直接映射数据块下标。而block[13]
也会映射到Data blocks
中。不同的是这块空间(4KB)不是直接用于存储内容的,而是存放映射其他数据块的信息(1000个)。通过二次索引,找到更多数据块用于存放数据!!
而block[14]被称为三级映射。block[14]映射到的数据块用于保存数据块下标(假设为bk1)。但又该bk1中数据指向的数据块依旧存储的数据块下标(假设为bk2)。只有bk2中映射的才是真正存放数据内容的数据块下标!!
如果文件实在太大,文件系统指出跨组存储访问!
4. Block Bitmap
和inode一样,操作系统要为新创建的文件创建文件缓冲区,这也意味着需要为新文件分配块空间。所以我们需要知道块的使用情况!!而块位图Block Bitmap同样利用位图实现,1表示块已经被使用,0则没有。记录整个组中块的使用情况!!
5. Group Descriptor Table
Group Descriptor Table(GDT):块组描述符,用于描述整个块组的使用情况!比如整个组的起始inode,整个组的大小,inode的个数,inode的使用情况,块组的个数,块组的使用情况等等。
Group Descriptor Table通常位于文件系统的起始位置或者与文件系统的Super Block相邻的位置。它存储了文件系统中每个Block Group的信息,使得文件系统能够有效地管理数据块的分配和释放,以及inode的分配和管理。
6. 超级块(Super Block)
存放文件系统本身的结构信息以及整个区的相关信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息和文件系统类型。
Super Block只在少数几个分组中存在。操作系统需要管理每一个分区,操作系统要对每一个分区的文件系统进行管理。所以操作系统内核中会维护一张文件系统链表,然后将Super Block记载到内存。从而将对整个文件系统的管理,转化为对多个Super Block管理。
为何每个分区Super Block存在少数几个?在操作过程中,可能由于断电,错误刷盘等问题导致信息错误,从而导致各种问题,甚至无法加载操作系统。为了解决这个问题,我们一般在其他区域保存一些副本,即Super Block存在多个副本。一般某一个Super Block出现问题,我们可以加载其他副本信息,或者通过副本来恢复!!!至于为啥只有少数几个,原因在于如果每个块组都保存一个,刷新成本过高!!
四、目录、文件名和inode映射关系
对于用户来说,我们查找文件是通过路径加文件名来实现的。但操作系统只认识inode。这也意味只我们需要将路径文件名转换为对应文件inode!
在解决这个问题前先来了解目录是啥?
Linux下一切皆文件。所以目录也是文件,只是目录文件保存的是目录内部直接保存文件的文件名和inode的映射关系!
这也是为啥创建文件时名字不能重复。原因在于文件名被作为key,索引对应文件inode,组成键值对!并且在目录下创建文件、删除文件,本质上就是新增或删除键值对,时对文件内容的修改,所以需要w权限
!!
最后我们仅需根据文件路径,从根节点来时一层一层剥开,即可找到目标文件的inode!!至于我们访问文件时,只需通过文件名即可访问。原因在于进程中存在cwd等字段,进程会自动保存路径!
五、挂载
一个磁盘被分区格式化之后,Linux要使用分区,需要对分区进行挂载!那格式化、挂载是啥?
5.1格式化
简单来说,我们在使用磁盘加载文件前,我们首先要先将管理磁盘的数据加载到磁盘中,在存放文件。就好比创业,我们需要先决定好管理层,然后才会招聘人员干活一样。
而仅将管理磁盘的数据写入磁盘的行为则被称为格式化。我们日常说是的格式化不是将数据全部清理,而是将你的文件数据清理,管理磁盘的数据依旧存在!!
5.2 挂载
通俗来讲,挂载就是将分区和一个目录绑定,在Centos7中我们可以通过df- h
查看挂载情况!
dev/vdal
是磁盘的一个分区。图中的意思时将分区dev/vdal
绑定到根目录/
上。即我们通过访问根目录即可确定待访问的磁盘分区!!
六、操作系统查找、打开、创建文件过程
6.1 查找文件
首先每一个文件都有绝对路径,我们根据绝对路径的前缀即可确定文件具体所在分区。并且每一个文件都有唯一的inode,每个分区的文件inode编号是唯一的。操作系统拿到inode后,访问Group Descriptor Table,即可确定inode在那个分组中,然后访问到inode Table,进而获取到文件的相关属性信息。在通过block字段可以获取到文件内容存储在Data blocks的位置。进而获取文件内容!
6.2 打开文件
进程打开文件时,进程中的CWD字段中保存当前的工作路径。结合工作路径和文件名,我们即可确定文件所在分区、分组、inode编号。此时进程会为被打开文件创建一个struct file结构体,通过inode将文件的相关属性加载到内存,填充到struct file结构体中;然后通过inode找到Data blocks,并加载到内存形成文件缓存区!最后按照打开方式会将数据在进程中保存。最后就是对内存缓存区文件的相关操作了!
6.3 创建文件
创建一个新文件分为以下4个步骤:
- 存储属性:内核先找到一个空闲的inode节点,内核把文件信息记录到其中,并修改inode Bitmap。
- 存储数据。操作系统会通过 Block Bitmap为文件分配合适的数据块,用于存放文件数据,并修改 Block Bitmap。
- 记录分配情况。操作系统会在inode上的磁盘分布区记录数据块对应映射关系。
- 添加文件名到目录。Linux会将入口(263466,abc)(文件名和inode的对应关系)加到当前目录文件中。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。
七、软硬链接
7.1 软硬链接创建 及 软硬链接的区别
假设用软链接log.soft.link
链接 log
,链接方式如下:
ln -s log log.soft.link
假设用硬链接txt.hard.link
链接 txt
,链接方式如下:
ln txt txt.hard.link
【最终结构】:
- 所以软连接是一个独立的文件,而硬链接不是,因为硬链接没有对立的inode编号!
7.2 软连接和硬链接是啥?
- 软连接类似windows中的快捷方式,是一个独立的文件。软连接中的内容是指向目标文件的路径!
- 硬链接不是一个文件,没有独立的inode,所以硬链接是指定目录内容中的一种映射关系,即文件名 <—> inode的映射关系!一个文件真正意义上被删除,就是文件的硬链接数为0,即没有文件和inode的映射关系了!文件名在目录里面具有唯一性,而文件名和inode的索引也类似与指针行为!
- 目录文件创建默认硬链接从2开始。原因在于目录文件下默认存在2个隐藏文件,其中
.
文件表示当前路径,其inode和目录本身inode一样!!并且没多创建一个目录,硬链接数会+1。 - 硬链接应用场景就是用于路径切换,用于Linux构造整个路径结构,方便路径回退!
- 用户可以对目录建立软连接,但无法建立硬链接。原因在于如果可以建立硬链接会导致下面的环形结构,可能会作为查找时的一个路上节点被使用,使得在查找时无法结束查找工作。至于软连接其本身只是一个文件,查找时不会进入其中!至于Linux中
.\和..
两个硬链接也会构成环形结构,这是Linux特殊情况!