文章目录
一、磁盘的物理结构

磁盘的物理结构,核心是:
- 盘片:
真正存数据的圆形盘片,一般一张硬盘里有1~N 层叠在一起。表面涂了磁性材料,用磁性可以表示01,数据就存在这里。 - 磁头:
负责读 / 写数据的小探头,每个盘片的上下两面都有一个磁头,工作时不接触盘片,悬浮飞行。 - 磁道
盘片旋转时,磁头不动,划出的一个个同心圆,像唱片的纹路,数据就存在磁道上。 - 扇区
把磁道切成一段一段的小扇形,称为扇区,一个扇区是512字节。八个扇区组成一个"块",块是文件系统IO最小的物理单位,一块为4KB(4096 字节),每个块都有它的块号。 - 柱面
所有盘片上相同半径的磁道,合起来叫一个柱面,操作系统按柱面来读写,效率最高。
二、ext文件系统
我们想要在磁盘上存储文件,必须先把磁盘格式化为某种格式的文件系统,才能存储文件,文件系统的目的就是组织和管理硬盘中的文件。
在Linux系统中,最常见的就是ext2系列文件系统,ext2后面发展处理ext3和ext4,核心设计还是一样的:

- 磁盘:最开头的MBR(主引导记录),位于磁盘最开头的512字节,主要包含引导代码,开机时执行,用于加载操作系统。磁盘剩下的部分,会分成若干个分区,每个分区的文件系统相互独立。分区表记录了磁盘上每个主分区的起始位置、大小等信息。
- 分区:整块磁盘划分为几个独立的逻辑区域,每个分区有自己的文件系统。ext文件系统将一个分区划分为若干个块组(Block Group):

Linux系统下,文件的属性和内容是分开存储的!保存文件属性的集合叫做inode,一个文件有一个inode,inode中有一个唯一的标识符叫做inode号。inode结构的大小固定是128字节,文件名属性并没有存到inode内部!
ls命令的-i选项,可以查到文件的inode号:

-
Super Block(超级块):存放文件系统本身的结构信息,描述整个分区的文件系统信息。记录的主要信息有:分区内块组和inode总量,未使用的块组和inode数量,一个块组和inode的大小,等等。Super Block的信息被破坏了,就是整个文件系统结构被破坏了。
不是每个块组开头都有Super Block,第一个块组必须有。为了保证文件系统在部分扇区出现物理问题时还能正常工作,通常会有多个Super Block备份,它们的数据保持一致。
-
GDT:块组描述符表。它描述着存储一个块组的描述信息,比如这个块组中哪里开始是inode Table,哪里开始是Data Blocks,空闲的inode还有多少个等等。每个块组都有一份GDT。
-
Block Bitmap(块位图):这个位图记录着Data Block中哪个块已经被占用,哪个没被占用。
-
Inode Bitmap(Inode位图):这个位图记录着每个inode是否空闲可用。
-
Inode Table:inode结构内容都存放在这里。要注意的是,inode编号是以分区为单位划分的。也就是不同分区内可以有相同inode编号,但是不同的文件。
-
Data Block:这个区域存放文件内容。 文件存储也是以块为单位的,块号和inode编号一样,都是不跨分区的!

在inode结构中,有一个数组i_block,里面记录这个文件的内容存放在哪些块的块号,所以文件就可以通过它的inode寻找到它的内容了。
但是,这个数组大小是固定的15,也就是最多只能找到15个块吗?万一文件大小超过了怎么办?

其实不然:数组15个位置,前12个能指向正常的块,第13个能指向一个专门记录块号的块(一级间接块索引表),第14个能指向一个专门记录一级间接块索引表块的块(二级间接块索引表),第15个能指向一个专门记录二级间接块索引表块的块(三级间接块索引表)。一个块是4KB,一个块号是4字节,这样计算下来,整个inode理论上可以管理的最大文件大小约为4TB!

三、目录与文件名
Linux系统,一切皆文件!目录也是文件,目录也有文件属性和文件内容。目录的文件内容是:目录中的文件名与其inode号的映射关系!
在磁盘和文件系统角度,保存目录和普通文件没有任何区别。
所以,访问一个文件,必须打开当前目录,根据文件名找到inode号,然后找到文件内容。
问题是,当前目录也是一个文件,要访问它,也需要找到它所在的目录!
这个过程就类似递归了,最终,访问一个文件,需要把它的路径上的所有目录全部解析,出口是/根目录!访问目标文件,都要从根目录开始,依次打开每一个目录,根据目录名继续访问目录下指定的目录,直到访问到目标文件。这个过程叫Linux路径解析!
还有一个问题,inode不能跨分区,我怎么知道一个文件在哪个分区?
答案:分区写入文件系统,无法直接使用,必须要和指定的目录相关联,进行挂载才能使用!
所有分区,必须挂到目录上才能用。一个目录一挂,它就变成一个文件系统的入口。
所以,就能根据目标文件的路径前缀判断出他在哪个分区下。
四、软硬链接
1. 硬链接
真正在磁盘上找文件,用的是inode。其实在Linux中可以让多个文件名对应同一个inode:
ln abc def命令,可以为abc文件建立一个硬链接def:

硬链接和目标文件的inode相同,所以它们就是同一个文件!
建立硬链接的本质,就是在当前目录下新建一个字符串(文件名)和目标文件的映射关系。
在ls显示文件详细属性这里,这一列数字就表示这个文件有几个硬链接,内核记录了这个硬链接数。当删除一个文件时,首先会将硬链接数-1,只有当为0时才会真正删除内容:

但是,我们不能给目录建立硬链接,防止用户形成环状路径! 假设/a是目录,给它建硬链接 /b
那么:/a 和 /b 是同一个 inode,进入 /a = 进入 /b,进入 /a/.../b = 又回到自己!
有一个例外,就是每个目录下的隐藏目录.和..,它们的本质就是硬链接!
这就是为什么我们创建一个目录默认硬链接数是2,因为有自己的.,同理在一个目录下创建一个目录它的硬链接数就是3因为又有子目录的..了!
不难看出,硬链接的作用是:可以让同一文件多处共享、防止文件误删(备份)、节省存储空间,维护Linux系统的目录结构。
2. 软链接
ln -s abc def命令,为abc文件建立一个软链接def。
软链接是一个独立的文件,它保存的是目标文件的路径!硬链接通过inode引用另一个文件,软链接通过路径引用另一个文件,但是软链接和目标文件的inode不同。
可以把软链接想象成快捷方式的道理。我们可以给一个常用但是路径复杂的文件做软链接放到方便的路径下,你访问软链接时,系统就会自动跳转到它指向的路径。

本篇完,感谢阅读。