文件系统和崩溃一致性


VSFS

文件系统:纯软件。VSFS(Very Simple File System)。一个简单的实现如下:

大致磁盘结构:

image-20210830144050545

S:超级块,包含 inode 的数目和数据块数目,inode 表开始位置等等。

i,d:位图,表示占用还是空闲。

I:inode 表。存放文件信息,如是否可以读、写、执行,拥有者,大小、访问时间、磁盘指针…

D:数据区域。

多级索引:文件太大的话磁盘指针不够用,可以用一个磁盘指针指向一个间接块,继续存放磁盘指针。

局部性和快速文件系统

第一个 UNIX 文件系统:

image-20210830150126835

inode 包含指向空闲列表块的头部的指针。

很多东西都是一步步迭代的,刚开始就是勉强能用,性能不是首要关注点,然后再慢慢改进。

碎片问题:

image-20210830150604735

原始块太小,定位开销。

FFS:更改磁盘结构,分组,称为柱面组。在每个组分配文件和目录,每个组有超级块的一个副本。相关文件放在同一个组中。

局部性:大量的文件访问是相同的文件或同一目录的文件。

大文件:一个组放一部分,防止占用过多影响相关文件。

子块:4KB块可能导致磁盘浪费,可以分成更小的子块。子块满了再分配一个子块,缓冲写入(如4KB块缓冲写入,避免子块特殊情况)。

优化磁盘布局:防止读完0刚发请求读1的时候1转跑了。如下图只是一种方案,FFS更智能。

image-20210830153837297

崩溃一致性:FSCK和日志

crash consistency problem

写到一半崩了怎么办?如要写 inode,更新位图,写入数据,崩了可能导致数据不一致。

文件系统检查程序

无法解决的问题:文件系统看起来一致,但是 inode 指向垃圾数据。

fsck 在文件系统挂载并可用之前进行。

全部扫描,检查 inode,位图和磁盘指针,有效,但浪费。

预写日志

带有日志的 ext3 文件系统如下所示:

image-20210830155814752

操作顺序:

  • 日志写入,将事务(事务开始块,要写入的数据和元数据,事务结束块)写入日志。
  • 加检查点:写入元数据和数据更新。

防止日志写入时崩溃可以:等待事务开始和数据、元数据写入了再写事务结束块,或者加上校验和。

批处理日志更新:先修改内存中数据,超时一段时间后写入磁盘时提交事务,避免大量磁盘写入流量。

日志写入可以选择不写入具体的数据,前提是在事务提交之前数据已经写好,也就是 inode 不能指向无效数据。

image-20210830163052434

image-20210830163031262

inode, 位图,数据块。