文件系统的注册和安装
使用文件系统前必须对文件系统进行注册和安装,下面分别对这两种行为做简要介绍。
文件系统的注册
VFS要想能将自己定义的接口映射到实际文件系统的专用方法上,必须能够让内核识别实际的文件系统,实际文件系统通过将代表自身属性的文件类型对象(file_system_type)注册(通过register_filesystem()函数)到内核,也就是挂到内核中的文件系统类型链表上,来达到使文件系统能被内核识别的目的。反过来,内核也正是通过这条链表来跟踪系统所支持的各种文件系统。
我们简要分析一下注册步骤:
struct file_system_type {
const char*name; /*文件系统的名字*/
intfs_flags; /*文件系统类型标志*/
/*下面的函数用来从磁盘中读取超级块*/
struct super_block*(*read_super) (struct file_system_type*, int,
const char *, void *);
struct file_system_type *next; /*链表中下一个文件系统类型*/
structlist_headfs_supers; /*超级块对象链表*/
};
其中最重要的一项是read_super()函数,它用来从磁盘上读取超级块,并且当文件系统被装载时,在内存中组装超级块对象。要实现一个文件系统首先需要实现的结构体便是file_system_type结构体。
注册文件系统只能保证文件系统能被系统识别,但此刻文件系统尚不能使用,因为它还没有被安装到特定的安装点上。所以在使用文件系统前必须将文件系统安装到安装点上。
文件系统被实际安装时,将在安装点创建一个vfsmount结构体。该结构体用来代表文件系统的实例——换句话说,代表一个安装点。
vfsmount结构被定义在<linux/mount.h>中,下面是具体结构
―――――――――――――――――――――――――――――――――――――――
struct vfsmount
{
structlist_headmnt_hash; /*哈希表*/
structvfsmount*mnt_parent; /*父文件系统*/
struct dentry*mnt_mountpoint; /*安装点的目录项对象*/
struct dentry*mnt_root; /*该文件系统的根目录项对象*/
structsuper_block*mnt_sb; /*该文件系统的超级块*/
structlist_headmnt_mounts; /*子文件系统链表*/
structlist_headmnt_child; /*和父文件系统相关的子文件系统*/
atomic_tmnt_count; /*使用计数*/
intmnt_flags; /*安装标志*/
char*mnt_devname; /*设备文件名字*/
structlist_headmnt_list; /*描述符链表*/
};
――――――――――――――――――――――――――――――――――――――
文件系统如果仅仅注册,那么还不能被用户使用。要想使用它还必须将文件系统安装到特定的安装点后才能工作。下面我们接着介绍文件系统的安装[7][7]过程。
安装过程
用户在用户空间调用mount()命令——指定安装点、安装的设备、安装类型等——安装指定的文件系统到指定目录。mount()系统调用在内核中的实现函数为sys_mount(),该函数调用的主要例程是do_mount(),它会取得安装点的目录项对象,然后调用do_add_mount()例程。
do_add_mount()函数主要做的是首先使用do_kern_mount()函数创建一个安装点,再使用graft_tree()将安装点作为叶子与根目录树挂接起来。
整个安装过程中最核心的函数就是do_kern_mount()了,为了创建一个新安装点(vfsmount),该函数需要做以下几件事情:
l 检查安装设备的权利,只有root权限才有能力执行该操作。
l Get_fs_type()在文件链表中取得相应文件系统类型(注册时被填加到链表中)。
l Alloc_vfsmnt()调用slab分配器为vfsmount结构体分配存储空间,并把它的地址存放在mnt局部变量中。
l 初始化mnt->mnt_devname域
l 分配新的超级块并初始化它。do_kern_mount()检查file_system_type描述符中的标志以决定如何进行如下操作:根据文件系统的标志位,选择相应的方法读取超级块(比如对Ext2,romfs这类文件系统调用get_sb_dev();对于这种没有实际设备的虚拟文件系统如 ramfs调用get_sb_nodev())——读取超级块最终要使用文件系统类型中的read_super方法。
安装过程做的最主要工作是创建安装点对象,挂接给定文件系统到根文件系统的指定接点下,然后初始化超级快对象,从而获得文件系统基本信息和相关操作方法(比如读取系统中某个inode的方法)。
总而言之,注册过程是告之内核给定文件系统存在于系统内;而安装是请求内核对给定文件系统进行支持,使文件系统真正可用。