ext2文件系统

2018-05-26 17:47:44

我们知道,当磁盘被分区后还是不能使用,要经过格式化成相应格式的文件系统才能被操作系统正式使用。

较新的操作系统的文件数据除了文件实际内容外, 通常含有非常多的属性,例如 Linux 操作系统的文件权限(rwx)与文件属性 (拥有者、群组、时间参数等) 。 文件系统通常会将这两部份的数据分别存放在不同 的区块,权限与属性放置到 inode 中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总 量、使用量、剩余量等。这三个数据的意义可以简略说明如下:

superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码;
block:实际记录文件的内容,若文件太大时,会占用多个 block 。

由于每个 inode 与 block 都有编号,而每个文件都会占用一个 inode ,inode 内有文件数据放置的 block 号码。 因此,如果能够找到文件的 inode 的话,那么就会知道这个文件所放置数据的 block 号码, 当然也就能够读出数据了。

我们将 inode 与 block 区块用图解来说明一下,如下图所示,文件系统先格式化出 inode 与 block 的区块,假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内) , 而这个 inode 记录了文件数据的实际放置点为 2, 7, 13, 15 这四个 block 号码,此时我们的操作系统就能够据此来排列磁盘的读取顺序,可以一口气将四个 block 内容读出来! 那么数据的读取就如同下图中的箭头所指定的模样了。

这种数据存取的方法我们称为索引式文件系统 (indexed allocation)。FAT 这种格式的文件系统并没有 inode存在,它使用的是链接式文件系统。每个 block 号码都记录在前一个 block 当中。

如果同一个文件数据写入的 block 分散的太过厉害时,则我们的磁头将无法在磁盘转一圈就读到所有的数据, 因此磁盘就会多转好几圈才能完整的读取到这个文件的内容!常常会听到所谓的磁盘重组吧? 需要磁盘重组的原因就是文件写入的 block 太过于离散了, 此时文件读取的性能将会变的很差所致。 这个时候可以通过磁盘重组将同一个文件所属的 blocks 汇整在一起,这样数据的读取会比较容易! FAT 的文件系统需要三不五时的磁盘重组一下,而Ext2基本不需要。

inode 的内容在记录文件的权限与相关属性,至于 block 区块则是在 记录文件的实际内容。 而且文件系统一开始就将 inode 与 block 规划好了,除非重新格式化 (或者利用 resize2fs 等指令变更文件系统大小) ,否则 inode 与 block 固定后就不再变动。 但是如果仔细考虑一下,如果我的文件系统高达数百GB时, 那么将所有的 inode 与 block 通通放置在一起将是很不智的决定,因为 inode 与 block 的数量太庞大,不容易管理。 因此 Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。Ext2 格式化后有点像下面这样

文件系统最前面有一个开机扇区(boot sector) ,这个开机扇区可以安装开机管理程序, 这是个非常重要的设计,因为如此一来我们就能够将不同的开机管理程序 安装到个别的文件系统最前端,而不用覆盖整颗磁盘唯一的MBR, 这样也才能够制作出多重开机的环境啊!至于每一个区块群组(block group) 的六个主要内容说明如后:

data block(数据区块)
data block 是用来放置文件内容数据地方,在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已。在格式化时 block 的大小就固定了,且每个 block 都有编号,以方便 inode 的记录。 不过要注意的是,由于 block 大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件大小并不相同。 因为 block 大小而产生的 Ext2 文件系统限制如下

block大小 1kb  2kb 4kb
 最大单一文件 16GB 256GB 2TB
 最大文件系统容量 2TB 8TG 16TB

1.原则上,block 的大小与数量在格式化完就不能够再改变了;
2.每个 block 内最多只能够放置一个文件的数据;
3.如果文件大于 block 的大小,则一个文件会占用多个 block 数量;
4.若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)

所以如果一个文件系统把block大小设置为4K,但是却有很多小文件,那么会造成很多的磁盘空间的浪费。但是如果block设置的太小,那么一个大文件就占用了很多的block,这些block都要记录在inode里,会造成不良的读写性能。

inode table
如前所述 inode 的内容在记录文件的属性以及该文件实际数据是放置在哪几号 block 内! 基本上,inode 记录的文件数据至少有下面这些

1.该文件的存取模式(read/write/excute
2.该文件的拥有者与群组(owner/group)
3.该文件的容量
4.该文件创建或状态改变的时间(ctime)
5.最近一次的读取时间(atime)
6.最近修改的时间(mtime)
7.定义文件特性的旗标(flag) ,如 SetUID...
8.该文件真正内容的指向 (pointer)

inode 的数量与大小也是在格式化时就已经固定了,除此之外 inode 还有些什么特色呢?

1.每个 inode 大小均固定为 128 Bytes (新的 ext4 与 xfs 可设置到 256 Bytes)
2.每个文件都仅会占用一个 inode 而已;
3.因此文件系统能够创建的文件数量与 inode 的数量有关;
4.系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与使用者是否符合,若符 合才能够开始实际读取 block 的内容

inode 要记录的数据非常多,但偏偏又只有 128Bytes 而已, 而 inode 记录一个 block 号码要花掉 4Byte ,假设我 一个文件有 400MB 且每个 block 为 4K 时, 那么至少也要十万笔 block 号码的记录呢! inode 哪有这么多可记录的信息?为此我们的系统很聪明的将 inode 记录 block 号码的区域定 义为12个直接,一个间接, 一个双间接与一个三间接记录区

我们以1K block来举例

12个直接指向,可以指向12个block

一个间接指向,指向block(大小为1k), 里面可以存放256个块号码(每个号码占用4B),所以可以指向到256个block。

双间接,同上为256*256

三间接,同上为256*256*256

总共为16G,此时我们知道当文件系统将 block 格式化为 1K 大小时,能够容纳的最大文件为 16GB,比较 一下文件系统限制表的结果可发现是一致的!但这个方法不能用在 2K 及 4K block 大小的计 算中, 因为大于 2K 的 block 将会受到 Ext2 文件系统本身的限制,所以计算的结果会不太符合之故。

如果你的 Linux 依旧使用 Ext2/Ext3/Ext4 文件系统的话,例如CentOS 6.x 系统,那么默认还是使用 Ext4 的文件系统喔! Ext4 文件系统的 inode 容量已经可以扩大到 256Bytes 了,更大的 inode 容量,可以纪录更多的文件系统信息,包括新的 ACL 以及 SELinux 类型等, 当然,可以纪录的单一文件大小达 16TB 且单一文件系统总容量可达1EB

Superblock(超级区块)
Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。他记录的信息主要有

1.block 与 inode 的总量;
2.未使用与已使用的 inode / block 数量;
3.block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128Bytes 或 256Bytes) ;
4.filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间 等文件系统的相关信息;
5.一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1

Superblock 是非常重要的,因为我们这个文件系统的基本信息都写在这里,因此,如果 superblock 死掉了, 你的文件系统可能就需要花费很多时间去挽救啦!一般来说, superblock 的大小为 1024Bytes

此外,每个 block group 都可能含有 superblock 喔!但一个文件系统应该仅有一 个 superblock 而已。事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock , 而若含有 superblock 则该 superblock 主要是做为第一个 block group内 superblock 的备份咯,这样可以进行 superblock 的救援。

