首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
Linux资讯 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>系统管理>内核技术>正文

解析Linux中的VFS文件系统机制

http://www.oklinux.cn  2005-01-01  来源: IBM DW  Ricard Chen   会员收藏  游客收藏  【 】 

1. 摘要
2. VFS 概述
3. 文件系统的注册
4. VFS 目录树的建立
5. VFS 下目录的建立
6. 在 VFS 树中挂载文件系统
7. 安装根文件系统
8. 结束语



4. VFS 目录树的建立

既然是树,所以根是其赖以存在的基础,本节阐述 Linux 在初始化阶段是如何建立根结点的,即 "/"目录。这其中会包括挂载 rootfs 文件系统到根目录 "/" 的具体过程。构造根目录的代码是在 init_mount_tree() 函数 (fs\namespace.c) 中。

首先,init_mount_tree() 函数会调用 do_kern_mount("rootfs", 0, "rootfs", NULL) 来挂载前面已经注册了的 rootfs 文件系统。这看起来似乎有点奇怪,因为根据前面的说法,似乎是应该先有挂载目录,然后再在其上挂载相应的文件系统,然而此时 VFS 似乎并没有建立其根目录。没关系,这是因为这里我们调用的是 do_kern_mount(),这个函数内部自然会创建我们最关心也是最关键的根目录(在 Linux 中,目录对应的数据结构是 struct dentry)。

在这个场景里,do_kern_mount() 做的工作主要是:

1)调用 alloc_vfsmnt() 函数在内存里申请了一块该类型的内存空间(struct vfsmount *mnt),并初始化其部分成员变量。

2) 调用 get_sb_nodev() 函数在内存中分配一个超级块结构 (struct super_block) sb,并初始化其部分成员变量,将成员 s_instances 插入到 rootfs 文件系统类型结构中的 fs_supers 指向的双向链表中。

3) 通过 rootfs 文件系统中的 read_super 函数指针调用 ramfs_read_super() 函数。还记得当初注册rootfs 文件系统时,其成员 read_super 指针指向了 ramfs_read_super() 函数,参见图2.

4) ramfs_read_super() 函数调用 ramfs_get_inode() 在内存中分配了一个 inode 结构 (struct inode) inode,并初始化其部分成员变量,其中比较重要的有 i_op、i_fop 和 i_sb:




inode->i_op = &ramfs_dir_inode_operations;
inode->i_fop = &dcache_dir_ops;
inode->i_sb = sb;

这使得将来通过文件系统调用对 VFS 发起的文件操作等指令将被 rootfs 文件系统中相应的函数接口所接管。


图3

5) ramfs_read_super() 函数在分配和初始化了 inode 结构之后,会调用 d_alloc_root() 函数来为 VFS的目录树建立起关键的根目录 (struct dentry)dentry,并将 dentry 中的 d_sb 指针指向 sb,d_inode 指针指向 inode。

6) 将 mnt 中的 mnt_sb 指针指向 sb,mnt_root 和 mnt_mountpoint 指针指向 dentry,而 mnt_parent指针则指向自身。

这样,当 do_kern_mount() 函数返回时,以上分配出来的各数据结构和 rootfs 文件系统的关系将如上图 3 所示。图中 mnt、sb、inode、dentry 结构块下方的数字表示它们在内存里被分配的先后顺序。限于篇幅的原因,各结构中只给出了部分成员变量,读者可以对照源代码根据图中所示按图索骥,以加深理解。

最后,init_mount_tree() 函数会为系统最开始的进程(即 init_task 进程)准备它的进程数据块中的namespace 域,主要目的是将 do_kern_mount() 函数中建立的 mnt 和 dentry 信息记录在了 init_task 进程的进程数据块中,这样所有以后从 init_task 进程 fork 出来的进程也都先天地继承了这一信息,在后面用sys_mkdir 在 VFS 中创建一个目录的过程中,我们可以看到这里为什么要这样做。为进程建立 namespace 的主要代码如下:




		namespace = kmalloc(sizeof(*namespace), GFP_KERNEL);
