当前位置: 首页 > ops >正文

linux--------------Ext系列⽂件系统(下)

1.ext2文件系统

引言
ext2(Second Extended File System)是Linux历史上最经典的文件系统之一,其设计思想深刻影响了后续的ext3、ext4等版本。尽管它缺乏日志功能,但其简洁高效的磁盘布局仍值得学习。本文将围绕ext2的Block Group结构目录与文件名的存储路径解析逻辑挂载分区的实现以及路径缓存优化展开详细解析。

1-1 宏观认识

所有的准备⼯作都已经做完,是时候认识下⽂件系统了。我们想要在硬盘上储⽂件,必须先把硬盘格 式化为某种格式的⽂件系统,才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。在 Linux 系统中,最常⻅的是 ext2 系列的⽂件系统。其早期版本为 ext2,后来⼜发展出 ext3 和 ext4。 ext3 和 ext4 虽然对 ext2 进⾏了增强,但是其核⼼设计并没有发⽣变化,我们仍是以较⽼的 ext2 作为 演⽰对象。 ext2⽂件系统将整个分区划分成若⼲个同样⼤⼩的块组 (Block Group),如下图所⽰。只要能管理⼀个 分区就能管理所有分区,也就能管理所有磁盘⽂件。


一、Block Group:ext2的物理组织单元

ext2将存储空间划分为多个Block Group,每个组独立管理自己的元数据和数据块,这种设计既提升了性能(减少磁头移动),又增强了容错能力。

  1. 超级块(Super Block)
    位于每个Block Group的头部(仅部分组备份),记录全局信息:

    • 文件系统大小、块大小(如4KB)

    • Inode总数、空闲块数

    • 最后一次挂载时间等

  2. 组描述符(Group Descriptor)
    存储组内关键结构的偏移地址:

    • 块位图(Block Bitmap)和Inode位图(Inode Bitmap)的位置

    • Inode表(Inode Table)的起始块号

  3. 块位图与Inode位图

    • 块位图:每个比特表示一个数据块是否空闲(1=占用,0=空闲)。

    • Inode位图:同理管理Inode的分配状态。

  4. Inode表

    • 每个Inode(如128字节)对应一个文件/目录,存储元数据:权限、大小、时间戳,以及15个块指针(12个直接、1个间接、1个双间接、1个三间接)。

  5. 数据块(Data Blocks)

    • 存储实际文件内容或目录项列表。


二、目录与文件名的存储机制

目录在ext2中是一个特殊文件,其内容由若干目录项(Dirent)组成,每个目录项结构如下:

plaintext

复制

下载

| Inode号(4B) | 目录项长度(2B) | 文件名长度(1B) | 文件类型(1B) | 文件名(变长) |
  • 可变长度设计:短文件名(如a.txt)占用较小空间,长文件名自动扩展,避免浪费。

  • 线性查找:目录项以链表形式存储,查找文件需遍历(后续ext4改用哈希树优化)。


三、路径解析:从/home/user/file.txt到数据块

当用户访问路径时,文件系统需逐级解析:

  1. 根目录起点:根目录的Inode号固定为2,读取其数据块。

  2. 逐级查找

    • 解析home:在根目录的目录项中找到home的Inode号。

    • 解析user:进入home目录的数据块,查找user的Inode号。

    • 最终定位file.txt的Inode,获取文件内容。

  3. 权限检查:每一级目录需验证执行权限(x位)。


四、挂载分区:连接设备与文件系统树

通过mount命令将分区挂载到目录(如/mnt):

  1. 读取超级块:验证文件系统类型和完整性。

  2. 初始化VFS结构:将设备关联到挂载点,建立super_blockinode内存对象。

  3. 隐藏原内容:挂载后,原目录内容不可见,直到卸载(umount)。


五、路径缓存(dentry缓存):加速访问的关键

为避免重复解析路径,内核维护目录项缓存(dentry cache)

  • 缓存命中:若/home/user已缓存,下次访问/home/user/file.txt时直接跳过已解析部分。

  • LRU淘汰策略:缓存空间不足时,淘汰最久未使用的条目。

二、硬链接(Hard Link):共享inode的“文件分身”
1. 硬链接的原理
  • 直接关联inode:硬链接通过目录项直接指向目标文件的inode号。

  • 引用计数:每个inode中有一个i_links_count字段,记录被硬链接引用的次数。

  • 示例命令

    bash

    复制

    下载

    ln source.txt hardlink.txt  # 创建硬链接
2. 目录结构中的表现
  • 目录项结构:硬链接的目录项与普通文件无异,仅存储文件名和inode号。

    plaintext

    复制

    下载

    | Inode号(与源相同) | 目录项长度 | 文件名长度 | 文件类型 | 文件名(如hardlink.txt) |
  • 删除操作:删除源文件(如source.txt)后,硬链接依然有效(inode引用计数减1)。仅当i_links_count=0时,文件数据才会被释放。

