1.VFS 概述
VFS 是一种软件机制,也许称它为 Linux 的文件系统管理者更确切点,与它相关的数据结构只存在于物理内存当中。所以在每次系统初始化期间,Linux 都首先要在内存当中构造一棵 VFS 的目录树(在 Linux的源代码里称之为 namespace),实际上便是在内存中建立相应的数据结构。VFS 目录树在 Linux 的文件系统模块中是个很重要的概念,不要将其与实际文件系统目录树混淆,VFS 中的各目录其主要用途是用来提供实际文件系统的挂载点。
2. 文件系统的注册
这里的文件系统是指可能会被挂载到目录树中的各个实际文件系统。
所谓实际文件系统,即是指VFS 中的实际操作最终要通过它们来完成而已,并不意味着它们一定要存在于某种特定的存储设备上。 例如:"rootfs"、"proc"、"ext2"、"sockfs"
数据结构
在 Linux 源代码中,每种实际的文件系统用以下的数据结构表示。
static struct file_system_type *file_systems;
struct file_system_type {
const char *name; /*文件系统的名字*/
int fs_flags; /*文件系统类型标志*/
struct super_block *(*get_sb) (struct file_system_type *, int,
const char *, void *); //获取超级块
void (*kill_sb) (struct super_block *); //阻止超级块
struct module *owner; //拥有模块
struct file_system_type * next; /*链表中下一个文件系统类型*/
struct list_head fs_supers; /*超级块对象列表*/
};
注册过程实际上将表示各实际文件系统的 struct file_system_type 数据结构的实例化,然后形成一个链表,内核中用一个名为 file_systems 的全局变量来指向该链表的表头
static struct file_system_type ramfs_fs_type = {
.name = "ramfs",
.get_sb = ramfs_get_sb,
.kill_sb = kill_litter_super,
};
static struct file_system_type rootfs_fs_type = {
.name = "rootfs",
.get_sb = rootfs_get_sb,
.kill_sb = kill_litter_super,
};
每个文件系统必须通过register_filesystem函数将自己的file_system_type挂接到file_systems这个全局变量上
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
*p = fs;
write_unlock(&file_systems_lock);
return res;
}
static struct file_system_type **find_filesystem(const char *name)
{
struct file_system_type **p;
for (p=&file_systems; *p; p=&(*p)->next)
if (strcmp((*p)->name,name) == 0)
break;
return p;
}
VFS描述文件系统使用超级块和inode 的方式,所谓超级块就是对所有文件系统的管理机构,每种文件系统都要把自己的信息挂到super_blocks这么一个全局链表上。
然后调用kern_mount函数把自己的文件相关操作函数集合表挂到super_blocks上。每种文件系统类型的读超级块的例程(get_sb)必须由自己实现。