理解硬件
磁盘、服务器、机柜、机房


- 机械磁盘是计算机中唯一的一个机械设备
- 随机读写速度慢
- 容量大,价格便宜
磁盘核心物理部件

- 盘片(Platter)
- 磁盘的数据真正存储载体,材质为铝合金 / 玻璃基底,表面喷涂磁性涂层。
- 数据以磁性磁极方向记录二进制 0、1,盘面正反两面都可存储数据。
- 磁头(Head)
- 负责读取、写入盘面磁性数据的感应元件,每一张盘面都对应独立磁头。
- 写入:改变盘面磁极方向;读取:感应磁极信号,转化为电信号数据。
- 磁臂(Arm)
- 固定所有磁头的支架,可做径向伸缩摆动。
- 作用:带动磁头在盘片同心圆轨迹之间移动,切换不同磁道位置。
- 主轴电机(Spindle Motor)
- 驱动所有盘片同步高速旋转的动力核心。
- 转速单位:RPM 转 / 分钟,转速越高,数据读取等待时间越短。
- 常见规格:家用 7200 转,企业服务器 10000 转、15000 转。
- 密封盘腔 + 外部电路板
- 密封腔体:内部真空无尘,杜绝灰尘划伤高速运转的盘片,灰尘会直接造成磁盘坏道。
- 电路板:磁盘的控制中枢,接收主板读写指令、缓存临时数据、转换电信号与磁信号。
磁盘的存储结构



注意:传动臂上的磁头是共进退的
1. 磁道 Track
- 形成原理:盘片高速旋转,磁头保持静止,在盘面划过一圈同心圆轨迹,即为一条磁道。
- 作用:磁头定位到指定磁道,才能继续读取内部扇区数据。
2. 扇区 Sector
- 磁盘最小物理存储单元
- 传统标准扇区:512 字节
- 形态:盘片被径向切割成无数扇形小块,每一块就是一个扇区
- 读写约束:硬件只能整扇区读写,哪怕只修改 1 个字节,也要读取整个扇区、修改后再整扇写回
3. 柱面 Cylinder
- 一块硬盘内部所有盘片上,半径完全相同的多条磁道,纵向堆叠形成一个虚拟圆柱面,称为柱面
如何定位一个扇区呢?(CHS地址定位法)
- 定位柱面:磁盘控制器驱动音圈电机,带动磁臂径向移动,将磁头对准指定柱面
- 选定磁头 :电路切换,启用对应编号的磁头,对准目标盘面
- 等待扇区轮转:盘片高速旋转,直到目标编号扇区转动到磁头正下方
计算磁盘容量公式:
磁盘总容量 = 磁头数 × 柱面数(磁道数) × 每磁道扇区数 × 单扇区字节数
磁盘的逻辑结构
理解过程


真实过程

所以,磁盘的真实情况是:
磁道:
某一盘面的某一磁道展开:

即:一维数组
柱面:
整个磁盘所有盘面的同一个磁道,即柱面展开:

- 柱面上的每个磁道,扇区个数是一样的
- 这不就是二维数组吗
整盘:

- 整个磁盘不就是多张二维的扇区数组表(三维数组?)
所以,寻址一个扇区:先找到哪一个柱面(Cylinder) ,再确定柱面内哪一个磁道(其实就是磁头位置,Head),最后确定扇区(Sector),所以就有了 CHS 。
总结:
不管是二维数组还是三维数组,其实都是一维数组:

