VFS的作用:为文件系统提供通用的接口。

通用文件模型:common file model。特殊文件系统需要将它的物理结构转换成通用文件模型。

common file model包括以下几个重要对象:

super block:存储关于文件系统的信息。

inode:存储一个特定文件的信息。每个inode都有一个inode号,唯一描述一个文件。

file:存储文件与进程交互的信息。

dentry:目录项,目录的每个组成部分。例如,/home/xxx/yyy.c中,/,home,xxx,yyy.c都是目录项。目录项也是文件,因此也有inode。

● struct super_block:

所有的super block对象都被链接在一个双向链表,这个链表的第一个节点由super_blocks变量指向,s_list成员指向与自己相邻的成员。

s_fs_info成员指向与特定文件相关的信息(私有信息,和common file model无关)。例如该super block 对象指向一个ext2文件系统,则s_fs_info指向ext2_sb_info结构。

s_dirty反应super block对象是否被修改。

s_op:对super block的操作,它是struct super_operations类型。每种文件系统都可以定义自己的super_operators。vfs调用操作(例如read_inode)用类似这样的方式:sb->s_op->read_inode(inode)

● inode对象:struct inode

每一个inode对象都会在下面三个链表之一:

1)有效但未使用的inode链表,由变量inode_unused指向

2)正在使用的inode链表,由变量inode_in_use指向

3)脏inode链表,由对应的super block对象的s_dirty成员指向。

每个inode对象也会出现在super block对象的s_inodes成员指向的链表。

struct inode_operations:inode的操作,由inode对象的i_op成员指向。

● file对象:struct file

file对象描述了进程如何与它打开的文件交互。这个对象只存在于内存中,在磁盘不存在,因此没有标识是否dirty的成员。

每个super block对象的s_files成员指向一个file对象组成的链表,file对象的f_list成员指向它在这个链表的前后成员。因此,不同文件系统的file对象,在不同的链表中。

f_count:引用该file对象的进程的数量。

file_operations:file对象的操作,由file对象的f_op指向。

● dentry对象:struct dentry

对于一个路径,例如/tmp/test,的每一个组成部分,VFS都会未其创建一个dentry,因此,这个路径一共有三个dentry,每个dentry都有自己对应的inode。

dentry对象不存储在磁盘。

由kmem_cache_alloc和kmem_cache_free创建和销毁。

dentry对象的四种状态:

free:dentry对象没有有效的信息,并且没有被VFS使用。

unused:dentry对象当前没有被VFS使用,d_count成员的值为0,但是d_inode成员指向对 应的inode。对象包好的信息有效,但可能由于回收资源而被丢弃。

in use:dentry对象当前正被VFS使用中,d_count的值为正,d_inode指向对应的inode,对 象的内容也不能被抛弃。

negative:dentry对象对应的inode不存在。可能是因为inode被删除,或该dentry被创建的时候,对应的文件不存在。

dentry_operations:

由dentry对象的d_op成员指向。

unused dentry对象被组织在一个LRU双向链表中,按插入时间顺序排序。链表的第一个,也是最后一个元素被变量dentry_unused指向,这个元素的d_lru成员指向它在该lru链表中相邻的元素。

in use状态的dentry对象被组织在一个双向链表中,这个链表被它对应的inode对象的i_dentry成员指向。因为一个inode可能被多个dentry引用,因此,该链表实际上,是某个inode的dentry对象链表。

● struct fs_struct,files_struct

fs_struct:

描述进程与文件系统交互的信息。进程描述符task_struct的fs成员指向该结构。

file_struct:

描述了进程打开的所有文件,进程对象的files成员指向它。

fd成员的最大值由max_fds指定。fd_array包含32个file对象,如果进程打开的文件超过32个,则内核会分配一个更大的file指针数组,并将其赋给fd,同时更新max_fds的值。

对于fd这个数组,文件描述符就是它的索引。通常0为标准输入,1为标准输出,2为标准错误输出。允许不同的文件描述符,引用相同的文件,例如,通过shell重定向:2>&1。

疑问:fd是每个进程的局部变量,每个进程都是这样的规则?

文件描述符是一个无符号整型。

内核提供一个fget(fd)函数来使用一个file对象:current->files->fd[fd]。fget函数会使file对象的f_count成员加1。

相应地,内核提供一个fput函数,当该file对象使用完毕后,f_count减1。当f_count=0时,fput调用file对象的release方法,将i_writecount(假设该文件,用来写)减1,并从对应的super block的file链表上将该file对象删除,将该file对象返回给slab allocator,将对应的dentry的使用计数减1。

● 特殊文件系统:special filesystem

网络文件系统和基于磁盘的文件系统能让用户在内核以外处理信息,特殊文件系统让用户和程序处理内核的数据,并且实现操作系统的一些特殊功能。

特殊文件系统和具体的物理设备无关,但为了统一起见,内核会给每个挂载的特殊文件系统分配一个虚拟设备。这个虚拟设备用0作为主设备号(major number),任意的数值作为副设备号(minor number)。super_block有一个成员s_dev,是设备描述符,内核用set_anon_super函数来初始化特殊文件系统,这个函数获得一个副设备号minor number,然后用主设备号0和副设备号dev来初始化s_dev。

● 文件系统类型注册:

每个文件系统类型用file_system_type对象类表示:

所有的文件系统类型被插入到一个单链表,这个链表由变量file_systems来指向。file_system_type的next成员指向这个链表中的下一个文件类系统型对象。

file_system_type对象的fs_supers成员指向某个特定文件系统类型的所有super block,形成一个链表。super block的s_instances成员指向这个文件系统类型在链表的前一个和后一个元素。

注册:在编译时,调用register_filesystem 函数,将文件系统类型对象插入到file_systems指向的链表中。当一个实现了文件系统的模块加载时,也会调用register_filesystem。

解除注册:unregister_filesystem。

● 文件系统的挂载:

根文件系统root filesystem:内核在编译时期,直接挂载的文件系统。掌握了系统初始化脚本和最重要的系统程序。

其他文件系统可以挂载在已挂载的文件系统的目录上。每个文件系统都有它的根目录,文件系统挂载的目录叫做挂载点mount point。一个文件系统是它的挂载点对应的目录所在的文件系统的子文件系统。

根目录隐藏了挂载点目录的内容,以及挂载点之下的所有子树。

● namespace

namespace是一种资源隔离的方案pid,ipc,mnt等资源不再是全局性的,而是属于某个namespace。每个namespace下的资源对其他namespace是透明的。因此对于pid,可能出现相同的pid,但是相同的pid会在不同的namespace中。

对于文件系统,也有一个namespace。一个进程在clone时,如果设置了CLONE_NEWNS标志位,则获得了一个新的namespace。当一个进程挂载或卸载文件系统时,它只会修改自己的namespace。

命名空间结构体struct nsproxy,被进程对象的nsproxy成员指向。

每个文件系统可以挂载多次,但是他们共享一个super block。

一个挂载点也可以挂载多个文件系统。

● struct vfsmount

描述一个独立文件系统的挂载信息,每一个挂载点对应一个vfsmount结构。属于同一文件系统的文件和目录隶属于同一vfsmount。

VFSmount挂载点通过mnt_list双链表挂载在mnt_namespace->list中,该命名空间可以通过任意进程获得:task-> nsproxy

vfsmount结构被保存在下面的链表中:

  • 一个哈希表,索引为父文件系统的vfsmount地址挂载点的dentry地址。这个哈希表存储在名为mount_hashtable的数组里。该哈希表的每一项,是所有哈希值相同的vfsmount组成的链表。vfsmount的mnt_hash成员指向该链表的相邻元素。
  • 每一个namespace的list成员维护的一个链表,vfsmount的mnt_list成员指向这个链表中相邻的元素。

  • 对于每一个挂载的文件系统,维护了一个所有子文件系统(挂载在自己文件系统上的文件系统)的链表(假设为L)。vfsmount的mnt_mounts成员指向父文件系统的L。vfsmount的mnt_child成员指向父文件系统的L链表的相邻的元素。

(待续。。。)

