我们看到在 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/
关于作者 赵蔚(zhaoway@public1.ptt.js.cn) ,是中国大陆第二个注册的 Debian GNU/Linux 义务开发人员。作者对于 LISP 和 Lambda Calculus 也有浓厚的兴趣。
单击此处查看PDF版全文
上一篇:ext2文件系统下恢复误删除的文件 下一篇:Linux文件系统的反删除方法 |