所以,每一个扇区都有一个下标,我们叫做 LBA(Logical Block Address) 地址,其实就是线性地址
CHS 寻址 与 LBA 寻址
CHS、LBA 是磁盘两种扇区定位编码体系 ,核心作用只有一个:唯一确定磁盘上任意一个物理扇区。
- CHS :贴合磁盘机械物理结构的三维坐标寻址,老式磁盘标准
- LBA :抹平物理差异的一维线性逻辑寻址,当前 Linux、文件系统、硬盘通用标准
上层操作系统、文件系统只使用 LBA;磁盘硬件底层最终会转换为 CHS 完成机械定位,二者可以相互换算
CHS 三维寻址
全称与坐标形式
- Cylinder (柱面) + Head (磁头) + Sector (扇区)
用一组三维坐标(C, H, S)锁定单个扇区。
CHS 物理定位全过程
- 控制器依据柱面号,驱动磁臂移动到目标径向位置
- 电路切换,启用指定编号磁头,对准对应盘面
- 盘片高速旋转,等待目标扇区转动至磁头正下方
- 锁定位置,执行数据读取或写入操作
寻址容量瓶颈
早期 CHS 采用固定位数存储坐标数值,可表示的柱面、磁头、扇区数量有上限,最大只能支持 GB 级小容量硬盘,无法满足如今 TB 级大容量存储需求。
CHS 优缺点
优点
- 完全匹配磁盘机械结构,硬件底层理解直观
- 小容量硬盘寻址响应直接
缺点
- 三维坐标计算繁琐,程序调用复杂度高
- 地址位数受限,容量扩展性极差
现存使用场景
仅保留在主板 BIOS、磁盘固件底层做兼容适配,现代OS不会直接下发 CHS 地址指令。
LBA 一维逻辑寻址
全称
Logical Block Address 逻辑块寻址
核心原理:抛弃磁盘三维物理结构概念,将所有物理扇区扁平化处理,按顺序编成一维连续数字编号,只用单个数字就能唯一定位一个扇区,彻底解决老式 CHS 寻址的容量瓶颈与兼容难题
LBA 核心设计思想
- 忽略盘片、柱面、磁头的物理形态,把立体的磁盘存储空间,拉伸成一条笔直的线性存储空间
- 每一个 LBA 编号,严格对应磁盘上唯一一个物理扇区
- 软硬件分层解耦:上层系统只操作一维数字地址,无需关心硬件结构;磁盘固件内部自动完成逻辑地址到物理坐标的转换
扇区编排排序规则
通俗排布流程
- 先遍历第 0 号柱面,依次切换每一个磁头;
- 每个磁头对应的磁道里,按扇区顺序逐个编号;
- 第 0 柱面全部扇区编号完成后,继续编号第 1 柱面、第 2 柱面...... 直至整块磁盘所有扇区编完。
即:

LBA 完整寻址执行流程
- 系统下发逻辑地址:操作系统、文件系统计算出目标 LBA 编号,仅向磁盘控制器传递这一个数字。
- 固件自动地址转换 :磁盘内置固件接收 LBA 值,按照换算公式,自动把一维 LBA 地址,转换成硬件可识别的CHS 三维物理坐标。
- 机械物理定位:磁盘根据柱面、磁头、扇区坐标,驱动磁臂移动、切换磁头、等待盘片旋转,精准找到目标物理扇区
- 完成数据读写:对定位到的扇区执行读取或写入操作,数据原路返回上层系统
LBA 与 CHS 地址换算原理
LBA 只是逻辑编号,最终定位依旧依靠物理 CHS 坐标,二者存在固定数学映射关系
设定参数:
- Htotal = 磁盘总磁头数
- Strack = 单条磁道包含扇区数
- 磁头数 * 每磁道扇区数(Htotal × Strack)= 单个柱面的扇区总数
1. CHS → LBA
-
LBA = 柱面号( C ) × 单个柱面的扇区总数(Htotal × Strack) + 磁头号( H ) × 单条磁道包含扇区数(Strack) + 扇区号(S) − 1
-
减 1 原因:CHS 扇区从 1 编号,LBA 从 0 编号,对齐数值偏移
2. LBA → CHS
- 柱面号( C ) = LBA ÷ 单个柱面的扇区总数(Htotal × Strack)
- 磁头号( H ) = (LBA ÷ 单条磁道包含扇区数(Strack))% 总磁头数(Htotal)
- 扇区号( S ) = (LBA % 单条磁道包含扇区数(Strack))+ 1
引入文件系统
原始磁盘分区只有物理扇区,操作系统无法直接高效管理文件。文件系统的核心作用就是将无序的磁盘物理空间,规整为有序的逻辑空间,实现文件的存储、检索、权限管理。这里引入三个核心基石概念:块、分区、inode
块(Block):文件系统最小读写单元
磁盘最小物理单元是512字节扇区,操作系统如果以扇区读写,效率极低。因此文件系统将多个连续扇区组合为一个块,作为系统读写的最小单位
块的标准定义
- 物理构成 :由一段连续的物理扇区聚合而成
- 层级属性:纯软件逻辑概念,磁盘硬件本身不存在块
- 是文件系统最小读写单位 和文件系统最小空间分配单位
Linux Ext文件系统默认块大小:4KB(8个512字节扇区),可在格式化时指定(1K/2K/4K)

