【存储概念】存储系统中块设备、分区、文件系统的概念及关系
总的来说,这是一个层层抽象的关系:
物理块设备 -> 分区 -> 文件系统
信息保存在两个关键区域
- 分区表: 位于设备的最开始,描述了分区的布局。
- 文件系统元数据: 位于每个分区的开始部分,描述了该分区内的文件和数据。
1. 块设备
- 是什么: 块设备(如硬盘HDD、固态硬盘SSD)是一种以固定大小的“块”(通常为512字节或4K字节)为单位进行读写访问的存储设备。操作系统将其视为一个线性的、连续的块数组。
- 信息存储: 块设备本身除了硬件固件(用于管理物理介质)外,在用户数据区域的开头,并没有“块设备”级别的额外信息。它的身份(如 /dev/sda)是由操作系统内核驱动的。
2. 分区
分区是将一个物理块设备划分为多个逻辑上独立的区域。描述这些分区如何划分的信息,就存储在分区表 中。分区表位于设备上一个非常特殊且固定的位置。
主要有两种主流的分区表格式MBR和GPT。
MBR
- 位置: 占据物理设备的第一个扇区(512字节),这个扇区也被称为主引导记录。
- 结构:
- 引导代码(446字节): 前446字节是启动代码,用于系统引导。
- 分区表(64字节): 紧接着的64字节是分区表。由于只有64字节,它只能定义最多4个主分区。每个分区表项16字节,包含:
- 分区状态(是否可启动)
- 分区类型的起始CHS地址(已过时)
- 分区类型的结束CHS地址(已过时)
- 分区的起始LBA地址(逻辑块地址)
- 分区的大小(扇区数)
- 分区类型(如 0x83 代表 Linux,0x07 代表 NTFS)
- 引导签名(2字节): 最后两个字节是 0x55AA,用于验证MBR的有效性。
扩展分区: 为了突破4个分区的限制,MBR引入了扩展分区的概念。你可以将其中一个主分区标记为扩展分区,然后在扩展分区内创建多个逻辑分区。这形成了一个链式结构,信息存储在扩展分区的各个头部。
- 扩展分区: 为了突破4个分区的限制,MBR引入了扩展分区的概念。你可以将其中一个主分区标记为扩展分区,然后在扩展分区内创建多个逻辑分区。这形成了一个链式结构,信息存储在扩展分区的各个头部。
MBR的局限性:
- 最大支持2TB的磁盘。
- 最多4个主分区(需要扩展分区来突破限制)。
- 分区表没有备份,损坏后难以恢复。
GPT
- 位置: GPT为了兼容MBR,在第一个扇区仍然保留了一个保护性MBR,目的是防止不认识GPT的老旧工具误操作磁盘。
- 实际结构:
- GPT头(第二个扇区): 包含磁盘的GUID、分区表项的位置和数量、备份GPT头的位置,以及CRC32校验和用于数据完整性检查。
- 分区表项数组: 紧跟在GPT头后面,通常占用多个扇区(如128个)。每个分区表项为128字节,可以定义非常多的分区(通常是128个)。每个表项包含:
- 分区类型GUID(如 Microsoft Basic Data)
- 分区自身的GUID
- 分区的起始LBA
- 分区的结束LBA
- 分区属性标志
- 分区名称(UTF-16LE编码)
- 备份分区表 & 备份GPT头: 在磁盘的最后保存了一份完整的分区表和GPT头的副本。这提供了强大的容错能力。
GPT的优势:
- 支持巨大的磁盘容量。
- 分区数量几乎没有限制。
- 具有CRC校验,数据更可靠。
- 有备份,分区信息损坏后可以恢复。
MBR & GPT

3. 文件系统
文件系统创建在分区内部。它负责管理如何将文件(文件名、数据、权限等)存储到分区的块中。它的信息(称为元数据)存储在每个分区的内部。
不同文件系统(如EXT4, NTFS, XFS, FAT32)的元数据布局不同,但核心思想相似。
以最经典的 EXT4 文件系统为例:
- 引导块: 分区的第一个块(可选),用于存放启动代码。
- 超级块: 这是文件系统的“总控制中心”。它包含了关于整个文件系统的关键信息:
- 文件系统的类型(如EXT4)
- 总共有多少inode和数据块
- 空闲的inode和数据块数量
- 块大小(如4KB)
- 挂载时间、最后一次检查时间等
- 为了安全,EXT4在多个块组中对超级块进行了备份。
- 块组描述符表: 描述了文件系统中每个块组 的信息。文件系统被划分为多个块组以便于管理。
- 块位图所在块
- inode位图所在块
- inode表所在块
- 空闲块和inode数量等
- 块位图: 一个块大小的位图,每一位代表一个数据块是否被使用(1=已用,0=空闲)。
- inode位图: 类似块位图,用于管理inode的使用情况。
- inode表: 这是文件系统的核心。inode(索引节点) 是一个数据结构,用于描述一个文件(不包括文件名)。每个文件或目录都有一个inode。inode包含:
- 文件类型(普通文件、目录、符号链接等)
- 文件权限
- 文件的所有者和组ID
- 文件大小
- 时间戳(创建、修改、访问)
- 指向文件数据块的指针(直接指针、间接指针等)
- 数据块: 实际存储文件内容或目录项的地方。
- 目录 在数据块中本质上是一个特殊文件,其内容是一张表,记录了:文件名 -> inode编号 的映射关系。
总结与图示
[ 块设备 (如 /dev/sda) ]
│
├── [ 第一个扇区 ]
│ ├── 如果是MBR: [ 引导代码(446B) | 分区表(64B) | 签名(55AA) ]
│ └── 如果是GPT: [ 保护性MBR ]
│
├── [ 后续扇区 ]
│ ├── 如果是GPT: [ GPT头 | 分区表项数组 ... ]
│ └── ... (其他空间)
│
├── [ 分区1 (如 /dev/sda1) ] <-- 文件系统开始
│ ├── 超级块 (文件系统整体信息)
│ ├── 块组描述符表
│ ├── 块位图 (管理数据块)
│ ├── inode位图 (管理inode)
│ ├── inode表 (存放文件元数据)
│ └── 数据块 (存放文件和目录内容)
│
├── [ 分区2 (如 /dev/sda2) ]
│ └── ... (同样的文件系统结构)
│
└── [ 磁盘末尾 ]└── 如果是GPT: [ 备份分区表 | 备份GPT头 ]
工作流程:
- 系统启动时,固件(BIOS/UEFI)读取块设备第一个扇区的MBR或GPT。
- 找到活动分区(或EFI系统分区)后,加载该分区的引导扇区。
- 操作系统内核被加载,它读取分区表,识别出所有分区。
- 当用户访问一个文件(如 /home/user/file.txt)时:
- 操作系统找到根分区(/),读取其超级块,挂载文件系统。
- 在根目录的数据块中查找 home 目录名,找到对应的inode编号。
- 读取 home 的inode,进入其数据块。
- 在 home 的数据块中查找 user 目录名,找到其inode编号。
- 以此类推,最终找到 file.txt 的inode。
- 通过 file.txt 的inode中记录的数据块指针,读取文件的实际内容。
通过这种分层和索引的结构,操作系统能够高效、可靠地在物理块设备上组织和管理海量数据。
