文件系统的注册和安装是两个不同的概念。注册是指向内核生命自己可以被支持,但是可以被支持与能够被访问是两码事,仅仅只是一个文件系统,我们是不可能访问它的。为了能够被访问,文件系统还必须被安装到系统中,也就是mount操作。

文件系统注册

如果文件系统是作为可加载的模块,则在模块加载的时候进程注册。比如说,isofs文件系统编译为一个模块时,在模块加载的过程中,会调用初始化函数init_iso9660_fs(),该函数使用register_filesystem将自己的file_system_type对象iso9660_fs_type注册到内核里。

如果文件系统不是可加载的模块,比如说sysfs,同样必须使用register_filesystem()将自己的file_system_type对象注册到内核里。register_filesystem()的任务就是将指定文件系统的file_system_type对象向内核注册,所以已注册文件系统的file_system_type对象形成一个链表,链表头是fs/filesystems.c文件中定义的全局变量file_systems,

static struct file_system_type *file_systems;
static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
    struct file_system_type **p;
    for (p=&file_systems; *p; p=&(*p)->next)
        if (strlen((*p)->name) == len &&
            strncmp((*p)->name, name, len) == 0)
            break;
    return p;
}

int register_filesystem(struct file_system_type * fs)
{
    int res = 0;
    struct file_system_type ** p;
    BUG_ON(strchr(fs->name, '.'));
    if (fs->next)
        return -EBUSY;
    write_lock(&file_systems_lock);
    p = find_filesystem(fs->name, strlen(fs->name));
    if (*p)
        res = -EBUSY;
    else
        *p = fs;
    write_unlock(&file_systems_lock);
    return res;
}

int unregister_filesystem(struct file_system_type * fs)
{
    struct file_system_type ** tmp;
    write_lock(&file_systems_lock);
    tmp = &file_systems;
    while (*tmp) {
        if (fs == *tmp) {
            *tmp = fs->next;
            fs->next = NULL;
            write_unlock(&file_systems_lock);
            synchronize_rcu();
            return 0;
        }
        tmp = &(*tmp)->next;
    }
    write_unlock(&file_systems_lock);
    return -EINVAL;
}

文件系统安装

一个文件系统只有安装后才能够被访问。除了根文件系统系统是在内核引导阶段就被安装之外,其他文件或者由初始化脚本安装,或者由用户使用mount命令安装在已安装文件系统的某一个目录上。

每个文件系统都有自己的根目录,安装文件系统的那个目录成为安装点,已安装文件系统的根目录隐藏了安装点目录原来的内容。

在众多的文件系统中,之所以单独介绍rootfs的注册和安装,是因为它对于VFS的重要性。rootfs可以说是VFS存在的基础,它为其他文件系统提供一个作为初始安装点的空目录。

  • 注册rootfs

init_rootfsinit/do_mounts.c文件中定义,他仅是通过调用register_filesystem()将自己的file_system_type对象rootfs_fs_type注册到内核中。其定义如下所示:

static struct file_system_type rootfs_fs_type = {
    .name           = "rootfs",
    .mount          = rootfs_mount,
    .kill_sb        = kill_litter_super,
};
  • 安装rootfs

init_mount_treefs/namespace.c文件中定义,主要完成一下工作:

  • 调用vfs_kern_mount来安装rootfs;
  • 切换当前进程的根目录和当前目录为“/”.