list_add(&mnt->mnt_list, &namespace->list);  //mnt is returned by do_kern_mount()
	namespace->root = mnt;
	init_task.namespace = namespace;
	for_each_task(p) {
		get_namespace(namespace);
		p->namespace = namespace;
	}

	set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
	set_fs_root(current->fs, namespace->root, namespace->root->mnt_root);
	

该段代码的最后两行便是将 do_kern_mount() 函数中建立的 mnt 和 dentry 信息记录在了当前进程的 fs结构中。

以上讲了一大堆数据结构的来历,其实最终目的不过是要在内存中建立一颗 VFS 目录树而已,更确切地说, init_mount_tree() 这个函数为 VFS 建立了根目录 "/",而一旦有了根,那么这棵数就可以发展壮大,比如可以通过系统调用 sys_mkdir 在这棵树上建立新的叶子节点等,所以系统设计者又将 rootfs 文件系统挂载到了这棵树的根目录上。关于 rootfs 这个文件系统,读者如果看一下前面图 2 中它的file_system_type 结构,会发现它的一个成员函数指针 read_super 指向的是 ramfs_read_super,单从这个函数名称中的 ramfs,读者大概能猜测出这个文件所涉及的文件操作都是针对内存中的数据对象,事实上也的确如此。从另一个角度而言,因为 VFS 本身就是内存中的一个数据对象,所以在其上的操作仅限于内存,那也是非常合乎逻辑的事。在接下来的章节中,我们会用一个具体的例子来讨论如何利用 rootfs所提供的函树为 VFS 增加一个新的目录节点。

VFS 中各目录的主要用途是为以后挂载文件系统提供挂载点。所以真正的文件操作还是要通过挂载后的文件系统提供的功能接口来进行。

共5页: 上一页 [1] 2 [3] [4] [5] 下一页

上一篇:2.4和2.6上的Web服务   下一篇:Linux下PCI设备驱动程序开发基本框架


收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·2.4和2.6上的Web服务
·Linux下PCI设备驱动程序开发基本框架
·一个Linux爱好者的2.6.内核编译过程
·升级内核,感受Linux新时空
·Linux 2.6内核新特性比较
·谈谈GCC4.0几个值得关注的新特性
·开发人员眼中的Linux 2.6内核
·
·揭开Linux系统内核调试器的神秘面纱
·向Alan Cox——Linux内核的维护者致敬
·深入浅出 Linux设备驱动编程内核模块
·Linux 2.6内核如何武装Fedora Core 2
·高手风范 Linux操作系统内核编码风格
·揭秘Linux内核调试器之内幕
·高手进阶 更换Fedora Core 6的内核
·Linux系统可卸载内核模块完全指南(上)
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·学习园地:Linux系统内核中判断大小的
·系统编译:如何给Make命令来传递参数
·Linux 2.6内核中sysfs文件系统简单概述
·Fedora 8 Linux系统的内核配置注意事项
·升级Linux内核的一般步骤方法
·Linux发行版知识普及:三个版本的CPUID
·编译安装Virtualbox驱动模块
· Linux系统的内核解读入门
·新手学堂 Linux系统的内核解读入门
·Linux系统内核中网络参数的意义及其应
·走向Linux系统高手之路 内核编译过程解
·Linux系统中安装内核的方法详细介绍
  阅读排行
· 深入理解LINUX内核中文版下载地址
·基于S3C44B0微处理器的uClinux内核引导
·Kernel command using Linux system ca
·Linux 2.6内核如何武装Fedora Core 2
·Process priority and control on AIX
·Linux操作系统的内核编译内幕详解
·推荐:Linux用户态与内核态的交互
·通过振动向Linux ThinkPad传输信息
·Linux操作系统源代码详细分析(二)
·Linux系统内核接收以太帧的处理程序
·Linux and symmetric multiprocessing
·主流嵌入式Linux系统下GUI解决方案
·揭秘Linux内核调试器之内幕
·用命令行加挂Linux的文件系统简介
·Linux内核和核心OS组件的测试与分析
网摘收藏: