Reiser文件系统由Hans Reiser发明,设计目标是在性能上超过ext2文件系统,提供更高的空间利用率,并且在处理大目录时能强过所有当时的文件系统。Reiser文件系统使用平衡树结构来存储文件和目录,并提供日志功能。
本文描述Reiser文件系统3.6版本在磁盘上的结构。文本不解释文件系统的平衡树是怎样工作的,日志是怎样记录的,以及文件和目录是怎样实现的。
块(Blocks)
Reiser分区被分成多个固定大小的块,从0开始编号。每个分区最多可有232个块。分区从64K字节开始,前面的空间留给分区表和系统启动程序。分区里第一个块是超级块(super block),包含了重要的信息,比如块大小和块数。超级块的编号依赖于块大小,但总是从64K字节开始。Linux下默认的块大小是4096字节,于是超级块的编号就是16。整个分区只有一个超级块。
紧接超级块的是位图块,用每个bit记录某个块是否空闲。一个位图块能记录的块数也与块大小有关,如果这个数值是k,那么每隔k个块,就有一个位图块。
块大小(bytes) |
4,096 |
512 |
1,024 |
8,192 |
每个位图块能记录的块数 |
32,768 |
4,096 |
8,192 |
65,536 |
超级块编号 |
16 |
128 |
64 |
8 |
第一个位图块编号 |
17 |
129 |
65 |
9 |
第二个位图块编号 |
32,768 |
4,096 |
8,192 |
65,536 |
第三个位图块编号 |
65,536 |
8,192 |
16,384 |
131,072 |
第四个位图块编号 |
98,304 |
12,288 |
24,576 |
196,608 |
...... |
(假定分区足够大)
第一个位图块之后应该是日志,不过超级块里的信息才是最准确的。
超级块(Superblock)
Name |
Size |
Description |
Block count |
4 |
分区里的块数 |
Free blocks |
4 |
空闲块数 |
Root block |
4 |
包含根节点的块编号 |
Journal block |
4 |
包含第一个日志节点的块编号 |
Journal device |
4 |
日志设备号 |
Orig. journal size |
4 |
初始日志大小。当分区所在的系统有不同的日志大小时需要 |
Journal trans. max |
4 |
一次事务涉及的最大块数 |
Journal magic |
4 |
随机魔幻数 |
Journal max batch |
4 |
一次日志提交涉及的最大块数 |
Journal max commit age |
4 |
异步提交的最大延时(秒) |
Journal max trans. age |
4 |
事务提交的最大延时(秒) |
Blocksize |
2 |
块的字节大小 |
OID max size |
2 |
对象id的最大字节长度 |
OID current size |
2 |
当前对象id的字节长度 |
State |
2 |
当前分区状态:正常(1),错误(2) |
Magic string |
12 |
Reiser文件系统的标志,比如“ReIsEr2Fs” |
Hash function code |
4 |
使用的hash函数代号 |
Tree Height |
2 |
当前索引树的高度 |
Bitmap number |
2 |
所有位图块的个数 |
Version |
2 |
版本数 |
Reserved |
2 |
保留 |
Inode Generation |
4 |
当前inode的衍生代数,在每次平衡索引树的时候加1 |
示例:
下面是Intel系统里一个256M分区的超级块内容:
00000000 66 00 01 00 93 18 00 00 82 40 00 00 12 00 00 00 f........@......
00000010 00 00 00 00 00 20 00 00 00 04 00 00 ac 34 11 57 ..... ......¬4.W
00000020 84 03 00 00 1e 00 00 00 00 00 00 00 00 10 cc 03 ..............Ì.
00000030 08 00 02 00 52 65 49 73 45 72 32 46 73 00 00 00 ....ReIsEr2Fs...
00000040 03 00 00 00 04 00 03 00 02 00 00 00 dc 52 00 00 ............ÜR..
Block count: 65638
Free blocks: 6291
Root block: 16514
Journal block: 18
Journal device: 0
Original journal size: 8192
Journal trans. max: 1024
Journal magic: 1460745388
Journal max. batch: 900
Journal max. commit age: 30
Journal max. trans. age: 0
Blocksize: 4096
OID max. size: 972
OID current size: 8
State: 2 (error)
Magic String: ReIsEr2Fs
Hash function code: 3
Tree height: 4
Bitmap number: 3
Version: 2
Inode generation: 21212
注意:被加载的分区的state是“2 (error)”,这样如果系统崩溃了,下次启动时就能检测出来。version并不是文件系统的版本(3.6),而是文件系统结构的修改次数。
位图块(Bitmap blocks)
位图块的每个bit表示一个块的空闲状态。每个位图块能表示(8×块大小)个块。字节0表示头8个块,字节1表示下面8个,以此类推。每个字节的低4位表示前面4个块,高4位表示后面4个块。1表示已使用,0表示空闲。
示例:
00000400 ff ff f7 ff 7f 00 00 00 00 00 00 00 00 80 cb bd ÿÿ÷ÿ..........˽
上面的16字节表示编号从8192到8319的块,那么:
Blocks 8192-8210: 已用
Block 8211: 空闲 (f7的2进制是11110111)
Blocks 8212-8230: 已用
Blocks 8231-8302: 空闲
Blocks 8303-8305: 已用
Block 8306: 空闲
Block 8307: 已用
Blocks 8308-8309: 空闲
Blocks 8310-8312: 已用
Block 8313: 空闲
Blocks 8314-8317: 已用
Block 8318: 空闲
Block 8319: 已用