引言
Linux作为开源的操作系统,其中一个优点是支持各种各样文件系统类型,从远古的FAT到能现今常用的各种日志文件系统。
绝大多数Linux发行版支持ext2、ext3和reiser文件系统,因为它们是原生的Linux文件系统,下面将对虚拟文件系统、日志型文件系统和ext2、ext3、reiser文件系统进行介绍。
虚拟文件系统
虚拟文件系统(Virtual file system, VFS)是用户进程和底层各种文件系统之前的抽象接口。VFS主要提供两方面的功能:
- 提供管理底层文件系统的功能组件(inode、directory entry、page cache等)
- 提供访问底层文件系统的方法(read、write、open等系统调用)
下图说明了VFS与用户进程和底层文件系统之间的交互:
由于VFS的存在,用户进程不需要了解底层具体使用了哪种文件系统,VFS为用户进程访问底层文件系统提供了统一的接口。
日志(Journaling)
非日志型文件系统
对于早先的非日志型文件系统(non-journaling file system),当进行一个写操作时,操作系统首先修改文件系统的元数据(metadata),然后再写入实际用户数据。
如果元数据正在被修改时,发生系统崩溃或机器掉电,文件系统就有可能被损坏。使用fsck工具可检测并修复文件系统损坏的问题,但对于非日志型文件系统,fsck得扫描所有元数据,假如磁盘卷(volume)非常大,那就得花费很长时间进行检测和修复。
因此非日志型文件系统不仅不利于保护数据的完整性,而且在文件系统损害时,也不利于文件系统的恢复。为解决这些问题,日志型文件系统就出现了。
日志型文件系统
相比非日志型文件系统,日志型文件系统(Journaling file system)增加了一个特别的区域:日志区(journal area),作为一个中间层,元数据和实际数据被写入文件系统之前,可先写入日志区:
下面我们来看,日志型文件系统如何利用日志区保护数据完整性,又如何利用日志区快速恢复文件系统。
日志模式(Mode of journaling)
多数日志型文件系统(如ext3、 reiser)支持三种日志方式,分别是回写、顺序、全日志。
回写(writeback)
在回写方式中,元数据被记录到日志区中,实际数据被直接写入主文件系统,该方式能提供较好的性能。
使用回写模式,假如元数据写入日志区后出现系统崩溃,在对文件系统进行恢复后,元数据和部分实际数据被更新,但恢复后的文件可能包含原先旧的垃圾数据。
顺序(ordered)
在顺序方式中,实际数据同样被直接写入主文件系统,而元数据在实际数据写入完成后才写入日志区,顺序模式是日志文件系统默认使用的模式。
假如实际数据写入过程中出现系统崩溃,修复文件系统后,元数据不变,部分实际数据被更新。
全日志(journal)
在全日志方式中,元数据和实际数据均先被写入日志区,然后再写入主文件系统。
该方式提供了很高安全性,不论系统在元数据写入日志区阶段还是实际数据写入日志区阶段发生崩溃,均不影响实际的主文件系统。但该模式为实现安全也付出了效率的代价,因为所有数据都要写入两次。
分析以上三种模式,共同的特点是元数据写入主文件系统之前,都先记录到日志区,这样就保证了主文件系统的元数据不被破坏。另外,进行文件系统恢复时,只需读取日志区中的信息即可进行恢复,而无需遍历整个文件系统。
了解了非日志型文件系统和日志型文件系统的概念,下面我们来看ext2、ext3和reiser这三种具体的文件系统类型。
Ext2
Ext2是一种非日志型文件系统,其结构如下图所示:
一个被格式化为etx2文件系统的磁盘分区,被分成一个引导分区(boot sector)后接多个块组(block group),一个块组又包含以下内容:
超级块(super block): 用于存放文件系统信息,一个文件系统内,每个块组的超级块均包含相同内容
块组描述(block group descriptior): 用于存放块组信息
数据块位图(data block bitmaps): 用于管理空闲数据块
i-node位图(i-node bitmaps): 用于管理空闲i-node
i-node表(i-node tables): 用于存放i-node表,每个文件对应一个i-node表,i-node表用于管理文件的元数据(如uid、gid、ctime、dtime、指向数据块的指针等)
数据块(data blocks): 用于存放实际用户数据
因i-node表与数据块的物理磁盘位置靠的越近,寻道时间(seek time)越短,所以将整个文件系统分成多个小的组块有利于性能的提升。
Ext3
Ext3由ext2演进而来,其组成结构与ext2相似,但添加了对日志功能(journal)的支持。Ext3文件系统有以下特点:
- 可用性(Avalability): ext3文件系统保证连贯一致地写入数据,假如系统突然下电或崩溃,导致文件系统破坏,在进行文件系统修复时,将不必对数据的连贯一致性进行检查,减少了用于系统恢复的时间
- 数据完整性(Data integrity): 使用mount命令挂载磁盘时指定全日志模式(data=journal),可保证元数据和实际用户被完整地写入文件系统
- 写入速度(Speed): 指定data=writeback挂载选项,当写文件操作较多时,可加快数据写入速度
- 可扩展性(Flexibility): 使用tune2fs命令,可直接将ext2升级为ext3,而无需重新格式化磁盘
Ext3最初不是作为日志文件系统而设计,而是在ext2基础上开发,因此它缺少一些其他日志文件系统所具备的特性,性能也较reiserfs、XFS等日志文件系统逊色。
Reiser
reiserFS是从一开始就按照记录日志的意图而开发的日志型文件系统。reiserFS的基础格式建立在单一的B+树上,这使得搜索的效率提高、可伸缩性增强,在处理小文件方面也有较好的性能。
reiserFS因其出色的性能表现,较同期其他文件系统更引人注目,曾一度作为Suse系统安装时默认的文件系统。但由于reiserFS创建者Hans Reiser因故入狱,reiserFS的发展也近于停滞,Novell也于2006年将Suse默认的文件系统由reiserFS更改为ext3。
小结
本文简要描述了Linux文件系统的层次结构,介绍了VFS的作用、日志型文件系统的概念,并对ext2、ext3和reiser这三种文件系统进行了简要说明。
使用日志型文件系统,更多地是在数据完整性与效率两者间作平衡。为保证数据一致完整,需要以降低写入效率为代价;提高了写入效率,文件系统被破坏的几率就变大。
目前尚没有一个“完美”的文件系统,现有的文件系统有各自的限制与不足,业界寄望于btrFS,它是否能如大家所望,取代ext3FS成为主流?我们拭目以待。
Reference: wiki 日志文件系统
Anatomy of Linux journaling file systems