<返回更多

Linux文件系统EXT2,EXT3,ReiserFS详解

2021-03-04    
加入收藏
Linux文件系统EXT2,EXT3,ReiserFS详解

 

1.简介

文件系统是解决如何在存储设备上存储数据的一套方法,包括存储布局、文件命名、空间管理、安全控制等。linux 操作系统支持很多现代的流行文件系统,其中 ext2 、 ext3 和 ReiserFS 最普遍。 ext2 文件系统是伴随着 linux 一起发展起来的,在 ex2 的基础上增加日志就是 ext3 ,这两个文件系统可以很容易的转换而不必重新格式化存储介质,它们是 linux 特有的。 ReiserFS 可以说是后起之秀了,最初它不是用于 linux ,所以对 linux 来说它是一个泊来品。 ReiserFS 采用了一个非常先进的新颖算法,最新的 4 版本真正做到了文件系统操作的原子性(类似数据库事务操作的原子性),据官方报道, ReiserFS" 原子性 " 算法优于现代数据库的 " 原子性 " 算法,做到了空间和时间复杂度的双优!一个文件系统能做到这个份上,我算是彻底服了 :-) 

现代 Linux 系统继续采用了早期( 1992 年前)发展的虚拟文件系统( Virtual File System ,简写为 VFS )理念,VFS 是一个介于用户和实际文件系统之间,为用户提供了一个统一的编程接口,尽管处于其之下的各种文件系统类型千差万别,但对最终用户来说却是一样的。例如当用户张三输入命令 cd /data 后,他并没有意识到自己刚从 ext3 文件系统进入 ReiserFS 文件系统,他仍然使用命令 ls –l 列出当前目录下的所有文件,而且显示格式也是一样,但是幕后英雄 VFS 可忙坏了,它不得不启动一个算法找到 ReiserFS 文件系统提供的接口函数并调用它们,要知道 ReiserFS提供的一套函数可不同于 ext3 的那一套。得益于 VFS ,其他文件系统可以采用 " 热插拔 " 的非常简便的方式加入或退出 Linux 操作系统,例如当第一次 mount 一个文件系统 A 时,相应地就把该文件系统对应的模块装载到内核(假设没有被直接编译进内核),当最后把文件系统 A 对应的设备 umount 时,对应的模块被卸载出去。

 

2.原理

LINUX 的文件系统可以追溯到八十年代末的 Minix 文件系统,而 Minix 文件系统具有几个明显的缺点:文件系统不能超过 64M ,目录只能存放固定数目的文件,文件名长度不能超过 14 个字符,文件尺寸小于 64M 。之后由于继续沿袭传统技术,尽管 linux 的标准文件系统依次经历了 VFS(1992 年前 ) 、 ext(1992 年 ) 、 ext2(1993 年 ) 和最新的ext3 这一系列文件系统的传种接代,但 " 基因 " 没变,只不过新一代都是改进前一代的不足,或者加入一些新东东而已。但由于 Linux 几乎在一开始就引入 VFS 的概念(我个人认为非常英明 ^O^ ), Linux 对其他第三方文件系统都是包容的,目前几乎所有先进的文件系统都支持,其中著名的 ReiserFS 已经成了 Novell 的 SuSe Linux 发行版的缺省文件系统,但也由于 IT 界最臭名昭著的四字经 " 向后兼容 " 的要求,今日各种 linux 发行版中存在过多地包容早已经落伍的文件系统的现象,比如 Minix 、 FAT 等,但对于一个富有理论和经验的系统管理员来说,所有的这些 " 累赘 " 都可以在弹指间一一化解。

下面我们先看看一块物理硬盘是如何分区的。三个主要的参数是柱面数、磁头数和每磁道扇区数,起始编号分别为 0 、 0 和 1 , 0 柱面 0 磁头 1 扇区是主引导分区,上面存放引导代码和四个主分区表(如果一个物理硬盘多于4 个,那么就放在扩展分区), 0 柱面 0 磁头上的其他扇区保留,真正的分区是从 0 柱面 1 磁头 1 扇区开始的。在linux 中,用 /dev/had 、 /dev/hdb 、 /dev/sda 、 /dev/sdc 等表示一个物理磁盘。实验:

 

