
观众老爷们大家好 这里是邪修KING的独家频道 本文属于系列Linux系统篇 ------文件系统 一起学Linux的小伙伴可订阅专栏: Linux系统篇 上一篇我们讲了磁盘硬件层面的原理:数据存在扇区里,用 LBA 地址定位。但我们日常使用电脑,接触的都是文件、文件夹、C 盘 D 盘,从来不用管什么扇区号。
这中间的 "翻译官" 就是文件系统。它把零散的扇区组织管理起来,让我们能用文件名、路径来操作数据。今天我们就以 Linux 经典的 Ext 系列(Ext2/3/4)文件系统为例,从底层拆解它的工作原理,全程结合 Windows 里的概念帮你理解。
一、两个前置概念:块 与 分区
在讲文件系统之前,先搞懂两个最基础的概念。
1. 块(Block):文件存取的最小单位
磁盘物理读写的最小单位是扇区(512 字节),但操作系统如果一个个扇区去读写,效率会非常低。所以文件系统把连续的多个扇区组成一个 "块",作为文件存取的最小单位。
最常见的块大小是 4KB,也就是连续 8 个扇区。
- 块大小是格式化的时候确定的,一旦定了就不能更改。
- 哪怕文件只有 1 字节,也要占用一整个块的空间。
💡 类比理解:就像超市卖糖,不会一颗一颗卖给你,而是按袋卖。一袋就是一个 "块",批量交易效率更高。
我们用stat 文件名命令,就能看到文件占用了多少个块。
2. 分区(Partition):硬盘的逻辑划分
一块物理硬盘可以分成好几个逻辑区域,每个区域就是一个分区。对应到 Windows 里,就是我们熟悉的 C 盘、D 盘、E 盘。
- 分区的本质:以柱面为单位,给硬盘划分范围,规定每个分区的起始柱面和结束柱面。
- 为什么要分区:数据隔离(系统和文件分开)、不同分区可以用不同文件系统、方便管理。
二、inode:文件的 "身份证"
Linux 里有一句话:一切皆文件。那一个文件到底由什么组成?
文件 = 文件内容 + 文件属性
文件内容就是里面的数据,而文件属性包括文件大小、所有者、权限、创建时间、修改时间等等。这两部分是分开存储的:
- 文件内容:存在数据块(Block)里
- 文件属性 :存在一个叫inode(索引节点) 的结构里
1. inode 是什么
inode 是文件的 "身份证":
- 一个文件对应一个 inode,每个 inode 有唯一的 inode 号
- inode 里保存了文件的所有属性信息,但不保存文件名
- inode 的大小是固定的,一般是 128 字节或 256 字节
💡 类比理解:inode 就像身份证号,每个人唯一。身份证里存着你的姓名、年龄、住址等信息(对应文件属性),而你本人(对应文件内容)住在房子里(对应数据块)。
2. 验证 inode
用ls -li命令,第一列显示的就是 inode 号:
ls -li
如果你看到两个文件名的 inode 号完全一样,那它们本质上就是同一个文件(硬链接)。
三、Ext 文件系统的结构:块组
Ext 系列文件系统,会把一个分区分成很多个大小相同的块组(Block Group)。每个块组的结构完全一样,独立管理自己的块和 inode。
可以类比成:一个国家分成很多个省,每个省都有自己的政府、户籍系统、土地资源,各自管理自己区域内的人和事。
每个块组从前往后,依次由这几部分组成:
1. 超级块(Super Block)
超级块保存的是整个文件系统的全局信息:比如总共有多少个块、多少个 inode、空闲块数量、块大小、最近一次挂载时间、最近一次写入时间等等。
- 超级块是文件系统的 "总地图",如果超级块坏了,整个分区的文件系统就瘫痪了。
- 为了防止损坏,每个块组的开头都会保存一份超级块的备份。
2. 块组描述符表(GDT)
块组描述符表,记录每个块组的描述信息:比如这个块组里块位图在哪、inode 位图在哪、inode 表的起始位置、空闲块和空闲 inode 还有多少个。
相当于每个省的行政信息表,记录着本省的资源情况。
3. 块位图(Block Bitmap)
用二进制的每一位,来对应一个数据块是否空闲:1 表示已占用,0 表示空闲。
- 找空闲块的时候,直接查位图就能快速找到,不用遍历整个磁盘。
💡 类比:就像电影院的座位表,哪个位置卖了票、哪个空着,一眼就能看清楚。
4. inode 位图(Inode Bitmap)
和块位图原理一样,用每一位记录一个 inode 是否空闲。创建新文件的时候,先查 inode 位图找空闲 inode。
5. inode 表(Inode Table)
存放这个块组里所有 inode 的集合,就是一整块连续的区域,每个 inode 大小固定。相当于户籍管理处,集中存放所有人的身份证档案。
6. 数据块(Data Blocks)
这是真正存放文件内容的区域。
- 普通文件:数据块里存的就是文件的实际内容
- 目录文件:数据块里存的是**"文件名 + inode 号" 的映射表**
划重点:目录也是一种文件!它的内容就是里面所有子文件、子目录的名字,以及它们对应的 inode 号。这也是为什么文件名不存在 inode 里 ------ 因为文件名是目录的内容。
四、创建一个文件,底层发生了什么?
我们执行touch abc创建一个新文件,底层其实做了 4 件事:
- 分配 inode:查 inode 位图,找到一个空闲的 inode 号,把文件的权限、所有者、时间等属性写进这个 inode 里。
- 分配数据块:查块位图,找到需要的空闲数据块,把文件内容写进去。
- 记录映射:在 inode 里,记录下文件内容占用的数据块编号,这样以后通过 inode 就能找到文件内容。
- 更新目录 :在当前目录文件里,添加一条记录
(abc, inode号),把文件名和 inode 绑定起来。
完成这四步,一个文件就创建好了。以后我们访问文件名 abc,系统就会先查当前目录的映射表,找到 inode 号,再通过 inode 找到数据块,读到文件内容。
五、路径解析:怎么通过路径找到文件
我们访问一个文件,比如/home/whb/code/test.c,系统是怎么一步步找到它的?这个过程就叫路径解析。
- 系统知道根目录
/的 inode 号,先打开根目录文件。 - 在根目录的内容里,找到
home对应的 inode 号,打开 home 目录文件。 - 在 home 目录里,找到
whb对应的 inode 号,打开 whb 目录文件。 - 在 whb 目录里,找到
code对应的 inode 号,打开 code 目录文件。 - 最后在 code 目录里,找到
test.c对应的 inode 号,成功访问文件。
路径缓存:dentry
如果每次访问文件都要从根目录一层层读磁盘,那速度会非常慢。所以 Linux 内核做了优化:目录项缓存(dentry)。
它把访问过的路径结构,在内存里维护成一棵目录树。下次再访问相同路径,直接从内存缓存里就能找到,不用再读磁盘。这就是为什么第二次打开同一个文件,比第一次快很多。
六、挂载:分区和目录的绑定
分区分好了,文件系统也写好了,怎么才能让用户用到它?
- Windows 的做法:给分区分配一个盘符,比如 C:、D:、E:
- Linux 的做法:把分区挂载到目录树的某个目录上。以后访问这个目录,就是访问这个分区里的内容。
💡 类比理解:就像你插一个 U 盘到电脑,Windows 会给它分配 F 盘,打开 F 盘就是看 U 盘里的内容。Linux 里就是把 U 盘挂载到/mnt/usb目录,打开/mnt/usb就是访问 U 盘。
关键结论
- 不挂载的分区,是无法直接访问的。
- 通过路径的前缀,就能判断文件属于哪个分区。
mount命令用来挂载,umount命令用来卸载。
七、软硬链接:结合 Windows 彻底搞懂
硬链接和软链接是 Linux 的经典考点,很多人容易混淆。结合 Windows 的概念,其实非常好理解。
1. 硬链接(Hard Link)
- 本质:多个文件名指向同一个 inode,相当于给同一个文件起了多个别名。
- 命令 :
ln 源文件 链接文件 - 特点 :
- 硬链接文件和原文件的 inode 号完全相同
- 删除其中一个,只是删除了目录里的一条记录,inode 的硬链接数减 1;只要链接数不为 0,文件就真实存在。
- 不能跨分区(inode 号是分区内唯一的)
- 不能给目录创建硬链接(
.和..除外)
💡 类比:就像同一个人,有大名、小名、外号,叫哪个名字都是指这个人。删掉大名,这个人并不会消失。
2. 软链接(符号链接 Symbolic Link)
- 本质 :一个独立的文件,它的内容是另一个文件的路径。完全等同于 Windows 里的快捷方式。
- 命令 :
ln -s 源文件 链接文件 - 特点 :
- 有自己独立的 inode 号
- 删除原文件,软链接就会失效(变成死链接),就像原文件删了,快捷方式就打不开了。
- 可以跨分区
- 可以给目录创建软链接
3. 软硬链接对比表
表格
| 特性 | 硬链接 | 软链接 |
|---|---|---|
| inode 号 | 与原文件相同 | 独立的 inode 号 |
| 本质 | 同一个文件的多个别名 | 独立文件,保存原文件路径 |
| 删除原文件 | 不受影响,链接数减 1 | 失效,变成死链接 |
| 跨分区 | 不支持 | 支持 |
| 作用于目录 | 不支持 | 支持 |
| Windows 对应概念 | (不常用)同一文件的多入口 | 快捷方式 |
八、补充:文件的三个时间
用stat命令查看文件详情,会看到三个时间:
- Access(atime):最后访问时间,文件被读取就会更新
- Modify(mtime):文件内容最后修改时间,只有改了文件内容才更新
- Change(ctime):文件状态最后修改时间,改权限、改所有者、改名字等属性变化时更新
对应 Windows 文件属性里的 "访问时间""修改时间",不过 Windows 有 "创建时间",Linux 对应的是状态改变时间,略有区别。
总结
从磁盘扇区,到块、inode、块组,再到目录、路径、挂载、链接,整个文件系统的底层链路就通了。
文件系统本质上就是一个 "管理者":它把磁盘的物理扇区组织起来,向上提供友好的文件、目录、权限接口,让用户不用关心底层硬件细节。理解这些原理,不仅能帮你更好地理解 Linux "一切皆文件" 的设计哲学,也能更高效地排查磁盘满、文件丢失、链接失效等问题。