分类: LINUX
2008-05-12 15:37:52
◆
有了前面章节 5 的基础,理解 Linux 下根文件系统的安装并不困难,因为不管怎么样,安装一个文件系统到 VFS 中某一安装点的过程原理毕竟都是一样的。
这个过程大致是:首先要确定待安装的 ext2 文件系统的来源,其次是确定 ext2 文件系统在 VFS中的安装点,然后便是具体的安装过程。
关于第一问题,Linux 2.4.20 的内核另有一大堆的代码去解决,限于篇幅,笔者不想在这里去具体说明这个过程,大概记住它是要解决到哪里去找要安装的文件系统的就可以了,这里我们不妨就认为要安装的根文件系统就来自于主硬盘的第一分区 hda1.
关于第二个问题,Linux 2.4.20 的内核把来自于 hda1 上 ext2 文件系统安装到了 VFS 目录树中的"/root" 目录上。其实,把 ext2 文件系统安装到 VFS 目录树下的哪个安装点并不重要(VFS 的根目录除外),只要是这个安装点在 VFS 树中是存在的,并且内核对它没有另外的用途。如果读者喜欢,尽可以自己在 VFS 中创建一个 "/Windows" 目录,然后将 ext2 文件系统安装上去作为将来用户进程的根目录,没有什么不可以的。问题的关键是要将进程的根目录和当前工作目录设定好,因为毕竟只用用户进程才去关心现实的文件系统,要知道笔者的这篇稿子可是要存到硬盘上去的。
在 Linux 下,设定一个进程的当前工作目录是通过系统调用 sys_chdir() 进行的。初始化期间,Linux 在将 hda1 上的 ext2 文件系统安装到了 "/root" 上后,通过调用 sys_chdir("/root") 将当前进程,也就是 init_task 进程的当前工作目录(pwd)设定为 ext2 文件系统的根目录。记住此时 init_task进程的根目录仍然是图 3 中的 dentry,也就是 VFS 树的根目录,这显然是不行的,因为以后 Linux 世界中的所有进程都由这个 init_task 进程派生出来,无一例外地要继承该进程的根目录,如果是这样,意味着用户进程从根目录搜索某一目录时,实际上是从 VFS 的根目录开始的,而事实上却是从 ext2 的根文件开始搜索的。这个矛盾的解决是靠了在调用完 mount_root() 函数后,系统调用的下面两个函数:
sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); |
其主要作用便是将 init_task 进程的根目录转化成安装上去的 ext2 文件系统的根目录。有兴趣的读者可以自行去研究这一过程。
所以在用户空间下,更多地情况是只能见到 VFS 这棵大树的一叶,而且还是被安装过文件系统了的,实际上对用户空间来说还是不可见。我想,VFS 更多地被内核用来实现自己的功能,并以系统调用的方式提供过用户进程使用,至于在其上实现的不同文件系统的安装,也只是其中的一个功能罢了。
◆
文件系统在整个 Linux 的内核中具有举足轻重的地位,代码量也很复杂繁琐。但是因为其重要的地位,要想对 Linux 的内核有比较深入的理解,必须要能越过文件系统这一关。当然阅读其源代码便是其中最好的方法,本文试图给那些已经尝试着去阅读,但是目前尚有困惑的读者画一张 VFS 文件系统的草图,希望能对读者有些许启发。但是想在如此有限的篇幅里去阐述清楚 Linux 中整个文件系统的来龙去脉,是根本不现实的。而且本文也只是侧重于剖析 VFS 的机制,对于象具体的文件读写,为提高效率而引入的各种 buffer,hash 等内容以及文件系统的安全性方面,都没有提到。毕竟,本文只想帮助读者理清一个大体的脉络,最终的理解与领悟,还得靠读者自己去潜心研究源代码。最后,对本文相关的任何问题或建议,都欢迎用 email 和笔者联系。