2.1VFS

自从邓小平南巡讲话那年之前 VFS 投胎于 linux 以来( Mr. Linus 不愧为一个有远见的接生婆, @_@ ), VFS就一直与 Linux 形影不离,并且成了 Kernel 的一部分,在 Kernel 版本号如芝麻开花般节节攀升的同时自己也枝繁叶茂起来。

VFS 就像一个一个默默无闻的公仆,它介于各种文件系统和用户进程之间(参见图〖一〗),一方面屏蔽下层的各种异构文件系统的个性,另一方面为上层用户提供一个统一的接口(如 open 、 read 等),同时 VFS 还提供一些文件系统没有的操作,比如,没有哪个文件系统提供了函数 lseek ,此函数由 VFS 实现。

Kernel 中存在一个全局指针变量 file_systems ,该变量指向一个元素类型为 file_system_type 的链表,当 mount一个文件系统时装载对应的模块,而装载模块时触发的行为 register_filesystem() 会生成一个 file_system_type 结构并把它挂接到 file_systems 链表上,也就是说所有的已经 mount 的文件系统都挂在这个链表上, file_system_tpe 结构中有一个指向超级块结构的指针,存储介质上的超级块在设备 mount 时被读入内存,直到 umount 时从内存中删除。

Linux文件系统EXT2,EXT3,ReiserFS详解

 

图〖一〗 VFS 在内核中的地位

 

2.2EXT2 和 EXT3

EXT2 是 linux 上标准的文件系统, EXT3 是在 EXT2 基础上增加日志形成的,其思想还是可以追溯到早期UNIX 家族发展的基于超级块和 inode 的经典概念。 /dev/sda#n 表示 /dev/sda 硬盘上的第 #n 个分区,如果一个分区备格式化为 ext2 或 ext3 文件系统,那么整个分区的布局如图〖二〗所示:

Linux文件系统EXT2,EXT3,ReiserFS详解

 

图〖二〗: EXT2 文件系统分区结构

分区上的扇区是从 0 开始编号的,每个扇区 512bytes ,一个块( block )大小一般是 1k 、 2k 、 3k 和 4k ,具体大小可在创建文件系统时指定,如果不指定块大小那么会根据分区的大小自动相应选择一个。分区开始的1024bytes 存放引导程序 boot ,接下来的 1024bytes 存放超级块 super block ,组描述字 group descriptors 起始于一个新块,并单独占用一个块空间,之后的所有块被组织成块组,块组才是真正存放文件的场所。超级块含有整个文件系统的一些全局参数,如:卷名、全局唯一标识符、状态、块大小、总块数、每组 inode 数,总 i 节点数、每组块数等等, super block 在文件 mount 时被读入内存,直到 umount 时被释放,由于超级块对于文件系统来说至关重要,所以超级块一般在第 1 、 3 、 5 、 7 和 9 组的首块中存有副本。

实验:

  1. 创建一个 ext2 文件系统: mke2fs –c –c –L "Test Filesystem" /dev/sda2 ;
  2. 查看 ext2 分区开始部分的信息: od –t x1 /dev/sda2 | more ;其中 "aa55" 之前的为 boot ,含有魔数 "ef53"的区域为 super block ;
  3. 查看超级块中的内容: tune2fs –l /dev/sda2 ;例子见附件 1 。
  4. 查看详细的块组信息: dumpe2fs –x /dev/sda2 ;例子见附件 2 。

一个块组描述字占用 32 个字节,其中三个主要指针分别指到 到这个块组的 i 节点表、 i 节点位图和块位图。块组的设计是为了拉近 inode 和它的数据块的距离,这样就可以提高磁盘存取性能,一个块组的具体结构示意图见图〖二〗右边部分 。

inode 是 EXT2 文件系统的精华,一个 inode 对应一个文件, inode 编号是全局性的,从 1 开始,描述参考 图〖三〗。

Linux文件系统EXT2,EXT3,ReiserFS详解

 

inode 中存放文件的一些重要属性,如权限、文件大小、访问时间、修改时间、创建时间、文件属主 ID 、组 ID、块数等。 Inode 包含 15 个指针,前 12 个直接指向数据块,后三个依次是一次间接、二次间接和三次间接指向数据块。