注意:
- 磁盘就是一个三维数组,我们把它看待成为一个"一维数组",数组下标就是LBA,每个元素都是扇区
- 每个扇区都有LBA,那么8个扇区一个块,每一个块的地址我们也能算出来。
- 知道LBA:
块号 = LBA / 8 - 知道块号:
LBA = 块号 * 8 + n(n是块内第几个扇区)

分区(Partition):磁盘空间隔离机制
核心逻辑:磁盘→分区→格式化(生成文件系统)→挂载→可读写文件
物理上整块硬盘依旧完整一体,但软件层面实现彻底隔离:
- 格式化、清空、损坏某一个分区,不会篡改、破坏其他分区的扇区数据;
- 系统读写文件时,只会访问当前分区对应的 LBA 区间,不会越界访问其他分区
柱面是分区的最小单位,我们可以利用参考柱面号码的方式来进行分区,其本质就是设置每个区的起始柱面和结束柱面号码。

inode(索引节点):文件的唯一身份证
Linux中文件分为两部分,缺一不可:
- 元数据:文件属性(大小、权限、所有者、修改时间、数据块编号),存储在 inode 中。
- 数据:文件真实内容,存储在 Data Block(数据块)中
本质:inode 是一份文件的身份档案 + 寻址路标,只存文件属性与数据位置,不存放文件名,也不存放文件实际内容。
inode 内部存放的信息
- inode 编号:分区内文件唯一标识 ID
- 文件类型:普通文件、目录、符号链接、设备文件、管道文件
- 访问权限:r 读 w 写 x 执行,管控用户访问权限
- 所有者 UID、所属组 GID:记录文件归属用户
- 文件大小:占用存储空间字节数
- 硬链接计数:统计有多少个文件名指向该 inode
- 三个时间戳
atime:最后访问读取时间
mtime:最后修改文件内容时间
ctime:最后修改文件属性 / 权限时间 - 数据块指针数组(核心)
共 15 个指针,指向存放真实内容的数据块编号,用来寻址文件内容
inode 核心特性
- 分区内编号唯一,跨分区可重复
- 不存储文件名,文件名归属目录管理
- 每个文件有且仅有一个唯一 inode 号,是文件的唯一标识
- 删除文件不会立刻擦除磁盘数据
- inode的大小一般是128字节或者256,我们后面统一128字节
查看 inode 命令
- 查看文件 inode 编号
c
ls -il
- 查看完整 inode 所有属性
bash
stat 文件名
示例:

ext2 文件系统
宏观认识
我们想要在硬盘上存储文件,必须先把硬盘格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理硬盘中的文件。
ext2 是将物理磁盘空间组织成可管理文件体系的软件抽象层 ,通过块组化管理 实现资源分散与并行访问,通过inode 索引机制 实现文件身份标识与数据寻址,通过位图管理实现高效资源分配与回收。
ext2 文件系统将整个分区划分成若干个同样大小的块组 (Block Group),如下图所示。只要能管理一个分区就能管理所有分区,也就能管理所有磁盘文件