3. 硬链接的限制
  • 无法跨文件系统:inode号仅在同一个文件系统内有效。

  • 无法链接目录:避免目录环问题(仅超级用户可通过ln -d绕过,但风险极高)。


三、软链接(Symbolic Link):存储路径的“快捷方式”
1. 软链接的原理
  • 独立inode与数据块:软链接是一个独立的文件,其数据块中存储目标文件的路径字符串

  • 示例命令

    bash

    复制

    下载

    ln -s source.txt symlink.txt  # 创建软链接
2. 目录结构中的表现
  • 目录项结构:软链接拥有自己的inode,文件类型标记为符号链接

    plaintext

    复制

    下载

    | Inode号(新) | 目录项长度 | 文件名长度 | 文件类型(符号链接) | 文件名(如symlink.txt) |
  • 数据块内容:存储目标路径(如source.txt,长度不超过文件系统块大小)。

3. 软链接的特性
  • 跨文件系统支持:路径解析不依赖inode,可指向其他文件系统的文件。

  • 悬空链接风险:删除源文件后,软链接仍存在但指向无效路径。


三、软硬链接对比:核心差异与使用场景
对比项硬链接软链接
本质共享inode的多个目录项存储目标路径的独立文件
inode占用不创建新inode,共享源文件inode创建新inode和数据块
跨文件系统❌ 不支持✅ 支持
链接目录❌ 默认禁止(防止环路)✅ 支持
删除源文件文件仍可通过硬链接访问链接失效(悬空链接)
存储内容直接指向inode号存储目标文件的路径字符串
性能路径解析快(无需递归)解析慢(需递归查找目标路径)

四、目录结构中的链接示例

假设目录结构如下:

复制

下载

/
├── source.txt          # 源文件(inode=1001)
├── hardlink.txt        # 硬链接(inode=1001)
└── symlink.txt -> source.txt  # 软链接(inode=1002,数据块存储路径"source.txt")
  1. 硬链接的目录项

    • 文件名:hardlink.txt,inode号:1001,文件类型:普通文件。

    • 删除source.txt后,hardlink.txt仍可访问原数据。

  2. 软链接的目录项

    • 文件名:symlink.txt,inode号:1002,文件类型:符号链接。

    • 删除source.txt后,访问symlink.txt会报错:No such file or directory


五、应用场景与最佳实践
  1. 硬链接适用场景

    • 需要多入口访问同一文件(如日志文件的多个硬链接)。

    • 节省inode资源(无额外inode开销)。

  2. 软链接适用场景

    • 跨文件系统引用文件或目录。

    • 动态路径切换(如版本管理中指向latest版本目录)。

    • 避免循环依赖(如/bin/sh软链接到/bin/bash)。


六、ext2文件系统对链接的限制
  1. 硬链接的最大数量

    • 由inode的i_links_count字段位数决定(通常为65535次)。

  2. 软链接路径长度

    • 受限于文件系统块大小(如4KB块最大存储4096字节路径)。

http://www.xdnf.cn/news/5420.html

相关文章:

  • QOwnNotes:功能强大的跨平台笔记应用程序
  • FreeRTOS静态任务的创建、删除和软件定时器的开启(尚硅谷学习笔记)
  • 监控易一体化运维:任务计划管理的关键作用
  • 王道计算机网络知识点总结
  • 动态路由实现原理及前端控制与后端控制的核心差异
  • Linux:43线程封装与互斥lesson31
  • 前端Web开发HTML5+CSS3+移动web(基础-flex)
  • 基于Python的网络电子书阅读系统
  • 在Python中计算函数耗时并超时自动退出
  • 英语听力口语词汇--2.宣传类
  • 【时时三省】(C语言基础)字符数组
  • 关于TIAV20 PLCSIM仿真错误的原因
  • java中的io流
  • 专题一:汉诺塔问题:递归算法的精妙解析
  • PyGame游戏开发(含源码+演示视频+开结题报告+设计文档)
  • 【LwIP源码学习6】UDP部分源码分析
  • [思维模式-28]:《本质思考力》-8- 两种相反的构建与解构系统的思维模式:①自顶向下的分解、牵引;②自底向上的堆叠、聚合
  • 深入剖析 MyBatis 位运算查询:从原理到最佳实践
  • AI文字识别工具汇总
  • 控制LED灯设备
  • Linux epoll 详解:概念、使用、数据结构、流程及应用
  • C++:友元
  • CSS 基础知识分享:从入门到注意事项
  • 50.辐射抗扰RS和传导抗扰CS测试环境和干扰特征分析
  • Vue:生命周期钩子
  • 海上风电场数字孪生,可视化智慧运维
  • 20242817李臻《Linux⾼级编程实践》第9周
  • 鸿蒙开发RelativeContainer自适应高度
  • HTTP3详解
  • MySQL为什么选择B+树