QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 17374|回复: 74

请问,reserfs与ext3相比哪个优胜?

[复制链接]
发表于 2003-3-15 21:33:42 | 显示全部楼层 |阅读模式
各位使用者,说说你们的体会吧!!


我以前用过reserfs,但在kde中,kde的程序老是会无缘无故地崩溃。ext3就没有这个问题。但对于其他方面我就不甚清楚了。

印象中好像好像是reserfs的速度比较快。
发表于 2003-3-15 21:58:33 | 显示全部楼层
个人感觉前者强少少。
回复

使用道具 举报

发表于 2003-3-15 22:25:05 | 显示全部楼层
reiserfs比ext3好,
当然ext3兼容ext2,reiserfs就不行
回复

使用道具 举报

发表于 2003-3-15 22:57:20 | 显示全部楼层
所指的兼容性是什么呢?不能共存?
回复

使用道具 举报

发表于 2003-3-15 23:09:10 | 显示全部楼层
reiserfs应该好些,特别是对linux beginners来说,我感觉更合适。呵呵,用reiserfs你可以直接用手按power来关机都没有什么问题,但ext2/3遇到这种情况的时候不太行了。还有。
回复

使用道具 举报

发表于 2003-3-15 23:12:08 | 显示全部楼层
我来转一篇有关ReiserFS的文章。
[code:1]
RedHat环境下使用日志式文件系统ReiserFS
摘要:

ReiserFS是公认为效能与安全性都优于Linux采用多年的ext2档案系统﹐ReiserFS的最大优点是安全性大幅提升﹐系统当机不易造成文件的损坏。Kernel 2.4.1起已经正式将其列入标准﹐但是为数众多的 Linux 系统仍旧在使用ext2。本文将讨论在Redhat环境下为什么要使用日志式的档案系统,如何取得 ReiserFS ,Kernel 2.2 与 2.4 如何支持ReiserFS,如何产生新的档案统。RedHat 7.0 的使用者特别注意事项及相关网络资源。

日志式文件系统简介
尽管Linux可以支持种类繁多的文件系统,但是几乎所有的Linux发行版都用ext2作为默认的文件系统。ext2的设计者主要考虑的是文件系统性能方面的问题。ext2在写入文件内容的同时并没有同时写入文件的meta-data(和文件有关的信息,例如:权限、所有者以及创建和访问时间)。换句话说,Linux先写入文件的内容,然后等到有空的时候才写入文件的meta-data。这样若出现写入文件内容之后但在写入文件的meta-data之前系统突然断电,就可能造成在文件系统就会处于不一致的状态。在一个有大量文件操作的系统中出现这种情况会导致很严重的后果。因此就导致了新的日志式文件系统的出现以解决这个问题。日志文件系统比传统的文件系统安全,因为它用独立的日志文件跟踪磁盘内容的变化。就像关系型数据库(RDBMS),日志文件系统可以用事务处理的方式,提交或撤消文件系统的变化。Linux系统缺少日志式文件系统是限制推广其在企业级应用的一个重要制约因素。因此就出现了多种不同的日志式文件系统,当前linux环境下有下面几种日志文件可供选择:

* SGI的xfs(http://oss.sgi.com/projects/xfs/)日志文件系统,SGI的xfs是基于Irix(SGI的Unix)上已经实现的xfs。SGI已经宣布xfs为Open Source的软件。
* Veritas(www.veritas.com)的文件系统和卷管理(volume manager)。
* Reiserfs:Reiserfs应用了一些新的技术,例如,统一名字空间(unified name space)有一些Linux的发行版已经包括了reiserfs文件系统,作为安装时的可选项。SuSE 6.4 就很容易使用reiserfs文件系统。reiserfs的最新版是ReiserFS 3.6.25,经过测试reiserfs的基准测试的结果是非常令人满意的。
* IBM的jfs。这两文件系统都遵循开放源码版权声明,且的而且很多有天赋的人在开发这两个文件系统。jfs(Journaled File System Technology for Linux)的开发者包括AIX(IBM的Unix)的jfs的主要开发者。在AIX上,jfs已经经受住了考验。它是可靠、快速和容易使用的。
* 日志文件系统的另一个选择是ext2的后继者ext3fs文件系统。ext3fs文件系统正在Linux内核黑客Stephen Tweedie的领导下开发。ext3fs还处于beta测试阶段,就像reiserfs和jfs,但是它工作得很好。Stephen预计2000年夏天可以正式发布ext3fs。ext3fs最大的优点是向下兼容ext2。而且ext3fs还支持异步的日志,这意味着它的性能可能还比ext2好。
在上面提到的日志式文件系统中,ReiserFS是目前Linux环境下最成熟的一种。而IBM的JFS和SGI的XFS则相对于来说要年轻一些,ext3文件系统则仍然需要开发。因此我们这里选择ReiserFS。

为什么叫日志式?

日志式文件系统在强调数据完整性的企业级服务器中有着重要的需求,是文件系统发展的方向。日志式文件系统的思想来自于如Oracle等大型数据库。数据库操作往往是由多个相关的、相互依赖的子操作组成,任何一个子操作的失败都意味着整个操作的无效性,对数据库数据的任何修改都要回复到操作以前的状态。日志式文件系统采用了类似的技术。

在分区中保存有一个日志记录文件,文件系统写操作首先是对记录文件进行操作,若整个写操作由于某种原因(如系统掉电)而中断,则在下次系统启动时就会读日志记录文件的内容来恢复没有完成的写操作。而这个过程一般只需要几秒钟到几分钟,而不是ext2文件系统的fsck那样在大型服务器情况下可能需要几个小时来完成扫描。

对日志式文件系统原理的一个更详细的描述可以参考Journal File Systems

获得ReiserFS

Kernel 2.4.1已经包含了ReiserFS的代码,但是最好使用包含了最新的ReiserFS 3.6.25的kernel 2.4.3,若你不是使用kernel 2.4.3,建议你使用这个版本的ReiserFS。本文将使用kernel 2.4.3来作为示例。

对于Kernel 2.4.2则需要打补丁:

# cd /usr/src/linux
# zcat linux-2.4.2-reiserfs-20010327.patch.gz | patch -p1


对于2.2版本的内核:

# bzip2 -dc linux-2.2.18-reiserfs-3.5.32-patch.bz2 | patch -p1

在make config阶段需要对"prompt for development and/or incomplete code/drivers"回答Yes。否则系统就不会询问关于ReiserFS的选项;在编译内核的文件系统参数部分,应该选择支持ReiserFS。若你不希望将root(/)安装在ReiserFS文件系统下,则只需要将对ReiserFS的支持编译为模块即可。本文将讨论将root安装在ReiserFS之上的情况。

编译内核和模块

注:如果你使用的是RedHat7.0,那么就需要首先边际Makefile并将其中所有的gcc替换为kgcc。首先需要从redhat7.0安装光盘上安装kgcc,若没有采取这一步,那么得到的内核将会显示kernel panics信息。Redhat7.0带的gcc2.96有很多的bug。所有的内核编译都应该使用kgcc来完成。
gcc vs. kgcc:

Linux 之父 Linus Torvalds 日前在 Linux核心邮件论坛中,表明了他对 Red Hat 7.0 的看法:『基本上不堪使用』。 节录这封信的内容重点: 『坦白地说,任何使用 Red Hat 7.0 和他们那坏掉的编译器都会遇到麻烦。』『我不知道为何 Red Hat 选择释出那愚蠢的 gcc-2.96(一定通过没有任何 gcc 技术人员的批准 - gcc 人员对此也很生气),而且更令我惊讶的是他们显然已经知道他们用的这个编译器是坏的。他们包进了另一个好的编译器,叫它作 kgcc。』 『kgcc 意思是核心 gcc,显然因为 (a) 他们了解到核心编译错误比某些应用程序编译错误来得糟糕,和 (b)...』『... 我认为 Red Hat 7.0 基本上并非一个可用的开发平台,而且我希望 Red Hat 将他们的编译器降级...』 Red Hat 执行长 Matthew Szulik 对 Linus Torvalds 这番话的反应是:他不是真正能回应 Linus 这项挑战的人选,而且他表示 Red Hat 也预料到会遭受这样的谴责。 Red Hat 7.0 备受争议的关键在于其中包含了 gcc 发展分支中的一个非正式的版本 gcc 2.96,gcc 小组曾表示『gcc 2.96 并非 gcc 正式版本』、『而且将来也不会有这个版本』,它只是在到达 gcc 3.0 路上的一站。 Red Hat 技术长 Michael Tiemann 最近曾为 Red Hat 7.0 使用 gcc 2.96 的决定作出辩护,他表示:『没有技术上更好的决策』、『因为其他的选择不会比较好 - 对 Red Hat 系列这样复杂的需求而言 - 比起走回头路,这项决定还能推动 gcc 3.0 的发展。』 Tiemann 还说,若批评者的矛头想要找个目标,对使用 gcc 2.96 的决定『你也可以怪我』。)


下面我们将编译ReiserFS工具,相应的代码是存放在/usr/src/linux/fs/reiserfs/utils目录中的,首先make编译程序,然后再make install来安装程序。2.4内核中并没有包括这些工具,而需要另外下载。从这里可以下载。

解压文件:

# tar zxvf reiserfsprogs-3.x.0j.tar.gz
# cd reiserfsprogs-3.x.0j
# ./configure
# make
# make install

不幸的是,并没有ext2toreiserfs之类的转换工具,因此将/从ext2转换为reiserfs就需要三步才能完成:

1.创建一个新的分区,并格式化为ReiserFS格式。
2.将数据从ext2分区拷贝到新分区。
3.将新分区加载为根(/)

创建新分区,ReiserFS并不需要一个特定的分区类型,因此就使用83(Linux):

# fdisk -l /dev/hda
/dev/hda9 2872 3126 2048256 83 Linux
/dev/hda10 3127 3381 2048256 83 Linux

在新分区上创建ReiserFS文件系统:

# mkreiserfs /dev/hda10

加载新的分区:

# mount -t reiserfs /dev/hda10 /mnt/hda10

拷贝数据到新分区:

# cd /mnt/hda10
# tar cvlf - / | tar xf -

编辑fstab来指向新的root:

/dev/hda10 / reiserfs defaults 1 1

创建指向reiserfsck的一个符号链接因为RedHat启动时将寻找fsck.reiserfs文件来扫描:

# ln -s /sbin/reiserfsck /sbin/fsck.reiserfs

保证系统lilo至少为21.6。这是第一个支持ReiserFS的版本,也可以在/boot目录中使用小容量的ext2文件系统。但是升级lilo更好一些。也推荐使用GRUB来实现引导。

当在lilo.conf中使用新的内核时需要运行lilo程序。其中lilo.conf中需要将root指向新的内核所在分区。

重新启动系统,新系统的root将在ReiserFS文件系统上。上面的示例讨论的是如何在root中使用ReiserFS,而根据需要你可以选择在任何目录中使用ReiserFS。

资源

ReiserFS home http://www.reiserfs.org/

ReiserFS FAQ http://www.reiserfs.org/faq.html

LinuxGazette article on journal filesystems http://www.linuxgazette.com/issue55/florido.html

XFS by SGI http://oss.sgi.com/projects/xfs/

IBM's JFS http://oss.software.ibm.com/developerworks/opensource/jfs/

Ext3 beta testing program on redhat.com
http://beta.redhat.com/index.php?program=Display_Page&action=ext3

Other articles by Mayank Sarup http://www.freeos.com/author/?authorName=Mayank%20Sarup
[/code:1]
回复

使用道具 举报

发表于 2003-3-15 23:17:32 | 显示全部楼层
呵呵,还有一篇。
[code:1]
实战ReiserFS文件系统
内容:
ReiserFS的特点(与ext2的对比)
ReiserFS的缺点
ReiserFS的起源与未来
安装
作者简介

汤海京 ([email protected])
联想集团有限公司软件事业部工程师
2001 年 8 月

    ReiserFS文件系统是一种新的linux文件系统。它通过一种与众不同的方式--完全平衡树结构来容纳数据,包括文件数据,文件名以及日志支持,并能在上面继续保持很快的搜索速度和很高的效率。ReiserFS文件系统一直以来被用在高端Unix系统上如,SGI。

ReiserFS的特点(与ext2的对比):
ReiserFS相对于Linux上传统的文件系统--ext2有很多优点,在下面我将一一向大家介绍。

搜寻方式
ReiserFS是基于平衡树的文件系统结构,尤其对于大量文件的巨型文件系统,如服务器上的文件系统,搜索速度要比ext2快;ext2使用局部的二分查找法,综合性能比不上ReiserFS。

空间分配和利用情况
  ReiserFS里的目录是完全动态分配的,因此不存在ext2中常见的无法回收巨型目录占用的磁盘空间的情况。ReiserFS里小文件(<4K)可以直接存储进树,小文件读取和写入的速度更快,树内节点是按字节对齐的,小的文件可共享同一个硬盘块,节约大量空间。Ext2使用固定大小的块分配策略,也就是说,不到4K的小文件也要占据4K的空间,导致的空间浪费比较严重。

先进的日志机制
  ReiserFS有先进的日志(Journaling/logging)机制,在系统意外崩溃的时候,未完成的文件操作不会影响到整个文件系统结构的完整性。 ext2虽然健壮性很强,但一旦文件系统被不正常地断开,在下一次启动时它将不得不进行漫长的检查系统数据结构的完整性的过程,这是为了防止数据丢失而必需的操作。对于较大型的服务器文件系统,这种"文件系统检查"可能要持续好几个小时,在很多场合下这样长的时间是无法接受的。解决这个问题的一种技术"日志文件系统"。在日志的帮助下,每个对数据结构的改变都被记录下来,日志在机制保证了在每个实际数据修改之前,相应的日志已经写入硬盘。正因为如此,在系统突然崩溃时,在下次启动几秒钟后就能恢复成一个完整的系统,系统也就能很快的使用了。

支持海量磁盘和优秀的综合性能
  ReiserFS是一个相当现代化的文件系统,相比之下,ext2虽然性能已经很好了,但其设计还只是20世纪80年代的水准。ReiserFS的出现,使Linux拥有了像Irix/AIX那样的高档商用Unix才有的高级文件系统。ReiserFS可轻松管理上百G的文件系统,在企业级应用中有其用武之地,由于它的高效存储和快速小文件I/O特点,它在桌面系统上也表现出色:启动X窗口系统的时间ReiserFS比ext2少1/3。而ext2则无法管理2G以上的单个文件,这也使得ReiserFS在某些大型企业级应用中比ext2要出色。

ReiserFS的缺点
  ReiserFS一个最受人批评的缺点是每升级一个版本,都将要将磁盘重新格式化一次,这个缺点也正在改进中。

ReiserFS的起源与未来
在1997年7月23日,Hans Reiser把他的基于平衡树结构的ReiserFS文件系统在网上公布 。这是ReiserFS的第一次公开亮相。此后,ReiserFS一直在Hans Reiser和领导下的开发小组下开发和发展,SuSE Linux也对它的发展起了重大的帮助。由于ReiserFS有一些很有用的特性,更主要的是它比ext2fs要快得多,所以它很快被很多人使用。据说在Linux内核2.4.0以上的版本可能将采用ReiserFS作为它的文件系统。当前的ReiserFS只能在Intel结构体系上使用,但支持其他体系结构的ReiserFS版本也正在积极开发中。我们等待着更强大,兼容性更好的ReiseFS的到来。

怎样添加ReiserFS文件系统

安装
从http://www.namesys.com/下载reiserfs的补丁程序,要确保下载的补丁版本和你的kernel版本是一致的。

下载后用root身份登录进入系统,切换至/usr/src/linux目录,执行命令:
#gunzip /path/to/linux-2.2.16-reiserfs-3.5.22-patch.gz
#patch -p1 -i /path/to/linux-2.2.16-reiserfs-3.5.22-patch
在做完上面的两步后,重新编译kernel,将reiserfs编译进kernel或做成一个模块。

Reiserfs的相关应用程序在 /usr/src/linux/fs/reiserfs/utils 目录下。你可以用下面方法安装它们:
#mkdir bin
#make
#make install

最后,你可以用"fdisk"命令重新分区或用"mkreiserfs"命令重新格式化一个已经存在的分区。指定reiserfs类型加载这个分区,如"mount -t reiserfs /dev/hda2 /download",这样你就可以使用这个新的分区了。




作者简介

汤海京,联想集团有限公司软件事业部工程师。上大学之后,一直钻研Linux底层技术,闭门造车,企图开发"中国人自己的操作系统",毕业设计做的也是相关课题(OSKit)。后转向Linux上的应用开发。喜欢把学习Linux的感受和技经验写下来,在网上发布出去,算是为自由软件贡献一份微薄之力,也是对以前那段痴心妄想的时光的反省。同时还帮助维护蓝森林(http://lslnet.com/linux),为Linux爱好者服务。您可以通过电子邮件[email protected] 与他联系。
[/code:1]
回复

使用道具 举报

发表于 2003-3-15 23:20:10 | 显示全部楼层
[code:1]高级文件系统实现者指南 英文原文
内容:
准备好的内容
理解日志:元数据
理解日志:fsck
fsck 的问题
日志
运作中的日志
ReiserFS
小文件的性能
ReiserFS 技术
参考资料
关于作者
对本文的评价
相关内容:
JFS 基础教程
更多的 Linux 参考资料
日志和 ReiserFS

Daniel Robbins ([email protected])
总裁/CEO,Gentoo Technologies, Inc
2001 年 6 月

    伴随着 Linux 2.4 版本的发行,出现了大量的文件系统可能性,其中包括 ReiserFS、XFS、GFS 和其它文件系统。这些文件系统听起来的确都很酷,但是它们真正能做些什么呢,擅长在哪些方面,以及在 Linux 产品环境下如何才能安全地使用它们呢?在高级文件系统实现者指南中,Daniel Robbins 通过向您展示如何在 Linux 2.4 的环境下建立这些新的高级文件系统来回答以上的问题。遵从这个方法,他提供了在实际实现过程中的有价值的建议,性能信息和重要的技术性注意要点,以便于您在新的文件系统中能有令人愉快的经历。在这里,也就是这个系列的第一篇文章中,他解说了日志和 ReiserFS 的优点。

准备好的内容
这一系列文章的目的是向您详实地介绍 Linux 的各种新的文件系统,包括 ReiserFS、XFS、JFS、GFS、ext3 和其它的文件系统。我要让您知道一些必要的实用知识,有了这些知识您才能开始使用这些文件系统。我的目标是帮助您尽可能地避免潜在的隐患;这就是说,我们将仔细地了解一下文件系统的稳定性、性能问题(或好或差)、您应该知道的任何的负面应用程序交互作用、内核与补丁的最佳搭配以及更多内容。您可以把这一系列的文章看成是这些下一代文件系统的“内幕指南”。

这就是准备好的内容。但是要开始这一系列工作,我还有一篇文章要脱离这个主题,用来为接下来的行程做准备。我将会涉及两个对于 Linux 开发社区非常重要的主题 — 日志和 ReiserFS 后的设计理念。日志是非常重要的,因为它是我们长期以来一直期待的技术,而现在终于出现了。在 ReiserFS、XFS、JFS、ext3 和 GFS 中都用到它。确切地理解日志是做什么的和为什么 Linux 需要它是非常重要的。即使您对日志已有所掌握,我还是希望我有关日志的介绍可以成为一个好的模型,以用来向其他人解释这项技术,或者作为一项惯例,以利于全世界的部门和组织开始向这些新的日志文件系统进行转变。这个过程通常是由“Linux guy/gal”开始的,就像您自己也会说服其他人应该这么做。

在这篇文章的后半部分,我们将看看 ReiserFS 后的设计理念。通过这么做,我们能够很好地掌握一个事实,那就是这些新的文件系统并不只是为了做同样的事比老的系统快一点。它们还允许我们用以前完全不可能的方法来处理事情。开发人员在阅读这一系列文章时应该牢记这一点。这些新的文件系统的能力 将很可能对您今后的 Linux 软件开发工程的代码编写产生影响。

理解日志:元数据
正如您所了解的那样,文件系统的存在允许您储存、检索和操作数据。为了实现这一目的,文件系统需要保持一个内在的数据结构使得您的数据有组织并且便于访问。这一内部的数据结构(确切地说就是“关于数据的数据”)被称为 元数据。就是这个元数据的结构为文件系统提供了其特定的身份和性能特征。

通常,我们并不直接和文件系统的元数据打交道。而是一个特别的 Linux 文件系统驱动程序为我们作相应的工作。Linux 文件系统驱动程序是专门用来操作复杂的元数据的。然而,为了使得文件系统驱动程序正常工作,有一个很重要的必要条件;它需要在某种合理的、一致的和没有干扰的状态下找到元数据。否则,文件系统驱动程序就不能理解和操作元数据,那么您也就不能存取文件了。

理解日志:fsck
这就引出了 fsck。当 Linux 系统启动时,fsck 启动并扫描系统的 /etc/fstab 文件中列出的所有本地文件系统。fsck 的工作就是确保要装载的文件系统的元数据是处于可使用的状态。大多数的时候是可使用的。当 Linux 关闭时,它仔细地把所有的缓冲区数据转送到磁盘,并确保文件系统被彻底卸载,以保证系统再次启动时能够使用。典型的就是,fsck 扫描那些将被装载的文件系统,确定它们已被彻底卸载,并做出合理的假设 — 所有的元数据都没有问题。

然而,我们都知道不时地会有一些意外发生,例如意想不到的电源故障或者系统挂起。当出现这些不幸的情况时,Linux 没有机会彻底卸载文件系统。当系统重新启动,fsck 开始扫描时,它会检测到这些没有彻底卸载的文件系统,并做出合理的假设 — 文件系统可能没有为 Linux 文件系统驱动程序准备好。这就很有可能导致元数据在某种情况下陷入困境。

所以,为了弥补这种情况,fsck 将开始彻底的扫描并且全面地检查元数据,修正这一过程中找到的任何错误。一旦 fsck 完成这样的工作,文件系统就可以使用了。尽管意想不到的电源故障或者系统挂起可能造成最近修改的数据丢失,但是由于元数据现在是一致的,文件系统就可以被装载和投入使用了。

fsck 的问题
迄今为止,为确保文件系统的一致性,这种方法可能听起来并不是个坏主意,但是却不是最佳的解决方案。问题出自于这样一个事实 — fsck 必须扫描文件系统全部的元数据,以确保文件系统的一致性。对所有的元数据做彻底的一致性检查是一项极为费时的工作。通常至少要花上好几分钟才能完成。更糟糕的是,文件系统越大,完成这个彻底的扫描所花费的时间就 越长。这就是个大问题,因为当 fsck 做它自己事情的时候,您的 Linux 系统实际上就是被切断的,并且如果您有一个庞大数量的文件系统存储,您的系统可能就会花上半个小时或者更长的时间来执行 fsck。当然,在任务紧要的数据中心的环境里,也就是在系统正常运行极为重要的环境下,标准的 fsck 工作可能会造成破坏性的结果。幸运的是,有更好的解决方案。

日志
日志文件系统通过增加一个叫做日志的新的数据结构来解决这个 fsck 问题。这个日志是位于磁盘上的结构。在对元数据做任何改变以前,文件系统驱动程序会向日志中写入一个条目,这个条目描述了它将要做些什么。然后,它继续并修改元数据。通过这种方法,日志文件系统就拥有了近期元数据被修改的历史记录,当检查到没有彻底卸载的文件系统的一致性问题时,这个记录就唾手可得了。

可以这样来看待日志文件系统 — 除了存储数据(您的素材)和元数据(关于素材的数据)以外,它们还有一个日志。您可以称它们为元元数据(关于素材数据的数据)。

运作中的日志
那么,fsck 如何处理日志文件系统呢?实际上,通常它什么都不做。它只是忽略文件系统并允许它被装载。在快速地恢复文件系统到达一致性状态的背后,真正起作用的在于 Linux 文件系统驱动程序中。当文件系统被装载时,Linux 文件系统驱动程序查看文件系统是否完好。如果由于某些原因出了问题,那么就需要对元数据进行修复,但不是执行对元数据的彻底扫描(就像 fsck 那样),而是查看日志。由于日志中包含了按时间顺序排列的近期的元数据修改记录,它就简单地查看 最近被修改的那部分元数据。因而,它能够在几秒钟时间内将文件系统恢复到一致性状态。并且与 fsck 所采用的传统方法不同,这个日志重放过程在大型的文件系统上并不需要花更多的时间。多亏了日志,数百 G 的文件系统元数据几乎能在瞬间恢复到一致性的状态。

ReiserFS
现在,我们来谈一谈 ReiserFS,它是我们将要研究的几个日志文件系统中的第一个。ReiserFS 3.6.x(作为 Linux 2.4 一部分的版本)是由 Hans Reiser 和他的在 Namesys 的开发组共同开发设计的。Hans 和他的组员们相信最好的文件系统是那些能够有助于创建独立的共享环境或者命名空间的文件系统,应用程序可以在其中更直接、有效和有力地相互作用。为了实现这一目标,文件系统就应该满足其使用者对性能和功能方面的需要。那样,使用者就能够继续直接地使用文件系统,而不必建造运行在文件系统之上(如数据库之类)的特殊目的层。

小文件的性能
那么,如何能使文件系统更加适应环境呢?Namesys 已经决定着眼于文件系统的一个方面,至少最初是 — 小文件的性能。通常,像 ext2 和 ufs 这样的文件系统在这一方面做的并不是很好,经常迫使开发人员转向数据库或者特别组织的处理来获取他们所需要的某种性能。随着时间的推移,这种“围绕问题进行编码”的方法怂恿了代码的膨胀和许多不兼容的特殊目的 API,这并不是好事情。

这儿有一个 ext2 如何鼓励这种编程的例子。ext2 很擅长存储大量大小在 20k 以上的文件,但是对于存储 2,000 个 50 字节的文件来说,它就不是一种很理想的技术了。当 ext2 必须处理非常小的文件时,不只是性能显著地下降,而且存储效率也同样下降,因为 ext2 是按 1k 或者 4k 的块来分配空间的(可在文件系统创建时设定)。

现在,常规的明智做法会提示您不应该在文件系统上储存这么多小的文件。而是应该存储在某种运行在文件系统之上的数据库里。作为对这种说法的回应,Hans Reiser 指出无论何时您需要在文件系统的顶上建立一层,那就意味着文件系统不满足您的需要。如果文件系统满足您的需要,那么您首先就要避免使用特殊目的的解决方案。这样就可以节省开发的时间,并消除代码膨胀。这些代码可能是在您手动处理自己的个人存储器或者缓冲机制时,或者与数据库的某个库交互作用过程时所产生的。

理论上是这样。但是在实际运用中,ReiserFS 的小文件性能会是如何的好呢?好得让人吃惊。实际上,当处理小于 1k 的文件时,ReiserFS 大概要比 ext2 快 8 到 15 倍!更妙的是,这些性能提高并不以其它文件类型的性能损失为代价。通常,ReiserFS 几乎在各个方面都优于 ext2,但是在处理小文件时才真正体现出了其闪光点。

ReiserFS 技术
那么 ReiserFS 是怎样提供如此出色的小文件性能的呢?ReiserFS 使用了特殊的优化 b* 平衡树(每个文件系统一个)来组织所有的文件系统数据。这为其自身提供了非常不错的性能改进,也能够减轻文件系统设计上的人为约束。例如,现在一个目录下可以容纳 100,000 个子目录。另一个使用 b* 树的好处就是 ReiserFS 能够像大多其它的下一代文件系统一样,根据需要动态地分配索引节,而不必在文件系统创建时建立固定的索引节。这有助于文件系统更灵活地适应其面临的各种存储需要,同时提供附加的空间有效率。

ReiserFS 有许多特征是特别针对提高小文件的性能的。和 ext2 不同,ReiserFS 并不固定地以 1k 或者 4k 的块分配存储空间,而是分配所需要的精确尺寸。而且 ReiserFS 也包括了以尾文件为中心的特殊优化 — 尾文件是指那些比文件系统块小的文件及文件结尾部分。为了提高性能,ReiserFS 能够在 b* 树的叶子节点存储文件,而不是把数据存储在磁盘的其它地方再指向它。

这做了两件事。第一,它显著地提高了小文件的性能。由于文件数据和 stat_data(索引节)信息是紧挨着存储的,它们通常能被同一次磁盘 IO 操作所读取。第二,ReiserFS 能够压缩尾文件,节省大量磁盘空间。实际上,带有尾文件压缩功能(默认)的 ReiserFS 文件系统可以比同等的 ext2 文件系统多存储 6 个百分点的数据,这就其自身来说是令人惊叹的。

然而,由于在文件被修改时,尾文件压缩迫使 ReiserFS 重装数据,这就导致了性能上的轻微折损。鉴于这个原因,ReiserFS 尾文件压缩可以被关掉,允许系统管理员在速度与空间有效率上做出选择,或者牺牲一些存储能力来换取更高的速度。

ReiserFS 确实是一个非常出色的文件系统。在我的下一篇文章中,我将会指导您在 Linux 2.4 下完成 ReiserFS 安装的全过程。我们还将仔细地看一看性能调整,应用程序交互作用(和怎么围绕他们工作)以及使用的最佳内核等等。

参考资料

    * Namesys 网页正是更多地了解 ReiserFS 的地方。

    * 要想了解当前更为深入的 ReiserFS 信息,ReiserFS 邮件列表是一个极好的资源。也一定要查看 ReiserFS 邮件列表档案。

    * 您可以在 Juan I. Santos Florido 的 Linux Gazette 日志文件系统的回顾中,发现对于 UFS、ext2、ReiserFS 和更多文件系统中元数据的不同之处的深入探讨。

    * Jedi 的 ReiserFS/Qmail tuning page 中包含了许多对于 qmail 使用者来说很好的信息。也请一定查看 ReiserSMTP — Jedi 的 drop-in qmail 组件集,它提供了令人注目的更高 qmail 性能。

    * Linux 每周新闻是紧跟着最新内核发展的非常好的参考资料。

    * 请阅读在 developerWorks 上的 Steve Best 的 JFS 概述。

    * 请阅读一下在 developerWorks 上的 JFS 基础教程。



关于作者
Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是 Gentoo Technologies, Inc. 的总裁兼 CEO,Gentoo Linux(用于 PC 的高级 Linux)和 Portage 系统(Linux 的下一代移植系统)的创始人。他还是 Macmillan 书籍 Caldera OpenLinux Unleashed、SuSE Linux Unleashed 和 Samba Unleashed 的合作者。Daniel 自二年级起就与计算机结下不解之缘,那时他首先接触的是 Logo 程序语言,并沉溺于 Pac-Man 游戏中。这也许就是他至今仍担任 SONY Electronic Publishing/Psygnosis 的首席图形设计师的原因所在。Daniel 喜欢与妻子 Mary 和新出生的女儿 Hadassah 一起共度时光。可通过 [email protected] 与 Daniel 联系。
[/code:1]
回复

使用道具 举报

发表于 2003-3-15 23:20:47 | 显示全部楼层
[quote:61fe4ee237="pk"]所指的兼容性是什么呢?不能共存?[/quote]
不是,reiserfs当然也可以和ext2共存,具体我不太清楚,但是ext3是由ext2加入日志功能演变而来的,所以,你可以把它看作带有日志功能的ext2。
回复

使用道具 举报

发表于 2003-3-15 23:21:11 | 显示全部楼层
[code:1]使用 ReiserFS 和 Linux 2.4

Daniel Robbins([email protected]
总裁/首席执行官,Gentoo Technologies,Inc.
2001 年 8 月

    随着 Linux 2.4 的发行,出现了使用很多新的文件系统的可能性, 包括 ReiserFS、XFS、GFS 和另外一些文件系统。这些文件系统听起来很“酷”,但是它们到底能做些什么呢,它们擅长什么,还有您究竟怎样才能在一个产品 Linux 环境中安全地使用它们呢?在本系列文章中,Daniel Robbins 通过向您展示怎样在 Linux 2.4 下安装这些新的高级文件系统,回答了这些问题。在他的本系列前面的文章中, Daniel 介绍了日志和 ReiserFS 的好处。在本文中 Daniel 将教您安装一个非常稳定的基于 Linux 2.4 的 ReiserFS 系统。

在本文中,我会向您展示如何让 ReiserFS 运行在 2.4 系列的内核下。我还会和您分享很多关于不同主题的技术信息,包括使用 ReiserFS 最好的 2.4 内核,性能注意事项等等。因为我首先会谈到安装,所以我建议您先通读本文,然后再遵循安装指示。这样,您开始在自己的系统上运行 ReiserFS 的时候,脑子里就会有所有的技术注解,这样您就可以在各个步骤作必要的调整。

寻找好的内核
要在您的系统上使用 ReiserFS,您首先需要找到一个合适的内核。如果您已经熟悉 2.4 内核的发展,您就会知道这个过程比它听起来要复杂。本文完成时,最新的内核是 2.4.6-pre2;但是我建议您在自己的 ReiserFS 系统上还是使用 2.4.4(标准的 Linus 内核)或者 2.4.4-ac9(稍作改进的 Alan Cox 内核)。从我的测试看来,2.4.5 似乎很不稳定,所以我不推荐将这个内核作为产品使用;让我们希望 2.4.6 会比它好很多吧。

如果您想在自己的产品 ReiserFS 系统中使用除 2.4.4 或 2.4.4-ac9 以外的其它内核, 一定要作必要的检查以确保 ReiserFS(和内核大体上)是稳定的。当然,如果您是在一个测试服务器上安装 ReiserFS,只要不会丢失重要的数据,您就可以随意使用任一种内核。

总的来说,要注意内核稳定性问题,特别是 ReiserFS 的稳定性问题,这有两个原因。因为 ReiserFS 是一个“实验的”内核功能,您不能假定一个使用新内核的 ReiserFs 实现刚刚从 tarball 中解出就能够很好地运行。第二个原因(也许在目前是更重要的问题)在于大部分的 2.4 内核发行版和补丁都有一点不稳定,所以目前您行动时还是需要谨慎一点。理论上,所有的 2.4 发行版都应该是准产品化的,因为 2.4 版本应该是一个稳定的系列;但是,实际上它们(还)不是,所以强烈鼓励您小心使用新的、没有测试过的内核。

这段信息的意思不是要吓得您不敢使用 ReiserFS 或者 Linux 2.4,而是要给那些更敢于冒险的人一点理性。不要总是在重要的系统上使用各种还处于测试期的内核;如果这样,您 会吃到苦头的。当您使用一个不可靠的内核时,您不仅仅面临着系统锁定的危险;您还面临着丢失数据和文件系统崩溃的危险,这是您绝对不希望发生的。即便 ReiserFS 实现本身是稳定的,内核其他部分的主要错误也很可能引起文件系统崩溃的产生。

如果您没有最新的内核稳定性信息来源,我建议您定期地访问 Linux 每周新闻(请参阅本文后面的参考资料),及时了解最新的可能出现的内核问题(信息每个星期四更新)。希望现在我已经说服了更多喜欢冒险的读者坚持使用 2.4.4 或 2.4.4-ac9 内核作为产品 ReiserFS 的配置,让我们继续吧。

标准内核
OK,我们现在可以谈谈安装和运行一个准产品化的 ReiserFS 系统的三种选择。第一种选择是只用标准 2.4.4 Linux 内核。第二种选择是使用 2.4.4 内核,同时使用 ReiserFS 大补丁,它包括了一些专门的补丁,使 ReiserFS 达到配额兼容,并与在本机运行的 NFS 服务器更加兼容。第三种选择是,我们可以使用 2.4.4 内核和 ac9 补丁(即 2.4.4-ac9),再加上或不加大补丁。通常我推荐使用 2.4.4-ac9 和大补丁,因为大补丁并没有任何负作用,而且您可能会需要它,而且 ac9 比标准内核执行得好多了。但是,如果您不愿意使用 ac 内核,标准 2.4.4 也不错了。我会简单地向您介绍设置 2.4.4-ac9 和大补丁的步骤,但是如果因为某些原因您不愿安装这两个补丁或其中之一,只要跳过这个步骤即可。现在,让我们开始吧。

首先,从 kernel.org 下载 2.4.4 内核源码并进入您的 /usr/src 目录。 移去该处的任何 linux 目录或者符号连接,如果是目录就将其改名,如果是符号连接就只需删除它。然后:

# cd /usr/src
# cat /path/to/linx-2.4.4.tar.bz2 | bzip2 -d | tar xvf -



ac9 补丁和大补丁
如果您计划只用标准 2.4.4 内核,您就已经拥有全部所需的资源了,可以跳过其余的补丁。然而,我推荐您继续使用下面的 ac 补丁和大补丁。

要使用 ac9 补丁,请从 kernel.org 下载 Alan Cox ac9 补丁。然后键入:

# cd /usr/src/linux
# bzip2 -dc /path/to/patch-2.4.4-ac9.bz2 | patch -p1



一旦标准内核安装完毕,就到 DiCE 去下载 DiCE 的 ReiserFS 大补丁。这个步骤还是可选的,不过也是推荐的,特别是如果您将在此系统上运行 NFS 服务器或者需要配额(如果不是这样,无论如何这个补丁也不会有什么坏处)。要使用大补丁请遵循以下步骤:

# cd /usr/src/linux
# bzip2 -dc /path/to/bigpatch-2.4.4.diff.bz2 | patch -p1



一旦所有可选的修正和大补丁安装完毕,您就可以为 ReiserFS 配置内核了。

注意:如果您需要更多关于如何编译 Linux 内核的指导,可参阅 developerWorks 上的 编译 Linux 内核免费教程。下面是一个简单的摘要。

配置内核非常简单。首先,键入“make menuconfig”。在“Code maturity level options”部分,确保启用了“Prompt for development and/or incomplete code/drivers”选项。然后到“File systems”部分,启用“ReiserFS support”选项。 您将 ReiserFS 设置为直接编译到内核中(而不是作为一种模块);而且通常启用“Have reiserFS do extra internal checking”这个选项不是什么好主意。现在,保存您的设置,编译您的内核(“make dep;make bzImage;make modules;make modules_install”),然后配置您的引导装载器(boot loader)来装载新的配置了 ReiserFS 的内核。

重点:保存当前内核并配置引导装载器(boot loader)总是个好主意,这样万一您的新内核无法工作,您就可以用原来的内核启动。

使用 ReiserFS

安装工具
在重新启动之前,我们需要安装“reiserfsprogs”工具,它包括了“mkreiserfs”、“resize_reiserfs”(对 LVM 用户很有用),还有“fsck.reiserfs”。您可以从 Namesys.com 下载页下载最新版本的“reiserfsprogs”(目前是“3.x.0j”)。一旦这些工具下载完毕,您就可以按以下步骤编译和安装“reiserfsprogs”了:

# cd /tmp
# tar xzvf reiserfsprogs-3.x.0j.tar.gz
# cd reiserfsprogs-3.x.0j
# ./configure
./configure output will appear here
# make
make output will appear here
# make install
make install output will appear here



既然工具已经安装完毕,现在您可以按需要创建任何新的分区(使用“fdisk”或者“cfdisk”)或 LVM 逻辑卷(使用“lvcreate”)并重新启动您的系统。如果您正在创建标准分区,您可以简单地将此分区标记为一个“Linux native file system”(83)。

创建和安装文件系统
重新启动后,您就可以在一个空的分区上创建 ReiserFS 文件系统,如下所示:

# mkreiserfs /dev/
hdxy



在上面的示例中,/dev/hdxy 应该是对应于一个空闲分区的设备节点。象安装其它文件系统一样安装它:

# mount /dev/
hdxy
/mnt/reiser



而且,如果您想在自己的 /etc/fstab 文件中添加一个 ReiserFS 文件系统,只需将“freq”和“passno”字段设置为“0”,如下所示:

/dev/hdc1       /home                   reiserfs        defaults       0 0



从这以后,您的 ReiserFS 文件系统应该不比它的对手 ext2 逊色了,而且您再也不必担心长时间的“fsck”,整体性能也会好得多 — 特别是对于小文件来说。

ReiserFS 技术注解

文件系统稳定性
我已经在一个产品环境下使用了一个多月 2.4.4 版本内核的 ReiserFS(在 cvs.gentoo.org 开发服务器上),根本没有什么崩溃问题。2.4.4 和 2.4.4-ac9 已经非常稳定了。我们的服务器执行大量的磁盘 IO 任务,因为它是我们的 cvs 资料档案库、“dev-wiki”、gentoo.org 邮件服务器、基于邮差的邮件列表,还有很多其他东西的所在之处。

ReiserFS 的局限性
虽然 ReiserFS 在几乎每一种类型的应用程序上都比 ext2 文件系统表现得好,有些地方 ReiserFS 目前还是有点欠缺。令人欣慰的是,这些问题其实并不是 ReiserFS 无法克服的局限性,只是 Namesys 开发人员还没有来得及编码或优化的地方。

没有 dump/restore
是的,这是真的;ReiserFS 没有“dump”和“restore”实现。如果您想使用 ReiserFS 又碰巧是个喜欢使用“dump”的人,您就必须寻找备份数据的其他方法。实际上,事实证明这个根本就不是问题,因为 2.4 系列内核从一开始就不兼容“dump”和“restore”命令。要了解关于 dump 和 2.4 内核的不兼容性的更多信息,请阅读 Linus Torvalds 的帖子(请参阅参考资料),他在帖子中说道“Dump 从一开始就是个愚蠢的程序。不要去碰它。”

性能问题
虽然 ReiserFS 通常抢尽了 ext2 的风头,但它在特定情况下确实有性能上的不足之处。第一个就是处理稀疏文件的能力。ReiserFS 处理稀疏文件的能力会比 ext2 差很多。当 Namesys 开发人员一直设法为 ReiserFS 4 优化 ReiserFS 的这一部分时,这一点会有所改观。在这之前,ext2 是对处理稀疏文件有很高要求的应用程序的较好的解决方案。

在对大量文件执行多个 stat() 调用的代码中,可能也会碰到问题。一个可能触发这种性能缺陷的应用程序(它只存在于 2.4 系列内核的 ReiserFS 实现,在 2.2 内核中不存在)就是“mutt”邮件用户代理(请参阅参考资料),它在被用于读取大型 maildir 形式的邮箱时会触发性能缺陷。显然,每个邮件文件 mutt 都要 stat 两次,这样就会比平常更加影响性能。ReiserFS 开发小组已经意识到了这个特殊的问题,并已经确定了它的起因,如果近期没有解决方案的话,您应该可以在 ReiserFS 4 中看到相应的解决方案。

性能调整
幸运的是,有几种简单通用的性能调整方法可以用来缓解这些问题。第一种是用“noatime”选项(一种对 ReiserFS 和其它文件系统都有用的安装选项)来安装您的 ReiserFS 文件系统。您可能知道,UNIX 系统为文件系统上的每一个对象记录一个 atime,或称为访问时间,每次读取文件时,atime 都会被更新。对于大部分人来说,atime 邮戳功能不是十分有用,而且几乎没有任何应用程序(我想不到一个)依靠 atime 处理什么重要的任务。出于这个原因,通常可以安全地关掉它,这样可以带来一个很好的全面性能提升。通常情况下,除非您确实知道自己需要 atime 支持,您还是应该用 noatime 选项来安装文件系统。使用如下所示的 /etc/fstab 条目:

/dev/hdc1       /home                   reiserfs        noatime       0 0



在关于 ReiserFS 的第一篇文章中,我曾提到 ReiserFS 有一项特别的功能,称为“tail packing”。在 ReiserFS 术语中,“tail”是小于一个系统文件块(4k)的文件,或不能填满一个完整的文件系统块的文件末尾部分。ReiserFS 具有确实卓越的小文件处理性能是因为它能够将这些 tail 合并到它的 b*tree(它的主要数据组织结构)中去,这样它们就能真正地接近 stat-data(ReiserFS 中等同于索引节点的单元)。然而,因为这些 tail 不能填满一个完整的块,它们会浪费很多磁盘空间(当然是相对地说)。为了解决这个问题,ReiserFS 使用了它的“tail packing”功能来将这些 tail 压缩到占用尽可能小的空间。通常,这么做可以让 ReiserFS 文件系统比大小相等的 ext2 文件系统多容纳大约 5% 的数据。

更多关于 notail 的内容
然而,tail packing 也有它的缺点。首先,它的确给性能带来了一个小却不可忽视的冲击。幸运的是,ReiserFS 开发人员已经预计到有些人宁愿牺牲大约 5%的磁盘空间换取一点额外的性能,所以他们创建了“notail”安装选项。当文件系统用这个选项安装时,tail packing 将被关闭,使您的存储容量减小,却有更快的速度。通常,重视文件系统性能的狂热分子同时启用“notail”和“noatime”选项来安装他们的文件系统,从而带来显著的性能提升:

/dev/hdc1       /home                   reiserfs        noatime,notail       0 0



即便您想节省一点磁盘空间,有时候暂时用一下“notail”选项安装文件系统也是件好事。特别是,大多数引导装载器(boot loader)装载一个在启用 tail packing 的 ReiserFS 文件系统上创建的内核时,都会出现问题。如果您正在使用一个比版本 21.6 还低的 LILO,您就会碰到这种问题。在使用最新版本的 GRUB 时也会碰到问题,即不能装载它的 stage1 和 stage1_5 文件,尽管在装载实际内核的时候没有什么问题。如果您已经在经历这种问题了,您可以这样修正此问题-使用“notail”选项安装文件系统,将文件移到另一个文件系统中,然后再把它们移回来。当文件被重新创建时,就不会有 tail 了。另外,记住您还可以很轻易地重新安装文件系统(用新选项),而不需要卸载它。这个特别的示例使用“notail”选项重新安装根目录文件系统。通常情况下,如果您想使用 tail packing,但也需要引导装载器(boot loader)从根目录文件系统装载辅助文件(如内核),这条命令就很有用了:

# mount / -o remount,notail



Qmail 注解
如果您正在 ReiserFS 中使用 qmail,您应该了解一些重要的参考资料。首先,您应该使用 qmail 1.03 源码的补丁。它修正了 qmail 非同步调用“link()”和“unlink()”时出现的问题,它不但是 ReiserFS 的问题,恰好也是 ext2 的问题。接下来您应该看看 Jedi 的 qmail 调优页面,它包含了很多关于怎样尽可能发挥 qmail 性能的很好的建议。最后,请务必查看 Jedi 的 ReiserSMTP 软件包。ReiserSMTP 包含一个 GPL 插件来代替 qmail 的 SMTP 部分;Jedi 的这种替换是特别为 ReiserFS 调整的,依赖新的队列处理例程,它可以给您带来双倍的邮件收取性能。

结论
我发现 ReiserFS 真是一个不可思议的文件系统,它提供了很好的小文件处理性能和非常好的(通常比 ext2 要好)的常规文件处理性能。因为有了 ReiserFS,我的开发人员可以在仅仅 15 秒内完成 Gentoo Linux “cvs” 更新,而使用 ext2 通常要花大约两分钟时间。ReiserFS 使我们开发人员的生活更加愉快,还使我们的 cvs 服务器处理大量的并发 IO 而不会引起硬盘狂转和对交互性能的负面影响。

然而除了所有这些,关于 ReiserFS 最激动人心的地方是它将来的发展方向。Hans Reiser 对 ReiserFS 有一个非常激进而创新的计划,包括计划扩展文件系统从而能够将其作为一个发展成熟的高性能数据库来使用,最后还包括事务支持和高级查询功能。这意味 ReiserFS 将不仅仅“只是另一个高性能文件系统”;相反,它将开拓新的可能和道路,使我们能够用创新方式去解决传统的存储问题。有了 Namesys 的合作,Linux 将来的发展一定会非常激动人心 -这绝对是一件好事情。

参考资料

    * Namesys Web 页就是能更好地了解 ReiserFS 的地方。

    * 注意访问 DiCE 下载页,留意最新的 ReiserFS 大补丁。

    * ReiserFS 邮件列表是能获得当前的,更多深入的 ReiserFS 信息的极好的信息来源。请务必还要查看 ReiserFS 邮件列表档案。

    * Linux 每周新闻是我们及时了解最新的内核发展的很好的参考资料。

    * 您可以在 Linux Gazette 上 Juan I. Santos Florido 的日志文件系统回顾中找到一些有关 UFS、ext2、ReiserFS 之间元数据的差异,以及其它内容的非常详细的信息。

    * Jedi 的 ReiserFS/Qmail 调整页面包含许多对 qmail 用户很有用的信息。请务必还要查看 ReiserSMTP - Jedi 收集的众多 qmail 组件,它们显著提升了 qmail 的性能。

    * 看看 mutt 电子邮件客户,它可以用来读取大的 maildir 形式的邮箱。

    * 阅读 Linus Torvalds 最近关于 dump 和 restore 的评论。

    * 参加 developerWorks 上 编译 Linux 内核的免费教程。

    * 浏览 developerWorks 上更多 Linux 参考资料。

    * 浏览 developerWorks 上 更多开放源代码参考资料。



关于作者
作者Daniel Robbins 是 Gentoo Technologies,Inc. 的总裁/首席执行官,住在新墨西哥州的 Albuquerque,他是 Gentoo Linux(一种 PC 机上的高级 Linux)和 Portage 系统(Linux 的下一代移植系统)的创建者。他还是 Macmillan 的书籍 - Caldera OpenLinux Unleashed、SuSE Linux Unleashed 和 Samba Unleashed - 的特约作者。Daniel 从他二年级时接触到 Logo 编程语言和 Pac Man 游戏的潜在危险魔力后就被这股热流卷进了计算机中。这或许可以解释他为什么曾经是 SONY 电子出版/游戏公司的首席图形设计师了。Daniel 喜欢花时间和他的妻子 Mary 还有他刚出生的宝贝女儿 Hadassah 在一起。您可以通过 [email protected] 联系他。

[/code:1]
回复

使用道具 举报

发表于 2003-3-15 23:26:36 | 显示全部楼层
[quote:cad92a4ba3="樱家冢"][quote:cad92a4ba3="pk"]所指的兼容性是什么呢?不能共存?[/quote]
不是,reiserfs当然也可以和ext2共存,具体我不太清楚,但是ext3是由ext2加入日志功能演变而来的,所以,你可以把它看作带有日志功能的ext2。[/quote]

这个我知道。谢谢!
我在Debian和Mandrake下都试过,用ReiserFS比ext2/3的性能都好,死机的现象已经一去不复返了,但用ext2/ext3的时候,会出现这样那样的文件问题,而且你不正常关机的时候,重新开机扫的时间就够你受的了,有时一不小心,重新安装系统也是常有事情。
回复

使用道具 举报

发表于 2003-3-15 23:28:49 | 显示全部楼层
呵呵,既然转了,就多转一篇。
[code:1]
Ext2 文件系统的硬盘布局
内容:
1 前言
2 粗略的描述
3 详细的布局情况
4 小结
参考资料
关于作者
在 Linux 专区还有:
教程
工具与产品
代码与组件
文章

赵蔚 ([email protected])
2002 年 6 月

    本文主要讲述 Linux 上比较流行的 ext2 文件系统在硬盘分区上的详细布局情况。Ext2 文件系统加上日志支持的下一个版本是 ext3 文件系统,它和 ext2 文件系统在硬盘布局上是一样的,其差别仅仅是 ext3 文件系统在硬盘上多出了一个特殊的 inode(可以理解为一个特殊文件),用来记录文件系统的日志,也即所谓的 journal。由于本文并不讨论日志文件,所以本文的内容对于 ext2 和 ext3 都是适用的。

1 前言

本文的资料来源是 Linux 内核中 ext3 文件系统的源代码。为了便于读者查阅源代码,本文中一些关键的技术词汇都使用了内核源代码中所使用的英语单词,而没有使用相应的中文翻译。(这种方法是否恰当,还请读者朋友们指教。)

2 粗略的描述

对于 ext2 文件系统来说,硬盘分区首先被划分为一个个的 block,一个 ext2 文件系统上的每个 block 都是一样大小的,但是对于不同的 ext2 文件系统,block 的大小可以有区别。典型的 block 大小是 1024 bytes 或者 4096 bytes。这个大小在创建 ext2 文件系统的时候被决定,它可以由系统管理员指定,也可以由文件系统的创建程序根据硬盘分区的大小,自动选择一个较合理的值。这些 blocks 被聚在一起分成几个大的 block group。每个 block group 中有多少个 block 是固定的。

每个 block group 都相对应一个 group descriptor,这些 group descriptor 被聚在一起放在硬盘分区的开头部分,跟在 super block 的后面。所谓 super block,我们下面还要讲到。在这个 descriptor 当中有几个重要的 block 指针。我们这里所说的 block 指针,就是指硬盘分区上的 block 号数,比如,指针的值为 0,我们就说它是指向硬盘分区上的 block 0;指针的值为 1023,我们就说它是指向硬盘分区上的 block 1023。我们注意到,一个硬盘分区上的 block 计数是从 0 开始的,并且这个计数对于这个硬盘分区来说是全局性质的。

在 block group 的 group descriptor 中,其中有一个 block 指针指向这个 block group 的 block bitmap,block bitmap 中的每个 bit 表示一个 block,如果该 bit 为 0,表示该 block 中有数据,如果 bit 为 1,则表示该 block 是空闲的。注意,这个 block bitmap 本身也正好只有一个 block 那么大小。假设 block 大小为 S bytes,那么 block bitmap 当中只能记载 8*S 个 block 的情况(因为一个 byte 等于 8 个 bits,而一个 bit 对应一个 block)。这也就是说,一个 block group 最多只能有 8*S*S bytes 这么大。

在 block group 的 group descriptor 中另有一个 block 指针指向 inode bitmap,这个 bitmap 同样也是正好有一个 block 那么大,里面的每一个 bit 相对应一个 inode。硬盘上的一个 inode 大体上相对应于文件系统上的一个文件或者目录。关于 inode,我们下面还要进一步讲到。

在 block group 的 descriptor 中另一个重要的 block 指针,是指向所谓的 inode table。这个 inode table 就不止一个 block 那么大了。这个 inode table 就是这个 block group 中所聚集到的全部 inode 放在一起形成的。

一个 inode 当中记载的最关键的信息,是这个 inode 中的用户数据存放在什么地方。我们在前面提到,一个 inode 大体上相对应于文件系统中的一个文件,那么用户文件的内容存放在什么地方,这就是一个 inode 要回答的问题。一个 inode 通过提供一系列的 block 指针,来回答这个问题。这些 block 指针指向的 block,里面就存放了用户文件的内容。

2.1 回顾

现在我们回顾一下。硬盘分区首先被分为好多个 block。这些 block 聚在一起,被分成几组,也就是 block group。每个 block group 都有一个 group descriptor。所有这些 descriptor 被聚在一起,放在硬盘分区的开头部分,跟在 super block 的后面。从 group descriptor 我们可以通过 block 指针,找到这个 block group 的 inode table 和 block bitmap 等等。从 inode table 里面,我们就可以看到一个个的 inode 了。从一个 inode,我们通过它里面的 block 指针,就可以进而找到存放用户数据的那些 block。我们还要提一下,block 指针不是可以到处乱指的。一个 block group 的 block bitmap 和 inode bitmap 以及 inode table,都依次存放在这个 block group 的开头部分,而那些存放用户数据的 block 就紧跟在它们的后面。一个 block group 结束后,另一个 block group 又跟着开始。

3 详细的布局情况

3.1 Super Block

所谓 ext2 文件系统的 super block,就是硬盘分区开头(开头的第一个 byte 是 byte 0)从 byte 1024 开始往后的一部分数据。由于 block size 最小是 1024 bytes,所以 super block 可能是在 block 1 中(此时 block 的大小正好是 1024 bytes),也可能是在 block 0 中。

硬盘分区上 ext3 文件系统的 super block 的详细情况如下。其中 __u32 是表示 unsigned 不带符号的 32 bits 的数据类型,其余类推。这是 Linux 内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用 unsigned long 等等来代替。下面列表中关于 fragments 的部分可以忽略,Linux 上的 ext3 文件系统并没有实现 fragments 这个特性。另外要注意,ext3 文件系统在硬盘分区上的数据是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平台上开发 ext3 相关的程序,要特别注意这一点。如果只是在 PC 上做开发,倒不用特别注意。

struct ext3_super_block {
/*00*/ __u32 s_inodes_count;      /* inodes 计数 */
       __u32 s_blocks_count;      /* blocks 计数 */
       __u32 s_r_blocks_count;    /* 保留的 blocks 计数 */
       __u32 s_free_blocks_count; /* 空闲的 blocks 计数 */
/*10*/ __u32 s_free_inodes_count; /* 空闲的 inodes 计数 */
       __u32 s_first_data_block;  /* 第一个数据 block */
       __u32 s_log_block_size;    /* block 的大小 */
       __s32 s_log_frag_size;     /* 可以忽略 */
/*20*/ __u32 s_blocks_per_group;  /* 每 block group 的 block 数量 */
       __u32 s_frags_per_group;   /* 可以忽略 */
       __u32 s_inodes_per_group;  /* 每 block group 的 inode 数量 */
       __u32 s_mtime;             /* Mount time */
/*30*/ __u32 s_wtime;             /* Write time */
       __u16 s_mnt_count;         /* Mount count */
       __s16 s_max_mnt_count;     /* Maximal mount count */
       __u16 s_magic;             /* Magic 签名 */
       __u16 s_state;             /* File system state */
       __u16 s_errors;            /* Behaviour when detecting errors */
       __u16 s_minor_rev_level;   /* minor revision level */
/*40*/ __u32 s_lastcheck;         /* time of last check */
       __u32 s_checkinterval;     /* max. time between checks */
       __u32 s_creator_os;        /* 可以忽略 */
       __u32 s_rev_level;         /* Revision level */
/*50*/ __u16 s_def_resuid;        /* Default uid for reserved blocks */
       __u16 s_def_resgid;        /* Default gid for reserved blocks */
       __u32 s_first_ino;         /* First non-reserved inode */
       __u16 s_inode_size;        /* size of inode structure */
       __u16 s_block_group_nr;    /* block group # of this superblock */
       __u32 s_feature_compat;    /* compatible feature set */
/*60*/ __u32 s_feature_incompat;  /* incompatible feature set */
       __u32 s_feature_ro_compat; /* readonly-compatible feature set */
/*68*/ __u8  s_uuid[16];          /* 128-bit uuid for volume */
/*78*/ char  s_volume_name[16];   /* volume name */
/*88*/ char  s_last_mounted[64];  /* directory where last mounted */
/*C8*/ __u32 s_algorithm_usage_bitmap; /* 可以忽略 */
       __u8  s_prealloc_blocks;        /* 可以忽略 */
       __u8  s_prealloc_dir_blocks;    /* 可以忽略 */
       __u16 s_padding1;               /* 可以忽略 */
/*D0*/ __u8  s_journal_uuid[16]; /* uuid of journal superblock */
/*E0*/ __u32 s_journal_inum;     /* 日志文件的 inode 号数 */
       __u32 s_journal_dev;      /* 日志文件的设备号 */
       __u32 s_last_orphan;      /* start of list of inodes to delete */
/*EC*/ __u32 s_reserved[197];    /* 可以忽略 */
};

我们可以看到,super block 一共有 1024 bytes 那么大。在 super block 中,我们第一个要关心的字段是 magic 签名,对于 ext2 和 ext3 文件系统来说,这个字段的值应该正好等于 0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的 ext2 或 ext3 文件系统。从这里,我们也可以估计到,ext2 和 ext3 的兼容性一定是很强的,不然的话,Linux 内核的开发者应该会为 ext3 文件系统另选一个 magic 签名才对。

在 super block 中另一个重要的字段是 s_log_block_size。从这个字段,我们可以得出真正的 block 的大小。我们把真正 block 的大小记作 B,B = 1 << (s_log_block_size + 10),单位是 bytes。举例来说,如果这个字段是 0,那么 block 的大小就是 1024 bytes,这正好就是最小的 block 大小;如果这个字段是 2,那么 block 大小就是 4096 bytes。从这里我们就得到了 block 的大小这一非常重要的数据。

3.2 Group Descriptors

我们继续往下,看跟在 super block 后面的一堆 group descriptors。首先注意到 super block 是从 byte 1024 开始,一共有 1024 bytes 那么大。而 group descriptors 是从 super block 后面的第一个 block 开始。也就是说,如果 super block 是在 block 0,那么 group descriptors 就是从 block 1 开始;如果 super block 是在 block 1,那么 group descriptors 就是从 block 2 开始。因为 super block 一共只有 1024 bytes 那么大,所以不会超出一个 block 的边界。如果一个 block 正好是 1024 bytes 那么大的话,我们看到 group descriptors 就是紧跟在 super block 后面的了,没有留一点空隙。而如果一个 block 是 4096 bytes 那么大的话,那么在 group descriptors(从 byte 4096 开始)和 super block 的结尾之间,就有一定的空隙(4096 - 2048 bytes)。

那么硬盘分区上一共有多少个 block group,或者说一共有多少个 group descriptors,这我们要在 super block 中找答案。super block 中的 s_blocks_count 记录了硬盘分区上的 block 的总数,而 s_blocks_per_group 记录了每个 group 中有多少个 block。显然,文件系统上的 block groups 数量,我们把它记作 G,G = (s_blocks_count - s_first_data_block - 1) / s_blocks_per_group + 1。为什么要减去 s_first_data_block,因为 s_blocks_count 是硬盘分区上全部的 block 的数量,而在 s_first_data_block 之前的 block 是不归 block group 管的,所以当然要减去。最后为什么又要加一,这是因为尾巴上可能多出来一些 block,这些 block 我们要把它划在一个相对较小的 group 里面。

注意,硬盘分区上的所有这些 group descriptors 要能塞在一个 block 里面。也就是说 groups_count * descriptor_size 必须小于等于 block_size。

知道了硬盘分区上一共有多少个 block group,我们就可以把这么多个 group descriptors 读出来了。先来看看 group descriptor 是什么样子的。

struct ext3_group_desc
{
__u32 bg_block_bitmap;      /* block 指针指向 block bitmap */
__u32 bg_inode_bitmap;      /* block 指针指向 inode bitmap */
__u32 bg_inode_table;       /* block 指针指向 inodes table */
__u16 bg_free_blocks_count; /* 空闲的 blocks 计数 */
__u16 bg_free_inodes_count; /* 空闲的 inodes 计数 */
__u16 bg_used_dirs_count;   /* 目录计数 */
__u16 bg_pad;               /* 可以忽略 */
__u32 bg_reserved[3];       /* 可以忽略 */
};

每个 group descriptor 是 32 bytes 那么大。从上面,我们看到了三个关键的 block 指针,这三个关键的 block 指针,我们已经在前面都提到过了。

3.3 Inode

前面都准备好了以后,我们现在终于可以开始读取文件了。首先要读的,当然是文件系统的根目录。注意,这里所谓的根目录,是相对于这一个文件系统或者说硬盘分区而言的,它并不一定是整个 Linux 操作系统上的根目录。这里的这个 root 目录存放在一个固定的 inode 中,这就是文件系统上的 inode 2。需要提到 inode 计数同 block 计数一样,也是全局性质的。这里需要特别注意的是,inode 计数是从 1 开始的,而前面我们提到过 block 计数是从 0 开始,这个不同在开发程序的时候要特别留心。(这一奇怪的 inode 计数方法,曾经让本文作者大伤脑筋。)

那么,我们先来看一下得到一个 inode 号数以后,怎样读取这个 inode 中的用户数据。在 super block 中有一个字段 s_inodes_per_group 记载了每个 block group 中有多少个 inode。用我们得到的 inode 号数除以 s_inodes_per_group,我们就知道了我们要的这个 inode 是在哪一个 block group 里面,这个除法的余数也告诉我们,我们要的这个 inode 是这个 block group 里面的第几个 inode;然后,我们可以先找到这个 block group 的 group descriptor,从这个 descriptor,我们找到这个 group 的 inode table,再从 inode table 找到我们要的第几个 inode,再以后,我们就可以开始读取 inode 中的用户数据了。

这个公式是这样的:block_group = (ino - 1) / s_inodes_per_group。这里 ino 就是我们的 inode 号数。而 offset = (ino - 1) % s_inodes_per_group,这个 offset 就指出了我们要的 inode 是这个 block group 里面的第几个 inode。

找到这个 inode 之后,我们来具体的看看 inode 是什么样的。

struct ext3_inode {
__u16 i_mode;    /* File mode */
__u16 i_uid;     /* Low 16 bits of Owner Uid */
__u32 i_size;    /* 文件大小,单位是 byte */
__u32 i_atime;   /* Access time */
__u32 i_ctime;   /* Creation time */
__u32 i_mtime;   /* Modification time */
__u32 i_dtime;   /* Deletion Time */
__u16 i_gid;     /* Low 16 bits of Group Id */
__u16 i_links_count;          /* Links count */
__u32 i_blocks;               /* blocks 计数 */
__u32 i_flags;                /* File flags */
__u32 l_i_reserved1;          /* 可以忽略 */
__u32 i_block[EXT3_N_BLOCKS]; /* 一组 block 指针 */
__u32 i_generation;           /* 可以忽略 */
__u32 i_file_acl;             /* 可以忽略 */
__u32 i_dir_acl;              /* 可以忽略 */
__u32 i_faddr;                /* 可以忽略 */
__u8  l_i_frag;               /* 可以忽略 */
__u8  l_i_fsize;              /* 可以忽略 */
__u16 i_pad1;                 /* 可以忽略 */
__u16 l_i_user_id_high;           /* 可以忽略 */
__u16 l_i_gid_high;           /* 可以忽略 */
__u32 l_i_reserved2;          /* 可以忽略 */
};

我们看到在 inode 里面可以存放 EXT3_N_BLOCKS(= 15)这么多个 block 指针。用户数据就从这些 block 里面获得。15 个 blocks 不一定放得下全部的用户数据,在这里 ext3 文件系统采取了一种分层的结构。这组 15 个 block 指针的前 12 个是所谓的 direct blocks,里面直接存放的就是用户数据。第 13 个 block,也就是所谓的 indirect block,里面存放的全部是 block 指针,这些 block 指针指向的 block 才被用来存放用户数据。第 14 个 block 是所谓的 double indirect block,里面存放的全是 block 指针,这些 block 指针指向的 block 也被全部用来存放 block 指针,而这些 block 指针指向的 block,才被用来存放用户数据。第 15 个 block 是所谓的 triple indirect block,比上面说的 double indirect block 有多了一层 block 指针。作为练习,读者可以计算一下,这样的分层结构可以使一个 inode 中最多存放多少字节的用户数据。(计算所需的信息是否已经足够?还缺少哪一个关键数据?)

一个 inode 里面实际有多少个 block,这是由 inode 字段 i_size 再通过计算得到的。i_size 记录的是文件或者目录的实际大小,用它的值除以 block 的大小,就可以得出这个 inode 一共占有几个 block。注意上面的 i_blocks 字段,粗心的读者可能会以为是这一字段记录了一个 inode 中实际用到多少个 block,其实不是的。那么这一字段是干什么用的呢,读者朋友们可以借这个机会,体验一下阅读 Linux 内核源代码的乐趣。;-)

3.4 文件系统的目录结构

现在我们已经可以读取 inode 的内容了,再往后,我们将要读取文件系统上文件和目录的内容。读取文件的内容,只要把相应的 inode 的内容全部读出来就行了;而目录只是一种固定格式的文件,这个文件按照固定的格式记录了目录中有哪些文件,以及它们的文件名,和 inode 号数等等。

struct ext3_dir_entry_2 {
__u32 inode;    /* Inode 号数 */
__u16 rec_len;  /* Directory entry length */
__u8  name_len; /* Name length */
__u8  file_type;
char  name[EXT3_NAME_LEN]; /* File name */
};

上面用到的 EXT3_NAME_LEN 是 255。注意,在硬盘分区上的 dir entry 不是固定长度的,每个 dir entry 的长度由上面的 rec_len 字段记录。

4 小结

有了以上的这些信息,我们就可以读取一个 ext3 文件系统的全部内容了。如果读者有 Windows 驱动程序开发的经验,从本文的信息,开发一个 Windows 下只读的 ext3 文件系统是可能的。但是要想又读又写,那还需要了解 Ext3 的日志文件的结构,而本文限于篇幅,并没有包括这方面的内容。

参考文献

1 Remy Card, Theodore Ts'o, Stephen Tweedie, Design and Implementation of the Second Extended Filesystem, http://web.mit.edu/tytso/www/linux/ext2intro.html

2 Linux Kernel 2.4.18 Source Code, http://lxr.linux.no/source/fs/ext3/
关于作者
赵蔚,是中国大陆第二个注册的 Debian GNU/Linux 义务开发人员。作者对于 LISP 和 Lambda Calculus 也有浓厚的兴趣。
[/code:1]
回复

使用道具 举报

发表于 2003-3-15 23:31:05 | 显示全部楼层
问题是,在已经装了ext2的系统上,只要改一下参数就可以变成ext3
而reiserfs要把分区格掉重来,太麻烦了

而且如果不想用ext3,直接在fstab中改回ext2,就又回到非日志系统了

呵呵,不是在任何情况下都要用journal fs的

reiserfs也只是近一年多来才真正稳定的,以前死在reiserfs上的例子太多了
回复

使用道具 举报

发表于 2003-3-15 23:36:36 | 显示全部楼层
呵呵,我原来看到有些人用ext2,如果想升级ext3,要做很大的改动,而且还要承担很大的风险。呵呵,经过老兄这么一说,原来ext3转ext2是很么简单。
呵呵,ReiserFS也只是近一年多来才真正稳定的,所以我感觉用ReiserFS还是强少少。。。。
回复

使用道具 举报

发表于 2003-3-16 09:33:12 | 显示全部楼层
我也喜欢 reiserfs,是从用 mdk 时用 ext3 时不小心断电结果重启后 ext3 总是挂了,fsck 只会更惨。。。后来用 reiserfs 就没问题。

不过 reiserfs 消耗硬盘很利害,一个空的 200M 分区如果用 reiserfs 居然要莫名其妙吃掉 50M 硬盘。。。
-----------------------------------------
pk 今天很强啊,转那么多文章,待我好好研究一下  

这张帖子请进精华区~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-20 00:53 , Processed in 0.345292 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表