手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

[转载ibm]解析 Linux 中的 VFS 文档系统机制

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

这个数据结构在路径搜索的过程中用来记录相关信息,起着类似"路 标"的作用。其中前两项中的 dentry记录的是要建目录的父目录的信息,mnt 成员接下来会解释到。后三项记录的是所查找路径的最后一个节点(即待建目录或文档)的信息。 现在为建立目录 "/dev" 而调用 sys_mkdir("/dev", 0700),其中参数 0700 我们不去管他,他只是限定将要建立的目录的某种模式。sys_mkdir 函数首先调用 path_lookup("/dev", LOOKUP_PARENT, &nd);来对路径进行查找,其中 nd 为 struct nameidata nd 声明的变量。在接下来的叙述中,因为函数调用关系的繁琐,为了突出过程主线,将不再严格按照函数的调用关系来进行描述。

path_lookup 发现 "/dev" 是以 "/" 开头,所以他从当前进程的根目录开始往下查找,具体代码如下:



nd->mnt = mntget(current->fs->rootmnt);
nd->dentry = dget(current->fs->root);

记得在 init_mount_tree() 函数的后半段曾将新建立的 VFS 根目录相关信息记录在了 init_task 进程的进程数据块中,那么在这个场景里,nd->mnt 便指向了图 3 中 mnt 变量,nd->dentry 便指向了图 3 中的 dentry 变量。

然后调用函数 path_walk 接着往下查找,找到最后通过变量 nd 返回的信息是 nd.last.name="dev",nd.last.len=3,nd.last_type=LAST_NORM,至于 nd 中 mnt 和 dentry 成员,在这个场景里还是前面配置的值,并无变化。这样一圈下来,只是用 nd 记录下相关信息,实际的目录建立工作并没有真正展开,但是前面所做的工作却为接下来建立新的节点收集了必要的信息。

好,到此为止真正建立新目录节点的工作将会展开,这是由函数 lookup_create 来完成的,调用这个函数时会传入两个参数:lookup_create(&nd, 1);其中参数 nd 便是前面提到的变量,参数1表明要建立一个新目录。

这 里的大体过程是:新分配了一个 struct dentry 结构的内存空间,用于记录 dev 目录所对应的信息,该dentry 结构将会挂接到其父目录中,也就是图 3 中 "/" 目录对应的 dentry 结构中,由链表实现这一关系。接下来会再分配一个 struct inode 结构。Inode 中的 i_sb 和 dentry 中的 d_sb 分别都指向图 3 中的 sb,这样看来,在同一文档系统下建立新的目录时并无需重新分配一个终极块结构,因为毕竟他们都属于同一文档系统,因此一个文档系统只对应一个终极块。

这 样,当调用 sys_mkdir 成功地在 VFS 的目录树中新建立一个目录 "/dev" 之后,在图 3 的基础上,新的数据结构之间的关系便如图 4 所示。图 4 中颜色较深的两个矩形块 new_inode 和 new_entry 便是在sys_mkdir() 函数中新分配的内存结构,至于图中的 mnt,sb,dentry,inode 等结构,仍为图 3 中相应的数据结构,其相互之间的链接关系不变(图中为避免过多的链接曲线,忽略了一些链接关系,如 mnt 和 sb,dentry之间的链接,读者可在图 3 的基础上参看图 4)。

需要强调一点的是,既然 rootfs 文档系统被 mount 到了 VFS 树上,那么他在 sys_mkdir 的过程中必然会参和进来,事实上在整个过程中,rootfs 文档系统中的 ramfs_mkdir、ramfs_lookup 等函数都曾被调用过。

图 4: 在 VFS 树中新建一目录 "dev"
图 4: 在 VFS 树中新建一目录

6. 在 VFS 树中挂载文档系统
在本节中,将描述在 VFS 的目录树中向其中某个目录(安装点 mount point)上挂载(mount)一个文档系统的过程。

这 一过程可简单描述为:将某一设备(dev_name)上某一文档系统(file_system_type)安装到VFS目录树上的某一安装点 (dir_name)。他要解决的问题是:将对 VFS 目录树中某一目录的操作转化为具体安装到其上的实际文档系统的对应操作。比如说,假如将 hda2 上的根文档系统(假设文档系统类型为 ext2)安装到了前一节中新建立的 "/dev" 目录上(此时,"/dev" 目录就成为了安装点),那么安装成功之后应达到这样的目的,即:对 VFS 文档系统的 "/dev" 目录执行 "ls" 指令,该条指令应能列出 hda2 上 ext2 文档系统的根目录下任何的目录和文档。很显然,这里的关键是如何将对 VFS 树中 "/dev" 的目录操作指令转化为安装在其上的 ext2 这一实际文档系统中的相应指令。所以,接下来的叙述将抓住如何转化这一核心问题。在叙述之前,读者不妨自己设想一下 Linux 系统会如何解决这一问题。记住:对目录或文档的操作将最终由目录或文档所对应的 inode 结构中的 i_op 和 i_fop 所指向的函数表中对应的函数来执行。所以,不管最终解决方案如何,都能够设想必然要通过将对 "/dev" 目录所对应的 inode 中 i_op 和 i_fop 的调用转换到 hda2 上根文档系统 ext2 中根目录所对应的 inode 中 i_op 和 i_fop 的操作。

初始过程由 sys_mount() 系统调用函数发起,该函数原型声明如下:



asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
unsigned long flags, void * data);

其中,参数 char *type 为标识将要安装的文档系统类型字符串,对于 ext2 文档系统而言,就是"ext2"。参数 flags 为安装时的模式标识数,和接下来的 data 参数相同,本文不将其做为重点。

为了帮助读者更好地理解这一过程,笔者用一个具体的例子来说明:我们准备将来自主硬盘第 2 分区(hda2)上的 ext2 文档系统安装到前面创建的 "/dev" 目录中。那么对于 sys_mount() 函数的调用便具体为:

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!