王朝百科
分享
 
 
 

虚拟文件系统

王朝百科·作者佚名  2010-01-16  
宽屏版  字体: |||超大  

虚拟文件系统 Virtual File Systems

虚拟文件系统(VFS)是由Sun microsystems公司在定义网络文件系统(NFS)时创造的。它是一种用于网络环境的分布式文件系统,是允许和操作系统使用不同的文件系统实现的接口。

虚拟文件系统(VFS)是物理文件系统与服务之间的一个接口层,它对Linux的每个文件系统的所有细节进行抽象,使得不同的文件系统在Linux核心以及系统中运行的其他进程看来,都是相同的。严格说来,VFS并不是一种实际的文件系统。它只存在于内存中,不存在于任何外存空间。VFS在系统启动时建立,在系统关闭时消亡。

VFS使Linux同时安装、支持许多不同类型的文件系统成为可能。VFS拥有关于各种特殊文件系统的公共界面,如超级块、inode、文件操作函数入口等。实际文件系统的细节,统一由VFS的公共界面来索引,它们对系统核心和用户进程来说是透明的。

VFS的功能包括:纪录可用的文件系统的类型;将设备同对应的文件系统联系起来;处理一些面向文件的通用操作;涉及到针对文件系统的操作时,VFS把它们影射到与控制文件、目录以及inode相关的物理文件系统。

当某个进程发布了一个面向文件的系统调用时,核心将调用VFS中相应的函数,这个函数处理一些与物理结构无关的操作,并且把它重定向为真实文件系统中相应的函数调用,后者则用来处理那些与物理结构相关的操作。

VFS与实际文件系统的封装关系如下图所示:

VFS

MINIX FS

VFSinode缓存

VFS目录缓存

EXT FS

EXT2 FS

MSDS FS

缓冲存储

I/O设备驱动

图4 VFS与实际文件系统的封装关系

VFS的源代码集中在/usr/src/linux/fs目录下,关于它的数据结构的描述在文件/usr/src/lunux/include/linux/fs.h中。

3.1 VFS超级块

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:指向文件系统所需信息的指针。

3.2 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是否已经被写过,如果是则底层文件系统需要更新。

3.3 注册文件系统

用户可以通过两种途径向内核注册文件系统:一是在编译内核时确定可支持的文件系统类型,并在系统初始化时通过内嵌的函数调用在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()

name

owner

kem_mnt

next

*read_super()

name

owner

kem_mnt

next

*read_super()

name

owner

kem_mnt

next

图5

file_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;

//文件系统类型链表的后续指针。

};

3.4 安装文件系统

文件系统注册后便在设备上按一定格式建立文件系统,但是此时设备上的文件和节点都还不是可访问的,还不能按照一定的路径名访问其中特定的节点或文件。只有把它安装到文件系统中某个节点上,才能使设备上的文件和节点可被访问。因此注册了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对列,找到所需文件系统类型的数据结构。

3.5 卸载文件系统

超级用户卸载文件系统使用umount命令。

卸载过程必须检查文件系统及其超级块的状态。如果文件系统正被其他进程使用该文件系统就不能被卸载。如果文件系统的文件或目录正在使用,则VFS索引节点缓存中可能包含相应的VFS索引节点。检查代码在该缓存中,根据文件系统所在的设备标识符查找是否有来自该文件系统的VFS索引节点。如果有且使用计数大于0则说明该文件系统正在使用,不能被删除。如果文件系统的超级块为“脏”,即被修改,则应先将它写回到磁盘上。

文件系统允许在被删除后,对应的VFS超级块被释放,vfsmount数据结构从vfsmntlist链表中断开并被释放。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如何用java替换看不见的字符比如零宽空格​十六进制U+200B
 干货   2023-09-10
网页字号不能单数吗,网页字体大小为什么一般都是偶数
 干货   2023-09-06
java.lang.ArrayIndexOutOfBoundsException: 4096
 干货   2023-09-06
Noto Sans CJK SC字体下载地址
 干货   2023-08-30
window.navigator和navigator的区别是什么?
 干货   2023-08-23
js获取referer、useragent、浏览器语言
 干货   2023-08-23
oscache遇到404时会不会缓存?
 干货   2023-08-23
linux下用rm -rf *删除大量文件太慢怎么解决?
 干货   2023-08-08
刀郎新歌破世界纪录!
 娱乐   2023-08-01
js实现放大缩小页面
 干货   2023-07-31
生成式人工智能服务管理暂行办法
 百态   2023-07-31
英语学习:过去完成时The Past Perfect Tense举例说明
 干货   2023-07-31
Mysql常用sql命令语句整理
 干货   2023-07-30
科学家复活了46000年前的虫子
 探索   2023-07-29
英语学习:过去进行时The Past Continuous Tense举例说明
 干货   2023-07-28
meta name="applicable-device"告知页面适合哪种终端设备:PC端、移动端还是自适应
 干货   2023-07-28
只用css如何实现打字机特效?
 百态   2023-07-15
css怎么实现上下滚动
 干货   2023-06-28
canvas怎么画一个三角形?
 干货   2023-06-28
canvas怎么画一个椭圆形?
 干货   2023-06-28
canvas怎么画一个圆形?
 干货   2023-06-28
canvas怎么画一个正方形?
 干货   2023-06-28
中国河南省郑州市金水区蜘蛛爬虫ip大全
 干货   2023-06-22
javascript简易动态时间代码
 干货   2023-06-20
感谢员工的付出和激励的话怎么说?
 干货   2023-06-18
 
>>返回首页<<
 
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有