VFS的更多相关文章

  1. linux文件系统体系结构 和 虚拟文件系统(VFS)

    图 1. Linux 文件系统组件的体系结构 用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C 库(glibc),它们为文件系统调用(打开.读取.写和关闭)提供用户接口.系统调用接口的 ...

  2. 虚拟文件系统(VFS)

    原文链接:http://www.orlion.ga/1008/ linux在不同的文件系统之上做了一个抽象层,使得文件.目录.读写访问等概念都成为抽象层概念,这个抽象层被称为虚拟文件系统(VFS). ...

  3. virtual file system (VFS)

    http://www.ibm.com/developerworks/library/l-virtual-filesystem-switch/ http://www.ibm.com/developerw ...

  4. Linux VFS Extended Attribute And Access Control Table

    catalog . 简介 . 扩展属性 . 访问控制表 . 小结 0. 简介 许多文件系统都提供了一些特性,扩展了VFS层提供的标准功能,虚拟文件系统不可能为所有特性都提供具体的数据结构.超出标准的U ...

  5. 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解

    http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...

  6. [转载]VFS—Kernel Space & User Space

    在了解虚拟文件系统之前 , 需要先了解 Kernel Space 和 User Space 的区别 . 二者的差别在于内存使用上安全机制的差异 . kernel 执行时会占据一段系统的内存空间 , 这 ...

  7. apache commons vfs 文件夹监控

    package test.vfs; import java.io.File; import org.apache.commons.logging.Log; import org.apache.comm ...

  8. Linux内核学习笔记——VFS

    概念: ①硬链接:若一个 inode 号对应多个文件名,则称这些文件为硬链接.即硬链接就是同一个文件使用了多个别名.硬链接可由命令 link 或 ln 创建. 其特性: 文件有相同的 inode 及 ...

  9. linux VFS 内核数据结构

    <strong>简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp.</strong> 文件描述 ...

随机推荐

  1. 设计模式学习之原型模式(Prototype,创建型模式)(5)

    通过序列化的方式实现深拷贝 [Serializable] public class Person:ICloneable { public string Name { get; set; } publi ...

  2. html 表单 dom 注意跟表单的name值一致

    html 表单 dom 注意跟表单的name值一致 <script type="text/javascript"> function checkForm() { var ...

  3. 关于html5不支持frameset的解决方法

    转自:http://blog.sina.com.cn/s/blog_b2813a790101ejvf.html html5已经不支持frameset了,很郁闷,看了大家的解决方法,无非就是两种1. 使 ...

  4. Ubuntu常用命令大全(转)

    点评:Ubuntu常用命令大全,学习ubuntn系统的朋友可以收藏下,用ctrl+F查找即可 一.文件/文件夹管理 ls 列出当前目录文件(不包括隐含文件) ls -a 列出当前目录文件(包括隐含文件 ...

  5. C语言标量类型(转)

    在C语言中,枚举类型.字符型和各种整数的表示形式统一叫做标量类型. 当在C表达式中使用标量类型的值时,编译器就会自动将这些标识符转换为整数保存. 这种机制的作用是,在这些标量类型上执行的操作与整型上执 ...

  6. html5 canvas 标签

    <canvas id="board" width="500" height="400"></canvas> < ...

  7. Session: 防止用户多次登陆

    在web开发时,有的系统要求同一个用户在同一时间只能登录一次,也就是如果一个用户已经登录了,在退出之前如果再次登录的话需要报错. 常见的处理方法是,在用户登录时,判断此用户是否已经在Applicati ...

  8. Hadoop的mapreduce开发过程,我遇到的错误集锦(持续更新)

    1.Text包导错了. 将import com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider.Text; 改为import o ...

  9. 数学 Codeforces Round #291 (Div. 2) B. Han Solo and Lazer Gun

    题目传送门 /* 水题,就是用三点共线的式子来判断射击次数 */ #include <cstdio> #include <cmath> #include <string& ...

  10. 转:.NET获取当前方法名或调用此方法的方法名

    Introduction Before .NET, we were always looking for a way to log current method name in a log file ...