Ext系列⽂件系统

理解硬件

磁盘最基本的层次概念

CHS地址定位 ⽂件=内容+属性都是数据,⽆⾮就是占据那⼏个扇区的问题!能定位⼀个扇区了,能不能定位多个扇 区呢?

柱⾯(cylinder),磁头(head),扇区(sector),显然可以定位数据了,这就是数据定位(寻址)⽅ 式之⼀,CHS寻址⽅式。

• 扇区是从磁盘读出和写⼊信息的最⼩单位,通常⼤⼩为 512 字节。

  • 8 个 512B 扇区 = 4KB

  • 1MB = 1024 * 1024 B

• 磁头(head)数:每个盘⽚⼀般有上下两⾯,分别对应1个磁头,共2个磁头

• 磁道(track)数:磁道是从盘⽚外圈往内圈编号0磁道,1磁道...,靠近主轴的同⼼圆⽤于停靠磁 头,不存储数据

• 柱⾯(cylinder)数:磁道构成柱⾯,数量上等同于磁道个数

• 扇区(sector)数:每个磁道都被切分成很多扇形区域,每道的扇区数量相同

• 圆盘(platter)数:就是盘⽚的数量 • 磁盘容量=磁头数× 磁道(柱⾯)数× 每道扇区数× 每扇区字节数

• 细节:传动臂上的磁头是共进退的(这点⽐较重要,后⾯会说明)

CHS 和 LBA,只要理解,不必深算

  • CHS:老式按柱面/磁头/扇区定位

  • LBA:现代更常用的线性编号定位

只要扇区有编号,那么块也一定能编号。

  • 把磁盘看成一维数组

  • 下标就是 LBA

  • 每个元素是一个扇区

这个思路非常重要。它想表达的是: 磁盘在逻辑上可以被看成线性编号的空间。既然扇区能编号,那块由多个扇区组成,也就能编号

比如:

  • 1 个块 = 8 个扇区

  • 那么块号和 LBA 之间就能换算:

  • 已知 LBA,可算 块号 = LBA / 8

  • 已知 块号,可算块内各扇区的大致范围

块不是虚构出来的,它最终一定落在一串连续扇区上。

  • 现代系统更偏向逻辑编号

  • 这和后面 block、inode 编号思路一致

引⼊⽂件系统

"块"概念

硬盘是典型的"块"设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样 效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个"块"(block)。

硬盘的每个分区是被划分为⼀个个的"块"。⼀个"块"的⼤⼩是由格式化的时候确定的,并且不可 以更改,最常⻅的是4KB,即连续⼋个扇区组成⼀个"块"。"块"是⽂件存取的最⼩单位。

总结:

  • 块是文件系统操作磁盘的基本单位

  • 块通常由多个扇区组成

  • 常见块大小是 4KB

  • 常见扇区大小是 512B

  • 所以常见情况下 1 block = 8 sectors

  • 逻辑上磁盘可以按 LBA 编号

  • 块号和扇区编号之间可以换算

  • 硬盘是块设备,文件系统通常按块而不是按字节管理磁盘。

  • 块是文件系统存取数据的基本单位。

  • 一个块通常由多个连续扇区组成。

  • 常见情况下:1 block = 4KB = 8 * 512B sector

  • 扇区有 LBA 编号,块也可以由扇区编号推导出来。

引入"分区"概念

磁盘不是只能整体使用,通常会被切分成多个区域,每个区域就是一个分区

柱⾯是分区的最⼩单位,我们可以利⽤参考柱⾯号码的⽅式来进⾏分区,其本质就是设置每个区的起 始柱⾯和结束柱⾯号码。

分区的本质就是在磁盘逻辑空间里划出一段连续范围。

**- 分区是对磁盘逻辑空间的切分。

  • 文件系统通常创建在分区上。
  • 不同分区可以分别格式化、分别挂载、分别管理。
  • 后续 inode、block、super block 等概念通常都要放在"某个分区内"去理解。**

引入 inode 概念

⽂件 = 数据 + 属性

我们使⽤ls -l 的时候看到的除了看到⽂件名,还能看到⽂件元 数据(属性)。

cpp 复制代码
[root@localhost linux]# ls -l
-rwxr-xr-x. 1 root root 7438 "9⽉13 14:56" a.out
-rw-r--r--. 1 root root  654 "9⽉14:56" test.c

每⾏包含7列:

  • 权限 - 硬链接数 - 所有者 - 所属组 - 大小 - 时间 - inode 号

文件 = 数据 + 属性。这里的"属性",在 Linux 文件系统里就主要由 inode 负责保存。

注意: 文件名不在 inode 里。文件名以后由目录来保存,目录负责建立"文件名 -> inode号"的映射