文件系统的目录不同于普通文件的结构,是一种固定格式的文件,里面的每一个条目代表目录中的一个文件,示意图见图〖四〗。

Linux文件系统EXT2,EXT3,ReiserFS详解

 

图〖四〗:目录条目示意图

在 ext2 文件系统上增加一个特殊的 inode (日志文件),用于记录文件系统元数据的变化,即日志 journal ,这就是 EXT3 文件系统。 Ext3 这种粗糙的实现日志的文法付出了很大的代价:写两次!

实验: ext2 和 ext3 文件系统之间的转换(不需要重新格式化)

1). ext2 转换成 ext3 文件系统: tune2fs –j /dev/sda2 ;如果 sda 之前已经 mount ,那么该命令执行完后在顶层目录创建了一个不能删除和 dump 的日志文件 .journal ,机器重启或 umount 且 e2fsck 后该文件将被改变成隐藏的特殊日志文件 inode 。如果 /dev/sda2 是启动时自动 mount 的,那么还需手工修改 /etc/fstab 中/dev/sda2 所对应的文件系统类型,否则还是按 ext2 类型 mount 和使用。

2). ext3 转换成 ext2 文件系统: umount /dev/sda2; tune2fs –O ^has_journal /dev/sda2; e2fsck –y /dev/sda2; mount –t ext2 /dev/sda2 /mnt; 对于自动 mount 的设备还需修改 /etc/fstab 。

 

2.3ReiserFS 3.6

在香港回归那年, Hans Reiser 把他的基于平衡树结构( ReiserFS 3.6 采用 B*tree , B*Tree 查询速度比B+Tree 要快很多, 最近发布的 ReiserFS 4 采用独特的舞蹈树结构)的 ReiserFS 文件系统公布在网上,此后, ReiserFS 文件系统一直在 Hans Reiser 领导的开发小组下开发和发展。 ReiserFS 是一个完全不同于ext2/ext3 的文件系统,日志功能只针对于文件系统的元数据。由于其采用先进的日志机制,且空间复杂度和时间复杂度都优于诸如 ext2 等其他文件系统, 性能直逼高档 unix (如 AIX )上的高级文件系统, 所以 迅速走红(目前得到许多 linux 发行商的支持,而 SuSe linux 干脆直接把它作为缺省安装的文件系统)。ReiserFS 那帮狂热的维护者每一次升级都会为我们带来惊喜,正是这种跨越式的发展使得 ReiserFS 几乎抛弃了那个臭名昭著的 " 向后兼容 " 的理念,每一次的升级都必须重新格式化分区,这成了受他人攻击的唯一理由(我冤枉啊 !_! )。

ReiserFS 是根据面向对象的思想设计的,由语义层( semantic layer) 和存储层( storage layer) 组成。语义层主要是对对象命名空间的管理及对象接口的定义,以确定对象的功能。存储层主要是对磁盘空间的管理。语义层与存储层是通过键( key )联系的。语义层通过对对象名进行解析生成键,存储层通过键找到对象在磁盘上存储空间,键值是全局唯一的。

目前正在使用的是 ReiserFS 3.6 版本,在 32 位机器上最大可支持 2^32-4 个对象,每个对象包含一个对象 ID 和一个键。 ReiserFS3.6 文件系统分区的物理布局是这样的:首先余留 64k (全清 0 ),然后依次是super block (占用 1block )、位图块( 1block )、日志(如果日志和数据同在一个设备上,缺省大小为8193blocks )、根和其他节点区(参考图〖五〗)。缺省块大小是 4k ,开始时树高为 2 , 3.6 版树高不能超过 5 。

 

图〖五〗: ReiserFS 文件系统分区物理布局

B+Tree 的内部节点(占一个磁盘块)定义如下:

Linux文件系统EXT2,EXT3,ReiserFS详解

 

一些小文件( <4KB )直接存放在内部节点中,而大文件存放在叶子节点。

B+Tree 的叶子节点(占若干磁盘块)的结构如下:

Linux文件系统EXT2,EXT3,ReiserFS详解

 

对于具体的定义清阅读源代码,这里不做深入分析。

