Chinaunix首页 | 论坛 | 博客
  • 博客访问: 123079
  • 博文数量: 50
  • 博客积分: 125
  • 博客等级: 入伍新兵
  • 技术积分: 255
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-20 12:01
文章分类

全部博文(50)

文章存档

2013年(7)

2012年(43)

我的朋友

分类:

2012-11-08 09:48:14

原文地址:linux kernel 文件系统3 作者:BENNYSNAKE

3.2.              安装连接件 vfsmount

“安装”一个文件系统涉及“被安装设备”和“安装点”两个部分,安装的过程就是把“安装点”和“被安装设备”关联起来,这是通过一个“安装连接件”结构 vfsmount来完成的。

vfsmount 将“安装点”dentry 和“被安装设备”的根目录节点 dentry 关联起来。

每安装一次文件系统,会导致:

1、 创建一个 vfsmount

2、 为“被安装设备”创建一个 super_block,并由具体的文件系统来设置这个 super_block。(我们在“注册文件系统”一节将再来分析这一步)

3、 为被安装设备的根目录节点创建 dentry

4、 为被安装设备的根目录节点创建 inode 并由 super_operations->read_inode() 来设置此 inode

5、  super_block 与“被安装设备“根目录节点 dentry 关联起来

6、  vfsmount 与“被安装设备”的根目录节点 dentry 关联起来

在内核将根设备安装到“根安装点”上后,内存中有如下结构关系:



现在假设我们在 /mnt/win 下安装了 /dev/sda1 /dev/sda1 下有 dir1,然后又在 dir1 下安装了 /dev/sda2,那么内存中就有了如下的结构关系




4.   注册文件系统

前面说了,在安装一个文件系统的时候,需要为“被安装设备”创建一个 super_block,并设置它。

如果从源码追寻这个创建和设置 super_block 的过程,就引出了“注册文件系统”的概念。

实际上,在安装一个文件系统之前,还需要有一个注册文件系统的步骤,否则内核就因为不认识该文件系统而无法完成安装。

通过register_filesystem() ,将一个“文件系统类型”结构 file_system_type注册到内核中一个全局的链表file_systems 上。

struct file_system_type {

            
const char *name;
            
int fs_flags;
            
struct super_block *(*read_super) (struct super_block *void *int);
            
struct module *owner;
            
struct file_system_type * next;
            
struct list_head fs_supers;
};

int register_filesystem(struct file_system_type * fs)
{
            
int res = 0;
            
struct file_system_type ** p;

            
if (!fs)
                        
return -EINVAL;

            
if (fs->next)
                        
return -EBUSY;

             INIT_LIST_HEAD(
&fs->fs_supers);
            write_lock(
&file_systems_lock);
            p 
= find_filesystem(fs->name);

            
if (*p)
                        res 
= -EBUSY;
            
else
                        
*= fs;

             write_unlock(
&file_systems_lock);
            
return res;
}


这个结构中最关键的就是 read_super() 这个函数指针,它就是用于创建并设置 super_block 的目的的。

因为安装一个文件系统的关键一步就是要为“被安装设备”创建和设置一个 super_block,而不同的具体的文件系统的 super_block 有自己特定的信息,因此要求具体的文件系统首先向内核注册,并提供 read_super() 的实现。

5.   根据路径名寻找目标节点的 dentry

下面来研究文件系统中的一个非常关键的操作:根据路径名寻找目标节点的 dentry

例如要打开 /mnt/win/dir1/abc 这个文件,就是根据这个路径,找到目标节点 ‘abc’ 对应的 dentry ,进而得到 inode 的过程。

5.1.              寻找过程

寻找过程大致如下:

1、 首先找到根文件系统的根目录节点 dentry  inode

2、 由这个 inode 提供的操作接口 i_op->lookup(),找到下一层节点 ‘mnt’  dentry  inode

3、  ‘mnt’  inode 找到 ‘win’  dentry  inode

4、 由于 ‘win’ 是个“安装点”,因此需要找到“被安装设备”/dev/sda1 根目录节点的 dentry  inode,只要找到 vfsmount B,就可以完成这个任务。

5、 然后由 /dev/sda1 根目录节点的 inode 负责找到下一层节点 ‘dir1’  dentry  inode

6、 由于 dir1 是个“安装点”,因此需要借助 vfsmount C 找到 /dev/sda2 的根目录节点 dentry  inode

7、 最后由这个 inode 负责找到 ‘abc’  dentry  inode

可以看到,整个寻找过程是一个递归的过程。

完成寻找后,内存中结构如下,其中红色线条是寻找目标节点的路径


现在有两个问题:

1、在寻找过程的第一步,如何得到“根文件系统”的根目录节点的 dentry

答案是这个 dentry 是被保存在进程的 task_struct 中的。后面分析进程与文件系统关系的时候再说这个。

2、如何寻找 vfsmount B  C

这是接下来要分析的。

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