⽂件数据都储存在"块"中,那么很显然,我们还必须找到⼀个地⽅储存 ⽂件的元信息(属性信息),⽐如⽂件的创建者、⽂件的创建⽇期、⽂件的⼤⼩等等。这种储存⽂件 元信息的区域就叫做inode,中⽂译名为"索引节点"。

Linux下⽂件的存储是属性和内容分离存储的 ,Linux下,保存⽂件属性的集合叫做inode,⼀个⽂件,⼀个inode,inode内有⼀个唯⼀ 的标识符,叫做inode号

总结:

  • Linux 下文件的属性信息保存在 inode 中。

  • inode 是索引节点,是文件元信息的数据结构。

  • inode 中保存权限、大小、时间、链接数、数据块位置等信息。

  • 每个文件都有 inode 号。

  • 文件内容和属性是分离存储的。

  • 文件名不在 inode 中,文件名与 inode 的对应关系由目录维护。

文件系统要先解决"空间怎么组织"和"文件属性怎么管理"这两个问题,然后才能谈文件名和路径。

具体来说:

  • 块 解决"磁盘空间按什么单位管理"

  • 分区 解决"在哪个范围内建立文件系统"

  • inode 解决"文件属性和索引信息存在哪"

ext2 ⽂件系统

宏观认识

我们想要在硬盘上储⽂件,必须先把硬盘格 式化为某种格式的⽂件系统,才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。

ext 文件系统是在分区内部,用一套固定的数据结构,把"空间管理、文件属性、文
件内容、文件名、路径访问"全部组织起来。

ext2 不会把整个分区当成一团混乱空间来管理,而是把整个分区切成多个 Block

Group。

Block Group

文件系统内部重复出现的一个"管理分区小单元"。ext2 的思路是:把整个分区切成很多个小组,每组内部都有自己的管理信息和数据区域。

块组内部构成

  • 超级块 Super Block

  • GDT Group Descriptor Table

  • 块位图 Block Bitmap

  • inode 位图 Inode Bitmap

  • inode 表 Inode Table

  • 数据块 Data Block

一个完整流程:

  1. 文件系统先要知道自己总体长什么样

  2. 再要知道每个组内部结构长什么样

  3. 再要知道哪些块空闲、哪些 inode 空闲

  4. 再要有地方真正存 inode

  5. 再要有地方真正存文件内容

超级块(Super Block)

超级块保存整个文件系统的全局信息。注意是"整个文件系统"的信息,不是某一个文件的信息。

里面大概会记录:

  • inode 总数

  • block 总数

  • 空闲 block 数

  • 空闲 inode 数

  • block 大小

  • 每组多少 block

  • 每组多少 inode

  • 文件系统状态

  • 最近挂载时间

  • 最近写入时间

  • inode 大小等

  • Super Block = 文件系统全局元数据

  • 记录总量、空闲量、block/inode 参数、状态、时间等

  • 超级块极其重要,因此有冗余备份

GDT(Group Descriptor Table)

它记录什么?比如:

  • 这个块组的 block bitmap 在哪

  • inode bitmap 在哪

  • inode table 在哪

  • 这个组还有多少空闲 block

  • 这个组还有多少空闲 inode

块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符。

如果说: 超级块是"全局总账本",那 GDT 就是:每个块组的导航表。GDT 管每个块组的细节位置和资源情况。GDT = Block Group 的描述信息表

块位图(Block Bitmap)

BlockBitmap中记录着DataBlock中哪个数据块已经被占⽤,哪个数据块没有被占⽤

  • Block Bitmap:记录数据块空闲/占用状态

  • 一个 bit 对应一个 block

  • 用 0/1 记录这个块是否被占用

inode 位图(Inode Bitmap)

  • Inode Bitmap:记录 inode 是否已分配

  • 创建文件 = 分发inode + 分发block

它记录:

  • 哪些 inode 已经分配给文件

  • 哪些 inode 还空闲

节点表(Inode Table)

inode 不仅是概念,而且在磁盘上有固定、可定位的存储区域。

  • Inode Table 存放 inode 结构本体

  • inode 大小通常固定

  • 知道 inode 号后可以定位到 inode 表中的具体位置

  • inode 号的意义依赖于所在分区/文件系统

  • Inode Table = inode 的磁盘存储区

  • inode号在分区内有意义,不可脱离分区单独谈

Data Block

这里正式落地:

  • 普通文件内容,比如代码、文本、图片字节流

  • 最终都放在数据块中

所以一个文件可以理解成两层:

  1. inode:记录文件属性、大小、权限、数据块位置等

  2. data block:真正存放文件内容

  • 文件内容存储在 Data Block

  • inode 记录的是内容在哪里

  • 文件本质上是 inode 和数据块共同构成的

  • Data Block:存真正的文件内容

  • inode:存属性 + 内容位置

inode 和 datablock 映射

不必细究,知道了解即可

inode 是文件属性和文件内容之间的桥梁。

inode 里面保存了"这个文件内容在哪些块里"的映射信息。也就是说,inode 不只是存权限、大小,它还像一张索引表:

  • 第一个内容块在哪

  • 第二个内容块在哪

  • 后面块在哪

于是系统流程就是:

  1. 先通过文件名找到 inode 号

  2. 再从 inode 表中找到 inode

  3. 再从 inode 中找到对应的数据块列表

  4. 最后读出内容

总结:

  • inode 中有 data block 的映射关系

  • 系统读文件时,不是直接靠文件名找内容,而是靠 inode 找 block

  • 文件名只是入口,inode 才是核心索引

  • inode 的核心职责之一:记录文件内容所在的数据块位置

  • 读文件流程本质:文件名 -> inode号 -> inode -> data blocks

目录与文件名

目录的本质作用,不是"装文件内容",而是维护文件名到 inode 号的映射。

文件名不是存在 inode 里的。而是放在目录里。 而且目录本身也是文件。 目录文件里保存的是一条条目录项,每个目录项大致就是: 文件名 ,对应 inode 号

  • 目录也是文件

  • 目录中保存目录项

  • 目录项建立"文件名 -> inode号"的对应关系

  • 文件名和 inode 分开存储

  • 目录的本质:维护文件名与 inode 号的映射关系

  • 文件名不在 inode 中

路径解析

路径解析本质上是:逐级目录查表的过程。路径访问本质是目录递归查找 inode。

路径缓存

如果每次路径解析都重新从磁盘一级一级找,会非常慢,所以内核会做缓存。

  • 路径查找可能被缓存加速

  • 缓存的是路径/目录项相关结果

  • 这是为了减少频繁磁盘访问

  • 路径缓存用于加速目录项查找和路径解析

挂载分区

它回答了一个很现实的问题:

如果 inode、block、super block 这些都只在某个分区里有意义,那 Linux 为什么

看起来像只有一棵统一目录树?

答案就是:**挂载 mount。**挂载的本质,记成一句话:把某个分区上的文件系统接到某个目录上。

挂载的本质意义:Linux 的统一目录树,不是因为只有一个文件系统,而是因为多个文件系统通过挂载拼接到了同一棵树上。即:把一个文件系统接入目录树

  • 文件系统通常建立在分区或设备上

  • 挂载后才能方便纳入 Linux 统一目录树

  • 挂载点是目录

  • 用户看到的是统一树,底层可能是多个文件系统拼起来的

总结:

ext 文件系统整个访问过程:

  1. 磁盘被切成分区

  2. 某个分区上建立 ext 文件系统

  3. ext 文件系统把分区划成多个 Block Group

  4. 每个块组里有超级块/GDT/位图/inode表/数据块

  5. 文件内容存 data block

  6. 文件属性和内容位置存 inode

  7. 目录维护"文件名 -> inode号"

  8. 路径解析逐级查目录找到目标 inode

  9. 挂载把这个文件系统接入 Linux 统一目录树

ext 文件系统的本质,就是在分区上用一套分组、索引、映射和目录结构,把原始磁盘空间变成"可按文件名访问的文件世界"。

  • ext2 按 Block Group 管理分区

  • Super Block:全局元数据

  • GDT:每组描述信息

  • Block Bitmap:块分配状态

  • Inode Bitmap:inode 分配状态

  • Inode Table:inode 存储区

  • Data Block:文件内容存储区

  • inode -> data block 映射

  • 目录维护"文件名 -> inode号"

  • 路径解析逐级查找

  • 挂载把多个文件系统接入统一目录树

软硬连接

这一章到底想表达什么?:在 Linux 里,文件名和文件本体不是一回事。

更准确地说:

  • 真正代表文件本体的是 inode

  • 文件名只是目录里的一个映射项

  • 所以可以出现:

  • 多个文件名指向同一个 inode

  • 一个文件去指向另一个文件的路径

这就分别对应: 硬链接 软链接

所以这一章真正要讲清楚的是:"名字"和"文件"到底是什么关系。

硬链接

硬链接就是让多个文件名对应同一个 inode:

cpp 复制代码
  ln abc def

这条命令不是"复制一个新文件"。

它做的事情是:

  • 原来有个名字叫 abc

  • 现在再增加一个名字叫 def

  • 这两个名字都指向同一个 inode

所以本质上是:

abc -> inode 100

def -> inode 100

这就是硬链接。 删除一个硬链接,不一定删除文件本身

inode 的硬链接数会增加创建硬链接前,可能是:Links: 1创建后,可能变成: Links: 2。这也是为什么 ls -l 的第二列会变化。

软链接

⾯解释⼀下三个时间: • Access最后访问时间 • Modify⽂件内容最后修改时间 • Change属性最后修改时间

软链接是一个独立的新文件,这个文件里保存的是目标文件的路径或名字信息。

cpp 复制代码
 ln -s abc def

这时 def 就是一个软链接。 它和硬链接最大的区别是:软链接不会和目标共享 inode。 也就是说:

abc -> inode 100

def -> inode 200

def 自己有自己的 inode。它不是 abc 的第二个名字。 它只是"指向 abc 的一个特殊文件"。

软链接和硬链接看起来都像"指向另一个文件",但底层完全不是一回事。

硬链接是:直接共享 inode

软链接是:通过名字/路径去引用目标

所以它们的层次不一样:硬链接是 inode 级别,软链接是路径级别

总结:- 软链接是一个独立文件

  • 软链接有自己的 inode

  • 软链接通过路径引用目标

  • 软链接不共享目标文件的 inode

  • 目标删除后,软链接可能悬空失效

软硬连接对⽐

对比项 硬链接 (Hard Link) 软链接 (Symbolic Link)
1. inode 是否相同 相同 inode 不同 inode
2. 本质是什么 多个文件名映射到同一个 inode 一个独立文件 ,其内容是目标文件的路径信息
3. 删除目标文件后的表现 删除其中一个文件名,只要该inode还有其它链接(文件名),文件数据依然存在 若目标文件被删除或移动,软链接将失效(成为"悬空链接")。
**4. 是否是真正的"同一个文件"**​ ,它们指向同一个inode,是同一个文件对象的多个别名。 不是,它是一个独立的文件,通过路径指向另一个文件。
5. 原因/引用层次 inode 层​ 建立引用。 文件路径(目录)层​ 建立引用。

硬链接的用途

硬链接更适合:

  • 给同一个文件提供多个名字入口

  • 不复制内容而共享同一个文件实体

  • 从理解文件系统角度,帮助你看清"文件名和 inode 的关系"

软链接在实际中更常用。适合做:

  • 快捷入口

  • 版本切换

  • 目录映射

  • 兼容旧路径

  • 给一个深路径起一个短名字

例如实际系统里很常见:

  • 某个 current 指向某个版本目录

  • 某个命令路径是另一个位置的软链接

因为软链接本质上是"路径级别的引用",所以它非常灵活。

总结:
Linux 中文件名只是目录中的映射项,真正的文件核心是 inode;硬链接和软链接分别从 inode 层和路径层证明了这一点。

  • 硬链接 = 多个文件名 -> 同一个 inode

  • 软链接 = 一个独立文件 -> 保存目标路径

  • 硬链接共享 inode,软链接不共享 inode

  • 删除硬链接只是删一个名字映射

  • 软链接目标删掉后可能失效

  • 文件名不在 inode 中,目录负责维护名字与 inode 的关系

  • 真正标识文件的是 inode,不是文件名。

  • 硬链接是多个文件名对应同一个 inode。

  • 软链接是保存目标路径的独立文件。

  • 硬链接不创建新的文件本体。

  • 软链接有自己的 inode。

  • 硬链接和软链接的根本区别在于:一个是 inode 级引用,一个是路径级引用。

相关推荐
野犬寒鸦2 小时前
面试常问:什么是TCP连接:虚拟对话通道的奥秘
服务器·网络·后端·tcp/ip·面试·tcpdump
蜜獾云2 小时前
从linux内核理解Java怎样实现Socket通信
java·linux·运维
痴心阿文2 小时前
Nextjs用法整理
运维·服务器
小鹿软件办公2 小时前
谷歌将在2026年第二季度为ARM64 Linux设备推出Chrome
linux·chrome
被遗忘的旋律.2 小时前
Linux驱动开发笔记(二十六)——PWM(SG90驱动)
linux·驱动开发·笔记
赵民勇2 小时前
gtk-update-icon-cache用法技巧总结
linux
wefg12 小时前
【Linux】线程同步与互斥 - 2(线程同步/条件变量/基于阻塞/环形队列的cp模型/线程池/线程安全/读写锁)
linux·开发语言
小生不才yz2 小时前
【Makefile 专家之路 | 基础篇】02. 初试锋芒:编写第一个 Makefile 与运行机制深度剖析
linux
Xu_youyaxianshen3 小时前
[特殊字符] Docker 小白极速入门笔记
linux·docker