您的位置:首页 > 其它

如何实现一个文件系统(三)

2013-11-07 21:30 543 查看
文件系统的注册和安装

使用文件系统前必须对文件系统进行注册和安装,下面分别对这两种行为做简要介绍。

文件系统的注册

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的方法)。



总而言之,注册过程是告之内核给定文件系统存在于系统内;而安装是请求内核对给定文件系统进行支持,使文件系统真正可用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: