虚拟档案系统


虚拟档案系统

文章插图
虚拟档案系统【虚拟档案系统】虚拟档案系统(VFS)是由Sun microsystems公司在定义网路档案系统(NFS)时创造的 。它是一种用于网路环境的分散式档案系统,是允许和作业系统使用不同的档案系统实现的接口 。虚拟档案系统(VFS)是物理档案系统与服务之间的一个接口层,它对Linux的每个档案系统的所有细节进行抽象,使得不同的档案系统在Linux核心以及系统中运行的其他进程看来,都是相同的 。严格说来,VFS并不是一种实际的档案系统 。它只存在于记忆体中,不存在于任何外存空间 。VFS在系统启动时建立,在系统关闭时消亡 。
基本介绍中文名:虚拟档案系统
外文名: Virtual File Systems
领域:计算机作业系统
简介虚拟档案系统 Virtual File Systems(VFS)Linux 是近年来发展起来的一种新型的作业系统,其最重要的特徵之一就是支持多种档案系统,使其更加灵活,从而与许多其它的作业系统共存 。Linux支持ext,ext2,xia,minix,umsdos,msdes,fat32 ,ntfs,proc,stub,ncp,hpfs,affs 以及 ufs 等多种档案系统 。为了实现这一目的,Linux 对所有的档案系统採用统一的档案界面,用户通过档案的操作界面来实现对不同档案系统的操作 。对于用户来说,我们不要去关心不同档案系统的具体操作过程,而只是对一个虚拟的档案操作界面来进行操作,这个操作界面就是 Linux 的虚拟档案系统(VFS )。形象地说,Linux 的核心好象一个 PC 机的母板,VFS 就是上面的一个插槽,具体的档案系统就是一块块的接 121 卡 。因此,每一个档案系统之间互不干扰,而只是调用相应的程式来实现其功能 。在 Linux 的核心档案中,VFS 和具体的档案系统程式都放在 Linux\FS 中,其中每一种档案系统对应一个子目录,另外还有一些共用的 VFS 程式 。在具体的实现上,每个档案系统都有自己的档案操作数据结构file—operations 。所以,VFS 作为 ILinux核心中的一个软体层,用于给用户空间的程式提供档案系统接口,同时也提供了核心中的一个抽象功能,允许不同的档案系统很好地共存 。VFS 使 Linux 同时安装、支持许多不同类型的档案系统成为可能 。VFS 拥有关于各种特殊档案系统的公共界面,如超级块、inode、档案操作函式入口等 。实际档案系统的细节,统一由 VFS 的公共界面来索引,它们对系统核心和用户进程来说是透明的 。Linux虚拟档案系统简介虚拟"虚拟"二字主要有两层含义:1, 在同一个目录结构中, 可以挂载着若干种不同的档案系统. VFS隐藏了它们的实现细节, 为使用者提供统一的接口;2, 目录结构本身并不是绝对的, 每个进程可能会看到不一样的目录结构. 目录结构是由"地址空间(namespace)"来描述的, 不同的进程可能拥有不同的namespace, 不同的namespace可能有着不同的目录结构(因为它们可能挂载了不同的档案系统) 。Inode含义: 索引节点, 对应设备上存放的一个档案 。创建: 1)在超级块被载入时, 作为根的inode一併被载入; 2)通过mknod调用创新新的索引节点; 3)在寻找档案路径的过程中, 从设备中读取, 并初始化(跟super_block一样, inode结构中一部分信息是保存在设备中的, 一部分则是在内在中初始化的) 。函式: i_op, 索引节点函式集, 主要包含对子inode的创建, 删除等操作. f_op, 档案函式集, 主要包含对本inode的读写等操作. 在inode被创建后, 1)如果是特殊档案, 则根据对应档案的类型(包括块设备, 字元设备, fifo, 等等)赋予特定的函式集(并不直接与设备和档案系统类型相关); 2)否则, 对应的档案系统类型会提供相应的函式集, 并且目录和档案函式集很可能不同 。操作已打开的档案VFS的使用者是进程(用户访问档案系统总是需要启动进程). 描述进程的task_struct结构中files指针指向了一个files_struct结构, 后者描述了进程已打开的档案集合 。files_struct结构维护了一个已打开档案所对应的file结构的指针数组, 数组下标被用作用户程式操作已打开档案的句柄(通常称作fd). files_struct还维护着已使用的fd点阵图, 以便在需要打开档案时, 为其分配一个未使用的fd 。详细见参考文献 。功能VFS的功能包括:纪录可用的档案系统的类型;将设备同对应的档案系统联繫起来;处理一些面向档案的通用操作;涉及到针对档案系统的操作时,VFS把它们影射到与控制档案、目录以及inode相关的物理档案系统 。当某个进程发布了一个面向档案的系统调用时,核心将调用VFS中相应的函式,这个函式处理一些与物理结构无关的操作,并且把它重定向为真实档案系统中相应的函式调用,后者则用来处理那些与物理结构相关的操作 。VFS与实际档案系统的封装关係如下图所示:VFSMINIX FSVFSinode快取VFS目录快取EXT FSEXT2 FSMSDS FS缓冲存储I/O设备驱动图4 VFS与实际档案系统的封装关係VFS的原始码集中在/usr/src/linux/fs目录下,关于它的数据结构的描述在档案/usr/src/lunux/include/linux/fs.h中 。超级块VFS使用了与EXT2档案系统类似的方式:超级块和索引节点inode描述档案系统 。VFS超级块是各种逻辑档案系统在安装时建立的,并在这些档案系统卸载时自动删除,它只存在于记忆体中 。VFS中保存了系统中挂接的档案系统的鍊表以及这些档案系统对应的VFS超级块 。系统启动后所有被初始化的档案系统都要向VFS登记 。每个已安装的档案系统由一个VFS 超块表示,它包含如下信息:⑴Device:表示档案系统所在块设备的设备标誌符 。例如系统中第一个IDE 硬碟的设备标誌符为0x301 。⑵Inode pointers:这个mounted inode指针指向档案系统中第一个inode 。而covered inode指针指向此档案系统安装目录的inode 。根档案系统的VFS超块不包含covered指针 。⑶Blocksize:以位元组记数的档案系统块大小,如1024 位元组 。⑷Superblock operations:指向此档案系统一组超块操纵例程的指针 。这些例程被VFS 用来读写inode和超块 。⑸File System type:这是一个指向已安装档案系统的file_system_type结构的指针 。⑹File System specific:指向档案系统所需信息的指针 。其它相关The VFS Inode和EXT2 档案系统相同,VFS 中的每个档案、目录等都用且只用一个VFS inode表示 。每个VFS inode 中的信息通过档案系统相关例程从底层档案系统中得到 。VFS inode仅存在于核心记忆体并且保存只要对系统有用,它们就会被保存在在VFS inode cache中 。每个VFS inode包含下列域:⑴device:包含此档案或此VFS inode 代表的任何东西的设备的设备标誌符 。⑵inode number:档案系统中唯一的inode号 。在虚拟档案系统中device和inode号的组合是唯一的 。⑶mode:和EXT2 中的相同, 表示此VFS inode 的存取许可权 。⑷user ids:所有者的标誌符 。⑸times:VFS inode 创建、修改和写入时间 。⑹block size:以位元组计算的档案块大小,如1024 位元组 。⑺inode operations:指向一组例程地址的指针 。这些例程和档案系统相关且对此inode 执行操作,如截断此inode表示的档案 。⑻count:使用此VFS inode 的系统部件数 。一个count为0 的inode可以被自由的丢弃或重新使用 。⑼lock: 用来对某个VFS inode加锁,如用于读取档案系统时 。⑽dirty:表示这个VFS inode是否已经被写过,如果是则底层档案系统需要更新 。注册档案系统用户可以通过两种途径向核心注册档案系统:一是在编译核心时确定可支持的档案系统类型,并在系统初始化时通过内嵌的函式调用在VFS中进行注册;二是把某个档案系统当作一个模组,利用模组的载入和卸载特徵向注册表登记类型或从注册表注销 。档案系统类型的注册函式为:int register filesystem (struct file_system_type *fs)每个档案系统都有一个初始化例程,档案系统通过它在VFS中进行注册,即填写file_system_type数据结构 。该结构包含了档案系统的名称及一个指向对应VFS超级块读取例程的地址 。所有已注册档案系统的file_system_type结构形成了一个注册鍊表,如下图所示:file_system_type file_system_type file_system_type*read_super()nameownerkem_mntnext*read_super()nameownerkem_mnt next*read_super()nameownerkem_mntnext图5file_system_type的数据结构在include/linux/fs.h中定义如下:struct file_system_type {const char *name;//档案系统的类型名,如EXT2 。这些名称出现在Linux中的/proc/filesystems中且必须是唯一的 。int fs_flags;//fs_flags的取值可能有很多种 。例如,档案系统标识FS_REQUIRES_DEV表示档案系统只能载入在一个块设备上;FS_SINGLE表示档案系统只能有一个超级块;FS_NOMOUNT表示档案系统不能安装在用户空间上 。struct super_block *(*read_super) (struct super_block *, void *, int);//read_super所指的函式用于读出该档案系统在外存的超级块 。struct module *owner;//如果实现该档案系统的程式段是由module动态载入的,则指向该module;如果实现该档案系统的程式段是在核心编译时生成的,则owner = NULL 。struct vfsmount * kem_mnt;//只为标识为FS_SINGLE的档案系统使用(For kernel mount)struct file_system_type * next;//档案系统类型鍊表的后续指针 。};安装档案系统档案系统注册后便在设备上按一定格式建立档案系统,但是此时设备上的档案和节点都还不是可访问的,还不能按照一定的路径名访问其中特定的节点或档案 。只有把它安装到档案系统中某个节点上,才能使设备上的档案和节点可被访问 。因此注册了wej系统只代表Linux系统支持这种档案系统的套用,要真正使用该档案系统还必须安装它 。档案系统的安装必须调用mount命令,把其他子系统安装到已经存在于档案系统的空闲节点上 。该命令使用系统的mount()调用:asmlinkage ling sys_mount(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data)其中dev_name是要安装的档案系统的磁碟分区的路径名,如/dev/hda5 。参数dir_name是要安装的档案系统的目录名;type指定磁碟分区上的档案系统类型;flags指定该档案系统如何被安装;data是指向任意的信息结构的指针,其内容依赖于被安装的特定档案系统类型 。使用mount命令后,VFS通过file_systems在file_system_type鍊表中根据指定的档案系统名称搜寻档案系统类型信息 。而函式get_fs_type()根据具体档案系统的类型名在核心中找到相应的file_system_type结构: struct file_system_type *get_fs_type(const char *name){struct file_system_type *fs;read_lock(&file_systems_lock);fs = *(find_filesystem(name));if (!fs && (request_module(name) == 0)) {read_lock(&file_systems_lock);fs = *(find_filesystem(name));if (fs && !try_inc_mod_count(fs->owner))fs = NULL;read_unlock(&file_systems_lock);}return fs;}其中函式find_filesystem(name)扫描file_system对列,找到所需档案系统类型的数据结构 。卸载档案系统超级用户卸载档案系统使用umount命令 。卸载过程必须检查档案系统及其超级块的状态 。如果档案系统正被其他进程使用该档案系统就不能被卸载 。如果档案系统的档案或目录正在使用,则VFS索引节点快取中可能包含相应的VFS索引节点 。检查代码在该快取中,根据档案系统所在的设备标识符查找是否有来自该档案系统的VFS索引节点 。如果有且使用计数大于0则说明该档案系统正在使用,不能被删除 。如果档案系统的超级块为“髒”,即被修改,则应先将它写回到磁碟上 。档案系统允许在被删除后,对应的VFS超级块被释放,vfsmount数据结构从vfsmntlist鍊表中断开并被释放 。