Linux基础IO【理解文件系统】
上文讲解了内存文件的相关知识,本文来介绍磁盘文件,它位于存储设备磁盘中,因此不属于冯诺依曼体系,对于用何方法来更高效地存储磁盘文件,就要提及本文的重点—文件系统了,下面就一起来看看吧
1. 磁盘
讲解磁盘文件首先要先理解一下磁盘,磁盘主要分为机械硬盘和固态硬盘,机械硬盘便宜、稳定,但读取速度很慢,固态硬盘读取速度相对较快,但价格高昂且数据易受损,本文主要介绍的是机械硬盘
1.1 物理组成
磁盘结构图

磁盘是由机械手臂、磁头、主轴马达、接口插座、控制电路以及许多盘片等组成
- 实际运行时,主轴马达让盘片转动,然后机械手臂可伸展让磁头在盘片上进行读写操作,机械设备查找具体扇区时的方法称为
CHS定位法 - 这里读写操作对应就是寻找
CHS地址,也就是sector(扇区)、header(磁头)、cylinder(柱面)这三者先是磁头找到对应的柱面在找到对应的扇区,以南北极为介质,对应操作就是:N->S,向磁盘写入数据;S->N,删除磁盘中的数据 - 磁盘的最小存储单位是扇区,在物理组成分面,每个扇区的大小是
512字节 - 所有盘片上的同一磁道可以组成一个柱面,分割硬盘的最小单位就是柱面

磁盘三维结构图

这里有个疑问:操作系统内部会直接使用CHS地址来进行访问修改数据吗?
- 答案是不会的,因为操作系统是软件,而硬盘是硬件,硬件会持续更新改变,如果操作系统也需要持续改变,这样就会发生耦合,所以要对其进行解耦操作就不需要持续改变
- 另外扇区是
512字节,硬件的基本单位是4KB(可以调整),所以操作系统有一套自己的地址对其进行块级别访问修改等操作
1.2 磁盘分区
为了更好的管理磁盘,计算机对磁盘进行了分区。比如在Windows下磁盘一般会被分为C盘和D盘等
在Linux下也可以通过指令来查看当前的分区信息
ll /dev/vda* -i //查看分区信息

盘片中有很多扇区,但是并不是每个扇区都一样重要
- 磁盘的第一个扇区特别重要,主要记录主引导分区:可以安装引导加载程序的地方,有
446字节;以及分区表:记录整块硬盘分区的状态,有64字节。 - 分区表是什么呢?把硬盘比作一根原木,需要把这个原木分割为很多区段才能做成满意的家具,如果不分割原木不能有效利用,同样的道理硬盘需要分区才能被你充分利用。分区表中的
64字节容量中,总共分为四组记录区,每组记录区记录了该区段的启动和结束柱面号码

上图中假设硬盘有400个柱面,共分为四个分区,第四个分区为第301到400号柱面的范围,当你使用Windows操作系统第一到第四个分区应该就是C,D,E,F,那么第301到400号柱面就是对应的F盘。由于分区表只有64字节而已,最多只能容纳四个分区,这四个分区被称为主或扩展分区。重要信息:其实所谓的分区只是针对64字节的分区表进行设置而已;硬盘默认的分区表仅仅能写人四组分区信息;分区的最小单位是柱面
分区的意义
- 分区数据是分开的,那么当你需要将某个分区的数据重整时,例如:你要重新安装
Windows时,可以将C盘中其他重要数据移动到其他分区,这样就不会丢失数据,所以善用分区,可以让数据更安全 - 按照区段进行搜索数据时,这样有助于提高系统的性能和速度
分区表就并不是只能把一块硬盘发最多分为四个分区
L1-L5这五个由扩展分区切出来的分区称为逻辑分区。重要信息:主分区和扩展区最多可以有四个;扩展分区最多只能有一个;逻辑分区有扩展分区持续切割出来的分区;能够被格式化后作为数据访问的分区是主分区和逻辑分区,扩展分区不能被格式化;逻辑分区的数量依操作系统而不同,IDE硬盘最多有59个逻辑分区(5到63号),SATA硬盘有11个逻辑分区(5到15号)

当磁盘完成分区后,我们还需要对磁盘进行格式化
每种操作系统文件系统所设置的文件属性/权限并不相同,为了存放这些文件所需要的数据,因此需要对其格式化
磁盘格式化就是对磁盘中的分区进行初始化的一种操作,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。简单来说,就是对分区后的各个区域写入对应的管理信息
2. 文件系统
2.1 inode
磁盘文件由文件内容和文件属性构成,文件属性又被称为元信息
输入指令ll,就可以查看当前目录下各文件的属性

在Linux中,文件的内容和属性是分开存储的,其中保存文件属性的结构就叫做inode,是一个文件属性集合,因为系统当中可能存在大量的文件,所以我们需要给每个文件的属性集起一个唯一的编号,即inode编号
使用指令ll -i,就可以查看当前目录下各文件的inode编号

无论是文件内容还是文件属性,都是存储在磁盘当中的
2.2 文件系统特性
Linux的正规文件系统是Ext2
- 传统磁盘和文件系统应用中,一个分区就是只能被格式化成一个文件系统,所以说一个文件系统就是一个分区,但是由于新技术的应用可以将一个分区格式化为多个文件系统,也能将多个分区合成一个文件系统,所以可以称呼一个被挂载的数据为一个文件系统而不是一个分区
文件系统是如何运行的呢?
- 文件包含内容和属性,那么文件系统通常会将内容和属性这两部分的数据分别存在不同的块中,权限和属性放在
inode中,内容放在data block块中。另外还有一个super block块会记录文件系统的整个信息,包括inode和block的总量、使用量等等。 - 每一个
inode和block都有编号方便管理。其中inode记录文件属性,一个文件占用一个inode,同时记录此文件的数据所在的data block号;block是记录文件内容,如果文件太大时,会占用多个block。既然我们知道inode中包含data block号,那么也就是说只要找到文件的inode就可以通过inode中data block编号读写数据,性能比较。如下图:

2.3 EXT2文件系统
Linux文件系统EXT2就是使用inode为基础的文件系统
inode是记录权限和属性,data block是记录文件内容。文件系统一开始就将inode和block规划好了,除非重新格式化,否则inode和block固定后就不再变动。- 如果文件系统非常大时,将所有的
inode和block放置在一起很不明智,为了更好的管理磁盘,会对磁盘进行分区。而对于每一个分区来说,分区的头部会包括一个启动块(Boot Block),对于该分区的其余区域,EXT2文件系统会根据分区的大小将其划分为一个个的块组(Block Group) - 每个组块都有着相同的组成结构,每个组块都由各自独立的超级块(
Super Block)、块组描述符表(Group Descriptor Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)和数据表(Data Block)组成
下面以单个盘片来说,磁道上的扇区全部拿下来就变成了一个数组,第一个扇区中有主引导分区和一个分区表,八个扇区也就是一个block(这样更方便管理),块中存放数据:

把区、块分组,再对每个块组做管理:

各区域作用
- 超级块(
Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck和inod的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了 GDT,Group Descriptor Table:块组描述符,描述块组属性信息- 块位图(
Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用 inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。i节点表(inode Tabl):存放文件属性,即每个文件的inode- 数据区(
Data Blocks):存放文件内容
3. 文件操作理解
有了以上内容做铺垫,下面理解一下文件子磁盘中的创建
3.1 创建文件
创建一个空文件的步骤
- 遍历
inode位图,找到一个空闲的inode - 在
inode表当中找到对应的inode,将文件的属性信息填入inode结构中 将该文件的文件名和
inode指针添加到目录文件的数据块中每个
inode和Data block只对应一个文件
3.2 信息写入
想要向文件写入信息首先需要访问到目标文件
- 首先根据文件的
inode编号,在目录分组中进行查找 - 通过
inode和Data block的映射关系,找到文件的数据块,并加载至内存中即可
这就解释了在file 对象中有 inode 信息的原因
向文件中写入信息的步骤
- 首先通过文件的
inode编号找到对应的inode结构 - 通过
inode结构找到存储该文件内容的数据块,并将数据写入数据块。 - 若不存在数据块或申请的数据块已被写满,则通过遍历块位图的方式找到一个空闲的块号,并在数据区当中找到对应的空闲块,再将数据写入数据块,最后还需要建立数据块和
inode结构的对应关系
下面来分析一下inode/block和文件大小的关系
inode记录的数据很多,但是只有128字节大小,而记录一个block就需要4个字节。假设一个文件有400MB,每个block为4KB时,就有至少10w条block号码,inode的128字节该如何记录呢?- 方法是:系统采用
12个直接索引、1个间接索引、1个双间接索引、1个三间接索引记录区,用多级索引来做到一个数据块中存储大量数据 - 说简单点就是类似套娃,在
Data block中存储其他的Data block信息

本文中多处图片取自《Linux -- 基础IO》
3.3 删除文件
删除文件的步骤
- 首先根据文件名找到
inode编号 - 再将该文件对应的
inode,在inode位图当中置为无效(置0) - 最后将该文件申请的数据块,在块位图当中置为无效(置0)
此删除操作并不会真正将文件对应的信息删除,而只是将其inode号和数据块号置为了无效,起到了访问不到就等于删除的效果
- 因此当我们删除文件后短时间内是可以恢复的,将该文件对应的
inode号和数据块号置为无效后,此时操作系统是可以直接使用的,此时删除的文件数据就会被覆盖,就无法恢复数据了,所以说是短时间内
Linux基础IO【理解文件系统】,到这里就介绍结束了,本篇文章对你由帮助的话,期待大佬们的三连,你们的支持是我最大的动力!
文章有写的不足或是错误的地方,欢迎评论或私信指出,我会在第一时间改正