上图中启动块(Boot Block/Sector)的大小是确定的,为1KB,由PC标准规定,用来存储磁盘分区信息和启动信息,任何文件系统都不能修改启动块。启动块之后才是ext2文件系统的开始。
块组(Block Group)
块组 = 分区拆分出来的微型独立小文件系统,各自管理本组内的块、inode、空闲资源,实现分片自治管理
层级嵌套
bash
物理磁盘
↓ 划分
磁盘分区
↓ 均等切分
多个大小相同的块组
↓ 内部组成
逻辑块 Block
↓ 聚合
物理扇区 Sector
核心规则
- 一个分区包含多个块组
- 同一个分区内所有块组尺寸、内部结构完全一模一样
- 块组从 0 开始顺序编号,连续铺满整个分区空间
- Ext 系列默认:每个块组固定包含 8192 个逻辑块
块组的内部构成
1. 超级块(Super Block)
本质 :整个文件系统的全局总控制台账,记录分区整体规格与资源统计信息
存储特点
- 并非每一个块组都完整存放,只在0、1、3、5、7... 质数编号块组做冗余备份
- 块组 0 一定包含完整超级块,是系统挂载识别入口
- 格式固定为
ext2_super_block结构体
核心存放信息
- 标识类:文件系统魔数(0xEF53),用来识别是不是 Ext2
- 规格类:块大小、inode 大小、每组块数量、每组 inode 数量
- 统计类:分区总块数、总 inode 数、空闲块数、空闲 inode 数
- 时间类:最后挂载时间、最后写入时间、检查时间
作用
- 系统挂载时校验文件系统合法性
- 全局统计磁盘整体使用情况
- 副本备份防止超级块损坏导致分区无法访问
2. 块组描述符表 Group Descriptor Table(GDT)
本质 :记录所有块组基础属性与位置的索引表,每一条描述符对应一个块组
核心存放字段
- 本组块位图所在块号
- 本组 inode 位图所在块号
- 本组 inode 表起始块号
- 本组空闲块数量、空闲 inode 数量
- 本组内部目录文件个数
作用
- 快速定位当前块组内位图、inode 表的物理位置
- 实时统计本组资源余量,新建文件优先挑选富余块组
- 是连接超级块与单个块组内部资源的中间索引
3. 块位图(Block Bitmap)
本质 :二进制位状态表,专门标记当前块组内每一个逻辑块的空闲 / 占用状态
核心规则
- 1 个比特位 对应 1 个逻辑块
- 比特值 = 0 → 块空闲,可分配存储数据
- 比特值 = 1 → 块已被文件占用,不可分配
工作逻辑
- 新建文件:检索比特 0,置为 1,分配对应块
- 删除文件:对应比特改回 0,回收空间
作用:极速管理本组数据块资源,避免全局遍历查找空闲块
4. inode 位图(Inode Bitmap)
本质 :和块位图原理完全一致,专门标记inode 索引节点的空闲占用状态
工作逻辑:创建文件分配 inode、删除文件回收 inode,都依靠位图快速判定状态
5. inode 表(Inode Table)
本质 :连续存储空间,按编号顺序整齐存放本组所有 inode 结构体
基础属性
- Ext2 默认单个 inode 大小:128 字节
- 块组内 inode 数量格式化固定,顺序排列、编号唯一
作用
- 存储文件身份信息、元数据、数据寻址地址,是文件在块组里的核心标识
- 一个 inode 唯一对应一个普通文件 / 目录 / 链接文件
6. 数据块(Data Blocks)
本质 :块组内容量最大的区域,真正存放二进制真实数据的空间
按用途分为 4 类块
1. 普通数据块
存放文本、图片、程序、日志等用户真实文件内容
2. 目录块
存放目录项结构:inode编号 + 文件名 + 文件类型
实现文件名到 inode 的映射关系
3. 间接索引块
不存业务数据,只存放下级数据块指针,支撑大文件多级寻址
4. 符号链接块
存放软链接指向的目标文件路径
特性
- 文件内容优先全部存放在同一个块组,减少跨组寻道
- 超大文件空间不足时,才向相邻块组申请数据块
注意:
- inode和数据块是跨组编号的
- inode和数据块不能跨分区
- 所以,在同一个分区内部,inode编号和块号都是唯一的
inode与Data Blocks映射
inode核心功能之一就是通过指针找到文件的数据块,Ext2 inode中定义了 i_block[EXT2_N_BLOCKS] 数组(EXT2_N_BLOCKS = 15),共15个指针,采用直接+间接的映射机制,适配不同大小的文件,兼顾读写速度与存储容量:
1. 前 12 个直接指针(i_block[0] ~ i_block[11])
- 寻址规则:指针内直接存储数据块编号,无任何中间跳转
- 访问路径:
inode → 逻辑块号 → 数据块(读取内容) - 可寻址总容量:12×4KB=48KB
2. 一级间接指针(i_block[12])
- 位置:第 13 个指针
- 寻址规则:该指针不指向数据块 ,而是指向一个一级间接块;间接块内部连续存放 1024 个数据块编号。
- 访问路径:
inode → 一级间接块号 → 读取间接块 → 取出数据块号 → 数据块 - 可寻址总容量:1024×4KB=4MB
3. 二级间接指针(i_block[13])
- 位置:第 14 个指针
- 寻址规则:两层间接跳转
指针 → 二级间接块(存放一级间接块编号)→ 一级间接块(存放数据块编号)→ 数据块 - 访问路径:两次间接块读取,跳转层级更深。
- 可寻址总容量:1024×1024×4KB=4GB
4. 三级间接指针(i_block[14])
- 位置:第 15 个指针
- 寻址规则:三层间接跳转,是层级最多的寻址方式。
- 可寻址总容量:1024×1024×1024×4KB≈4TB