Filesystem Description(文件系统描述说明)
这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段 (superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间

block bitmap(区块对照表)
从 block bitmap 当中可以知道哪些 block 是空的,因此我们的系统就能够 很快速的找到可使用的空间来处置文件,如果你删除某些文件时,占用的 block号码就得要释放出来, 此时在 block bitmap 当中相对应到该 block 号码的标志就得要修改成为“未使用中”!

inode bitmap(inode对照表)
记录了使用中和未使用的inode号码。

dumpe2fs 是查询 Ext 家族 superblock 信息的指令,将在linux 命令分类下讲解。


与目录树的关系

每个文件(不管是一般文件还是目录文件)都会占用一个 inode , 且可依据文件内容的大小来分配多个 block 给该文件使用。目录的内容在记录文件名, 一般文件才是实际记录数据内容的地方。 那么目录与文件在文件系统当中是如何记录数据的呢?

目录
当我们在 Linux 下的文件系统创建一个目录时,文件系统会分配一个 inode与至少一块 block 给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode号码数据。也就是说目录所占用的 block 内容在记录如下的信息

inode号码 文件名 
 53565541 a.txt
 53565561 b.txt

可以用ls -i来查看目录或文件占用的inode号码

目录并不只会占用一个 block 而已,在目录下面的文件数如果太多而导致一个 block 无法容纳的下所有的文件名与 inode 对照表时,Linux 会给予该目录多一个 block 来继续记录相关的数据。

当我们要读取某个文件时,就务必会经过目录的 inode 与 block ,然后才能够找到那个待读取文件的 inode 号码, 最终才会读到正确的文件的 block 内的数据。

文件
当我们在 Linux 下的 ext2 创建一个一般文件时, ext2 会分配一个 inode 与相对于该文件大小 的 block 数量给该文件。例如:假设我的一个 block 为 4 KBytes ,而我要创建一个 100 KBytes 的文件,那么 linux 将分配一个 inode 与 25 个 block 来储存该文件! 但同时请注意, 由于 inode 仅有 12 个直接指向,因此还要用到一个间接指向。


数据的不一致
你的文件在写入文件系统时,因为不知名原因导致系统中断(例如突然的停电啊、 系统核 心发生错误啊~等等的怪事发生时) ,所以写入的数据仅有 inode table 及 data block 而已, 最后一个同步更新中介数据的步骤并没有做完,此时就会发生 metadata 的内容与实际数据存放区产生不一致 (Inconsistent) 的情况了,早期的ext2文件系统会在开机的时候通过e2fsck这支程序来检查,整个文件系统,如果文件系统过大,就会很费时。

日志式文件系统ext3/ext4
为了避免文件在写入时发生意外情况使得文件系统不一致情况发生,因此我们的前辈们想到一个方式, 如果在我们的 filesystem 当中规划出一个区块,该区块专门在记录写入或修订文件时的步骤, 那不就可以简化一致性检查的步骤了?也就是说

1. 预备:当系统要写入一个文件时,会先在日志记录区块中纪录某个文件准备要写入的信 息;
2. 实际写入:开始写入文件的权限与数据;开始更新 metadata 的数据;
3. 结束:完成数据与 metadata 的更新后,在日志记录区块当中完成该文件的纪录。

在这样的程序当中,万一数据的纪录过程当中发生了问题,那么我们的系统只要去检查日志记录区块, 就可以知道哪个文件发生了问题,针对该问题来做一致性的检查即可,而不必针对整块 filesystem 去检查, 这样就可以达到快速修复 filesystem 的能力了!这就是日志式文 件最基础的功能。

ext3/ext4 是 ext2 的升级版本,并且可向下相容 ext2 版本呢! 目前我们才建议大家,可以直接使用 ext4 这个 filesystem。dumpe2fs 输出的讯息,可以发现 superblock 里面含有下面这样的信息

Journal inode: 8
Journal backup: inode blocks
Journal features: (none)
Journal size: 32M
Journal length: 8192
Journal sequence: 0x00000001

通过 inode 8 号记录 journal 区块的 block 指向,而且具有 32MB 的容量在处理日志。


总结

本文对ext2文件系统相关知识做了详细的介绍,如果有疑问可以给我留言,如果觉得作者的文章有帮助,可以关注作者。


备注
1.原文地址http://www.freecls.com/a/2712/38

©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。