烈火网(LieHuo.Net)教程 Linux 分区以柱面划分,且必须格式化成 Linux 标准文件系统 (ext2/ext3 等) 才能使用。通常来说,每个分区只能格式化为一个文件系统。
尽管硬盘的最小存储单位是扇区,但对于文件系统而言,扇区的读写效率过低,因此以 n 个扇区为一个块 (Block),这是文件系统的最小存储单位,当前支持 1024/2048/4096 三种大小的块。当分区存储大文件时,大的块有助于提高读写效率。以 10MB 文件为例,扇区是 512 字节,需要读取 (I/O) 20480 次,而对于 4096 字节的块而言只需 2560 次。但也正因为块是最小存储单位,对于众多的小文件来说,存储空间浪费也就非常严重。即便文件小于块,其剩余空间也是无法继续使用的。
1. EXT2 文件系统结构
在 EXT2 文件系统中,文件存储分为 Inode 和数据块两部分。inode 中存储了文件元数据(metadata 文件属性)信息和块指针(指向数据块位置),数据块中存储了文件内容数据。整个分区被划分为 n 个块组 (Block Group),每个块组又划分为多个区域。
Super Block: 超级块,记录文件系统信息,包括块和 inode 总量、使用情况等等。
Group Description: 组描述,记录块组信息。
Block Bitmap: 块位图,记录块使用状态,用于分配和回收数据块。
Inode Bitmap: Inode 位图,记录 Inode 使用状态,用于分配和回收 Inode。
Inode Table: Inode 表,存储 Inode。
Data Blocks: 数据块。
可以用 dumpe2fs 查看分区的相关信息
yuhen@yuhen-desktop:~$ sudo dumpe2fs /dev/sda1
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem OS type: Linux
Inode count: 498736
Block count: 1994060
Reserved block count: 99703
Free blocks: 1333369
Free inodes: 381040
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 486
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8176
Inode blocks per group: 511
Filesystem created: Sun Jul 19 14:03:01 2009
Last mount time: Wed Jul 29 11:21:01 2009
Last write time: Wed Jul 29 11:21:01 2009
First inode: 11
Block size: 4096
Inode size: 256
… …
Group 0: (Blocks 0-32767)
Primary superblock at 0, Group descriptors at 1-1
Reserved GDT blocks at 2-487
Block bitmap at 488 (+488), Inode bitmap at 489 (+489)
Inode table at 490-1000 (+490)
1172 free blocks, 8161 free inodes, 2 directories
Free blocks: 19992, 20034-20035, 20037-20043, 31605-31606, 31608-32767
Free inodes: 16-8176
Group 1: (Blocks 32768-65535)
Backup superblock at 32768, Group descriptors at 32769-32769
Reserved GDT blocks at 32770-33255
Block bitmap at 33256 (+488), Inode bitmap at 33257 (+489)
Inode table at 33258-33768 (+490)
20522 free blocks, 4056 free inodes, 175 directories
Free blocks: 33771-33773, 34053-34062, 34107-34136, 34141, …
Free inodes: 11956-11957, 11965, 11984, 11988, 11991, 11998, …
Group 2: (Blocks 65536-98303)
Block bitmap at 65536 (+0), Inode bitmap at 65537 (+1)
Inode table at 65538-66048 (+2)
17487 free blocks, 5021 free inodes, 724 directories
Free blocks: 67305-67307, 67309, 68035, 68043-68044, 70506-70514, …
Free inodes: 19508-24528
#p#副标题#e# 2. Inode 结构
Inode 结构中保存了文件的属性信息和数据块指针。每个 inode 大小为 128 字节。
Mode: 包含 inode 描叙的内容以及用户使用权限。EXT2 中的 inode 可以表示一个文件、目录、符号连接、块设备、字符设备或 FIFO。
Owner Information: 文件或目录所有者(用户/组)标志符。文件系统根据它可以进行正确的存取。
Size: 文件尺寸 (单位: 字节)。
Timestamps: inode 创建及最后一次被修改的时间。
Direct Blocks: 数据块直接指针快,可存储 12 个直接指针,也就是说指向 12 个数据块。
Indirect Blocks: 单级间接指针快,指向一个数据块。假设每个块为 1024B,那么一共可以存储 1024 / 4 = 256 个数据块指针。
Double Indirect: 二级间接指针快。可存储 256 * 256 个数据块指针。
Tripe Indirect: 三级间接之真快。可存储 256 * 256 * 256 个数据块指针。
当 Block = 1024 时,最大文件尺寸 = 1024 * 12 + 1024 * 256 + 1024 * 256 * 256 + 1024 * 256 * 256 * 256 = 16843020 KB (约 16 GB)。
所有的 Inode 都存储在 Inode Table 中,当我们访问一个文件时,将完成如下步骤。
(1) 首先访问文件根目录的 Inode,从根目录的数据块中,我们可以找到该目录下所有文件和子目录的 Inode。
(2) 利用找到的 Inode 从 Inode table 中继续访问下一级目录,直到获取文件的 Inode。
(3) 利用文件的 Inode 我们就可以读取文件数据块的内容了。
目录是一种特殊的文件,它的数据块中存储了该目录中所有文件和目录的名称以及 Inode (见下面的示意图)。从 Inode 数据结构上我们也可以看到,其内部并没有保存文件名的区域。
一个分区所能容纳的文件数量和 Inode 数量有关,因为一个文件最少要占用一个 Inode (也可能是多个,比如硬链接)。当目录下的文件数量过多时,那么就需要多个块来记录关联数据。
3. EXT3 文件系统
操作一个文件时,我们除了在数据块写入数据外,还需更新 Inode 中的相关信息。若在其完成操作前的任何时候出现异常(比如断电)都会导致 Inode 中数据和数据块不一致。如果发生这类问题,EXT2 文件系统会在重启时进行检查,从超级块开始逐步校验,这个过程非常耗时。EXT3 是 EXT2 的升级版本,其代码、磁盘格式和元数据都和 EXT2 相同,这意味着 EXT2 可以无损转化为 EXT3 。
EXT3 是一种日志文件系统,它会在操作文件前记录文件操作日志,在文件读写完成后,完成该日志,这类似于数据库的事务机制。这种日志模式的好处就是在发生错误时,直接检查日志就可获知问题所在。
———- 分割线 ————-
Linux 支持很多种文件系统,本文不作一一描述,可自行参考相关文档。