系统会根据文件大小,按需启用不同层级的指针,不会强制使用全部 15 个指针
结论:
- 分区之后的格式化操作,就是对分区进行分组,在每个分组中写入SB、GDT、Block Bitmap、Inode Bitmap等管理信息,这些管理信息统称:文件系统
- 只要知道文件的inode号,就能在指定分区中确定是哪一个分组,进而在哪一个分组确定是哪一个inode
问题:知道一个文件的inode编号,如何找到这个文件的所有内容和属性?
答:
逻辑流程:
bash
已知 inode 编号 → 定位 inode 表 → 读取 inode 结构体 → 直接获取【所有文件属性】
↓
解析 15 级指针 → 遍历所有数据块 → 拼接得到【文件全部内容】
补充:创建一个文件的底层流程
bash
用户命令 touch test.txt
↓
系统调用 open(O_CREAT)
↓
VFS路径解析 → 定位父目录 /home/user/
↓
选择块组 → 查找inode位图 → 分配空闲inode
↓
初始化inode:权限、时间、链接数=1、指针为空
↓
父目录数据块 → 新增目录项(test.txt → inode号)
↓
更新超级块、块组描述符、位图
↓
加载dentry缓存 + inode缓存
↓
返回文件描述符 → 文件创建成功
详细过程:
- 分配空闲 inode :读取 inode 位图 (Bitmap),找到第一个为
0的位,标记为1(占用),记录分配到的 inode 编号 ,从 inode 表 中,取出对应的空闲 inode 结构体 - 初始化 inode 元数据 :内核向新分配的 inode 写入所有文件属性(文件类型、权限、所有者 UID / 所属组 GID等等)
- (空文件跳过)分配数据块 :如果是创建非空文件 (如
echo hello > test.txt):读取 块位图 ,找到空闲逻辑块,标记块位图为已占用,将块号写入 inode 的直接指针,写入数据到数据块。 - 创建目录项(文件名 ↔ inode 绑定) :找到父目录的数据块 ,在父目录中新增一条目录项,将新目录项写入父目录的数据块(磁盘 / 缓存)
- 更新全局元数据 :
1.更新 块组描述符表(GDT) :本块组空闲 inode 数 -1;
2.更新 超级块(Superblock) :分区总空闲 inode 数 -1;
3.(如果分配了数据块)同步更新块相关统计。 - 更新内核缓存 :创建内存
dentry:绑定文件名 + inode,将新 inode 加入 inode 缓存 ,将父目录、新文件加入 路径缓存(dcache) - 返回文件描述符,完成创建

目录与文件名
目录本质是一种特殊文件,和普通文件一样拥有 inode 和数据块
目录与普通文件的核心差异
| 对比维度 | 普通文件 | 目录(文件夹) |
|---|---|---|
| inode 类型标记 | 标记为「普通文件」 | 标记为「目录文件」 |
| 数据块内容 | 文本、程序、二进制业务数据 | 一条条 目录项(文件名 + inode 映射) |
| 核心作用 | 存储用户数据 | 组织文件层级、管理文件名与 inode 的对应关系 |
| 权限语义 | r/w/x 控制文件内容读写、执行 | r/w/x 控制目录的浏览、增删、进入(语义完全不同) |
目录项定义 :目录的数据块中,按照固定格式存储的一条条记录,就叫做目录项
目录项的作用:建立 文件名 与 对应文件/子目录 inode 编号 的映射关系
用户通过文件名操作文件,系统底层永远通过 inode 识别文件,目录项就是二者的翻译器
文件名只存在于「父目录」的目录项中,绝对不会存放在 inode、文件自身的数据块里
路径解析
我们访问任何文件,都必须得有路径
所以,找到任何Linux文件,都必须从根目录开始,进行路径解析,直到找到相应文件。
路径解析流程
以 绝对路径 /home/alice/note.txt 为例,演示系统如何从路径找到文件内容
- 起点:根目录
/:系统默认获取根目录 inode(Ext2 根 inode 固定为 2),读取根目录的数据块 - 遍历根目录目录项 :在目录项中匹配名称
home,拿到home目录的 inode 编号 - 进入 home 目录 :根据 inode 读取
home目录的数据块,遍历内部目录项 - 匹配子目录 alice :找到
alice目录项,获取其 inode 编号,读取对应目录数据块 - 匹配目标文件 note.txt :在
alice的目录项中找到note.txt,拿到该文件的 inode 编号 - 访问文件
问题:访问任何文件,都要从根目录开始进行路径解析吗?
答:原则上是,但是这样太慢,所以Linux会缓存历史路径结构。
问题:Linux目录的概念,是怎么产生的?
答:打开的文件是目录的话,由OS自己在内存中进行路径维护
路径缓存
频繁的路径逐层解析会消耗大量内核资源,因此Linux引入路径缓存 机制:OS在进行路径解析的时候,会把我们历史访问的所有的目录(路径),形成一棵多叉树,进行保存。再次访问相同路径时,直接从缓存读取inode,无需逐层遍历磁盘目录,大幅提升文件访问速度
Linux中,在内核中维护树状路径结构的内核结构体叫做: struct dentry
struct dentry(directory entry,目录项 )是 Linux 内核 VFS 层 定义的纯内存数据结构,专门用于在内存中表示文件名 / 目录名 与 inode 的映射关系。
它是路径缓存(dentry cache) 的最小存储单元,也是路径解析的核心操作对象
内核源码:
c
struct dentry {
atomic_t d_count;
unsigned int d_flags; /* protected by d_lock */
spinlock_t d_lock; /* per dentry lock */
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
/*
* The next three fields are touched by __d_lookup. Place them here
* so they all fit in a cache line.
*/
struct hlist_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct list_head d_lru; /* LRU list */
/*
* d_child and d_rcu can share memory
*/
union {
struct list_head d_child; /* child of parent list */
struct rcu_head d_rcu;
} d_u;
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
unsigned long d_time; /* used by d_revalidate */
struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
void *d_fsdata; /* fs-specific data */
#ifdef CONFIG_PROFILING
struct dcookie_struct *d_cookie; /* cookie, if any */
#endif
int d_mounted;
unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
};
注意:
- 每个文件其实都要有对应的dentry结构,包括普通文件。这样所有被打开的文件,就可以在内存中形成整个树形结构
- 整个树形节点也同时会隶属于LRU(Least Recently Used,最近最少使用)结构中,进行节点淘汰
- 整个树形节点也同时会隶属于Hash,方便快速查找
- 更重要的是,这个树形结构,整体构成了Linux的路径缓存结构,打开访问任何文件,都在先在这棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry结构,缓存新路径

分区挂载
磁盘分区格式化Ext2文件系统后,依然无法直接使用,必须经过挂载(mount)
挂载核心本质:将分区的文件系统,关联到Linux根文件系统的某个目录节点,让该目录成为分区的访问入口。
- 系统所有文件、目录、设备都统一归属到
/开始的唯一树形结构下,不支持多棵独立目录树并存。必须通过挂载,把分散的分区 "接入" 这棵大树。 - 挂载后,访问挂载目录等价于访问对应磁盘分区的所有数据。
- 卸载(umount)则是切断目录与分区的关联,目录恢复原有状态。
挂载点(Mount Point)
挂载点是全局目录树中一个已经存在的目录,有两条硬性规则:
- 目录必须提前创建,不能使用不存在的路径;
- 推荐使用空目录:
- 若目录非空,挂载后原有文件 / 目录会被临时隐藏(并非删除);
- 卸载分区后,原目录内容会自动恢复。
模拟分区挂载:
- 制作一个大的磁盘块,当做一个分区
bash
dd if=/dev/zero of=./disk.img bs=1M count=5
- 格式化写入文件系统
bash
mkfs.ext4 disk.img
- 将分区挂载到指定目录
bash
sudo mount -t ext4 ./disk.img ./dir
- 查看磁盘分区挂载
bash
df -h
- 卸载分区
bash
sudo umount ./dir
结论 :所以,可以根据访问目标文件的"路径前缀"准确判断我在哪一个分区。
文件系统总结
核心设计思想
- 分区块组化:化整为零、分片自治,提升效率、降低碎片、隔离故障;
- inode + 数据块分离:元数据与内容分开存储,统一寻址规则;
- 树形目录 :Linux 全局唯一根目录树,无盘符,依靠挂载接入外部分区;
- 缓存加速:路径缓存 (dentry) 替代重复磁盘 IO,用空间换性能。
完整知识闭环图
bash
物理磁盘(扇区)
↓ 分区
独立分区(MBR/GPT)
↓ 格式化 → 生成Ext文件系统
分区 → 块组 → 超级块/位图/inode表/数据块
↓
inode(元数据+15级指针) ←→ 数据块(内容/目录项/间接块)
↓
磁盘目录项(文件名+inode)
↓ 加载到内存
struct dentry + 路径缓存(加速解析)
↓
路径解析(绝对/相对路径)
↓
文件增删改查、权限控制、软硬链接、挂载卸载



软硬链接
链接是Linux文件系统的特色机制,分为硬链接和软链接,二者底层原理、特性、用途完全不同,其本质依托于前文的inode与文件名映射关系
硬链接
硬链接本质是给同一个inode新增一个文件名,多个文件名共用同一个inode、同一套数据块,没有创建新文件,仅新增目录项记录
核心特性:
- 所有硬链接共享同一个 inode、权限、所有者、时间戳、数据块。修改任意一个链接的文件内容,所有链接同步变化
- 链接计数机制
- 创建硬链接:
i_links_count + 1 - 删除一个硬链接(文件名):仅删除对应目录项,
i_links_count - 1 - 只有当
i_links_count == 0时,内核才会将该 inode 和对应数据块标记为空闲,文件本体真正被删除。
- 不支持跨分区、跨文件系统(inode仅在当前分区唯一)
- 不支持目录硬链接(避免目录环路,造成文件系统混乱)
创建硬链接:
bash
ln 源文件 硬链接名称
示例:

软链接
软链接又称符号链接,是独立的新文件 ,拥有自己的独立inode和数据块。其数据块中不存储真实文件数据,仅存储目标文件的路径
核心特性:
- 软链接拥有独立inode号,与原文件是两个不同文件
- 支持跨分区、跨文件系统、跨主机链接
- 删除原文件,软链接失效,成为无效链接
- 支持对目录创建软链接
- 软链接的文件大小,就是其数据块中存放的路径字符字节数,和原文件大小无关
创建软链接:
bash
ln -s 源文件/源目录 软链接名称
示例:

软硬链接对比
| 对比维度 | 硬链接(Hard Link) | 软链接(Symbolic/Soft Link) |
|---|---|---|
| 核心本质 | 同一 inode 对应多条目录项(纯别名) | 独立特殊文件,数据块存储目标路径(快捷方式) |
| inode 归属 | 与源文件共用同一个 inode | 拥有全新独立 inode |
| 数据块 | 共用源文件数据块,不新增存储块 | 独立数据块,仅存放路径字符串 |
| 链接计数 | 依赖 inode 的 i_links_count(创建 + 1、删除 - 1) |
无链接计数,与源文件计数相互独立 |
| 跨分区 / 跨挂载 | 完全不支持 | 支持(可跨磁盘、跨文件系统) |
| 目录支持(普通用户) | 禁止(会造成目录树环路) | 允许,目录别名场景高频使用 |
| 文件大小 | 和源文件大小完全一致 | 等于路径字符串的字节长度 |
| 权限生效规则 | 共用源文件权限,修改同步生效 | 自身 rwx 权限基本无效,以目标文件权限为准 |
| 源文件删除后 | 链接数>0:链接正常可用;数 = 0 才回收文件本体 | 变为悬空 / 死链接,跳转失败,无法访问内容 |
软硬链接的用途
硬链接:
- 防止重要文件被误删除
- 同一文件多路径访问,避免重复复制
- 文件备份
软链接:
- 简化超长 / 深层路径(路径别名)
- 跨分区 / 跨磁盘 / 外接设备访问