Chinaunix首页 | 论坛 | 博客
  • 博客访问: 265738
  • 博文数量: 40
  • 博客积分: 589
  • 博客等级: 中士
  • 技术积分: 549
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-10 16:03
文章分类

全部博文(40)

文章存档

2013年(6)

2012年(34)

我的朋友

分类: LINUX

2012-12-14 10:52:53

http://www.ibm.com/developerworks/cn/linux/l-vfs/

在Linux系统中,每个分区都是一个文件系统,都有自己的目录层次结构。Linux的最重要特征之一就是支持多种文件系统,这样它更加灵

活,并可以和许多其它种操作系统共存。由于系统已将Linux文件系统的所有细节进行了转换,所以Linux核心的其它部分及系统中运行的程序

将看到统一的文件系统。   
    大多数由windows平台转来的用户在使用linux文件系统的时候都会感到困惑。linux文件系统与windows文件系统有很大的差别。本文设身

处地的为新手介绍他们的不同点并且向新手介绍linux的文件系统。
  作为开端,只有一个单独的顶级目录结构。所有一切都从 '根' 开始,用 '/' 代表, 并且延伸到子目录。DOS/Windows有不同的分区,同

时目录都存于分区上。linux则通过 '加载' 的方式把所有分区都放置在 '根' 下制定的目录里。windows下最接近于 '根' 的是c:。 
  一句话总结:Windows下,目录结构属于分区;Linux下,分区 '加载' 于目录结构。 
    在linux系统中,目前已经开发出多种文件系统,那么如何让这些文件系统能共存在一个系统中呢,从linux 2.0开始,引入了虚拟文件系

统管理器 VFS的概念。
    Linux 下的文件系统主要可分为三大块:
① 一是上层的文件系统的系统调用,
② 二是虚拟文件系统交换器 VFS(Virtual Filesystem Switch),
③ 三是挂载到 VFS 中的各实际文件系统,例如 ext2,jffs 等。

一、关于VFS
    VFS的确切叫法是Virtual Filesystem Switch虚拟文件系统交换器,这里的VFS中的“S”是指的switch,这个需要强调一下的,它很容易

被混淆成“system”,如果理解成“system”将是不正确的,请多加注意。
    VFS是具体文件系统filesystem的一个管理器。
    VFS是Linux内核中的一个软件层,一种软件机制,它也提供了内核中的一个抽象功能,允许不同的文件系统共存,可以称它为 Linux 的文

件系统管理者,与它相关的数据结构只存在于物理内存当中。所以在每次系统初始化期间,Linux 都首先要在内存当中构造一棵 VFS 的目录树

(在 Linux 的源代码里称之为 namespace),实际上便是在内存中建立相应的数据结构。VFS 目录树在 Linux 的文件系统模块中是个很重要的

概念,不要将其与实际文件系统目录树混淆,VFS 中的各目录其主要用途是用来提供实际文件系统的挂载点。
    平时所叫的文件系统是指可能会被挂载到目录树中的各个实际文件系统,所谓实际文件系统,即是指VFS 中的实际操作最终要通过它们来

完成而已,并不意味着它们一定要存在于某种特定的存储设备上(如ramfs是利用VFS自身结构而形成的内存文件系统,只存在于内存)。比如

在笔者的 Linux 机器下就注册有"rootfs"、"proc"、"ext2"、"sockfs" 等十几种文件系统。
    而rootfs将是挂载在这个目录树的根结点(root),即 "/"目录上的。有了VFS,那么对文件的操作将使用统一的接口,将来通过文件系统

调用对 VFS 发起的文件操作等指令将被 rootfs 文件系统中相应的函数接口所接管。
    同样,这个VFS目录树还有其他目录结点(如/dev)可供挂载,至于在 VFS 的目录树中向其中某个目录(安装点 mount point)上挂载

(mount)一个文件系统的过程,可简单描述为:将某一设备(dev_name)上某一文件系统(file_system_type)安装到VFS目录树上的某一安装点

(dir_name)。它要解决的问题是:将对 VFS 目录树中某一目录的操作转化为具体安装到其上的实际文件系统的对应操作。比如说,如果将

hda2 上的根文件系统(假设文件系统类型为 ext2)安装到了VFS新建立的 "/dev" 目录上(此时,"/dev" 目录就成为了安装点),那么安装成功

之后应达到这样的目的,即:对 VFS 文件系统的 "/dev" 目录执行 "ls" 指令,该条指令应能列出 hda2 上 ext2 文件系统的根目录下所有的

目录和文件。很显然,这里的关键是如何将对 VFS 树中 "/dev" 的目录操作指令转化为安装在其上的 ext2 这一实际文件系统中的相应指令。
记住:对目录或文件的操作将最终由目录或文件所对应的 inode 结构中的 i_op 和 i_fop 所指向的函数表中对应的函数来执行。所以,不管

最终解决方案如何,都可以设想必然要通过将对 "/dev" 目录所对应的 inode 中 i_op 和 i_fop 的调用转换到 hda2 上根文件系统 ext2 中

根目录所对应的 inode 中 i_op 和 i_fop 的操作。

安装根文件系统:
    不管怎么样,安装一个文件系统到 VFS 中某一安装点的过程原理毕竟都是一样的,安装根文件系统也是一样,前面所说的rootfs是挂载在

VFS目录树的"/"上其实是不准确的,其实是“/root"上的,看一下下面安装根文件系统的过程就明白了:
    这个过程大致是:首先要确定待安装的 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 这棵大树的一叶(/root这个目录),而且还是被安装过文件系统了的,实际上对用户空

间来说还是不可见。我想,VFS 更多地被内核用来实现自己的功能,并以系统调用的方式提供过用户进程使用,至于在其上实现的不同文件系

统的安装,也只是其中的一个功能罢了。

    总之,记住VFS 中各目录的主要用途是为以后挂载文件系统提供挂载点。所以真正的文件操作还是要通过挂载后的文件系统提供的功能接

口来进行就行了。
注:本节内容主要参考:http://www.ibm.com/developerworks/cn/linux/l-vfs/ 解析 Linux 中的 VFS 文件系统机制,作者:Ricard Chen

    二、关于其他文件系统
    这里要说的是相当于上节说的“实际文件系统”(与VFS虚拟文件系统区别开的)。
    这里说的实际文件系统可以分两种:
    一种也是叫虚拟的,其实可以叫pseudo的,或者可以理解为linux内核级的FS,如devfs,/proc,sysfs;ramfs,tmpfs(Virtual memory file system)等等,它们仅是个文件系统,而不是块设备,与下面的实际文件系统都不是在一个级别,不是一个层次的东西,是不能作为rootfs的,但是若嵌入式设备Flash上启动的是经过压缩的内核时,可以用ramfs,tmpfs实现ramdisk作为根文件系统。

    另一种是包含在flash或者硬盘等其他硬件块设备上的或者网络设备上的,如flash上的有jffs/jffs2,yaffs,硬盘ext2,网络nfs等等。

阅读(2790) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~