如果日志放在其他设备上,那么数据设备上就没有日志区,而根块就紧接着位图块存放。假如一块等于4k ,那么超级块放在第 16 块(块编号从 0 开始),位图从第 17 块开始存放,紧接着是根。

ReiserFS 超级块类似于 ext2 的超级块,里面含有整个文件系统的重要参数,如文件系统总块数、空闲块数、根所在的块号、日志起始块和大小、块大小、魔数(缺省日志设备 ReIsEr2Fs ,单独日志设备 ReIsEr3Fs)、文件系统状态、树高、位图所占块数等等。

与 ext3 一样, ReiserFS 也有三种日志模式,即 journal,ordered,writeback 。同时, ReiserFS 引入了两种日志优化方法: copy-on-capture 和 steal-on-capture 。 copy-on-capture: 当一个事务要修改的块在另一个未提交的事务中时,就把这个块复制一份,这样这两个事务就可以并发进行了。 steal-on-capture :当一个块被多个事务修改时,只有最晚提交的那个事务才把这个块实际写入文件系统,其他事务都不写这个块。

最近发布的 ReiserFS 4 更是给人带来了许多令人炫目的创新,比如采用舞蹈树算法进一步把性能推向极致,引入文件系统调用的原子性首次把文件系统操作带入类似于数据库的 ACID ( Atomiccity 、 Consistency、 Isolation 、 Durability )领域(将来可能想破坏文件系统也难 (-: ),在同一时刻既可以把一个对象当作一个文件访问又可以视为一个目录给苛刻的用户带来无限自由,小文件捆绑存储导致近乎 0% 的磁盘碎块,内置磁盘写加密和压缩功能的想法近乎疯狂,漫游( wandering )日志法的运用从此不再 " 写两次 " ,支持无数个 CPU ,支持插件, 通过刷新分配 (allocate-on-flush) 实现磁盘布局动态优化, …… 。

实验:

 

3.特征

3.1特性比较表 

注:Kernel 2.6 开始增加了 ACL 支持,当用 mount 设备时如果加参数 -o acl 则开启相应文件系统的 ACL 支持,例如 mount –t reiserfs –o acl /dev/sda2 /mnt 。在 Linux 系统上能使用 ACLs 是许多 linux 管理员期盼已久的。

3.2 合评价

Ext2 在 linux 上使用已经有很长的历史了,市面上已经出现了 针对 windowsmac OS X 的 ext2 驱动器,允许您直接从这些操作系统中读取和写入 ext2 文件系统,这使它成为了共享设备(如移动硬盘)极好的格式。另外 Ext2还 积累了可观的人气,与 ext3 和 ReiserFS 相比尽管存在更多的不足,但毕竟成了许多 it 人士的习惯,而且正在许多机器上跑着,尽管跑得有点艰难,想让其在短时间内从我们眼中消失是不可能的,这一点还真有点类似 windows 桌面!有人说 ext3 与 ext2 的唯一区别就是前者在后者的基础上增加了日志功能,这话有点偏激。 Ext3 的日志模式有三种,在 mount 时指定, journal 模式日志功能同时作用于数据和元数据,写操作有点令人难以忍受(如果再在其上跑大型数据库,我敢肯定那一定是一个蹩脚的系统管理员干的 ^O^ ), ordered 模式只对文件系统元数据的变化记录日志(数据先写入磁盘,然后元数据写入日志),它只对文件系统的完整性负责,而不顾用户数据,在这种模式下跑数据库效果不错,由数据库负责数据的完整性,双方各司其责,配合完美, writeback 模式不能保证数据先于元数据写入磁盘,因此可能存在元数据已经更新但数据没有更新的情况,传言这是三种模式中最快的。

先进的日志机制、几乎 0% 磁盘碎片、支持海量存储和无限 CPU 轻松管理上亿的文件、 " 光速 " 小文件访问速度,快速的自动修复功能,启动 X Window 比 ext2/3 快 30% 以上, …… ,这就是目前 ReiserFS 3.6 给人留下的深刻影响。刚刚发布的 ReiserFS 4 更是绝, Benchmark 结果几乎是样样领先, ReiserFS 4 加入 kernel 只是时间问题。据ReiserFS 4 追随者感叹,你一旦使用它,想破坏文件系统也难。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>