《Linux内核设计与实现》第13章阅读总结
【edited by 5216lwr】node
1、虚拟文件系统概述
1.虚拟文件系统
(也称做虚拟文件交换或VF)做为内核子系统,为用户空间程序提供了文件和文件系统相关的接口。经过虚拟文件系统,程序能够利用标准的Uinx 系统调用对不一样的文件系统,甚至不一样介质上的文件系统进行读写操做。linux
2.通用原理
- 之因此可使用这种通用接口(VF)对全部类型的文件系统进行操做,是由于内核在它的底层文件系统接口上创建了一个抽象层。
- 该抽象层使Linux 可以支持各类文件系统。为了支持多文件系统, VFS 提供了一个通用文件系统模型,该模型囊括了任何文件系统的经常使用功能集和行为。
- 同时实际文件系统也将自身的诸如“如何打开文件”,“目录是什么”等概念在形式上与VFS 的定义保持一致。
3.具体示例
- (以write函数为例)

2、Linux文件系统
1.Unix 使用了四种和文件系统相关的传统抽象概念:文件、目录项、索引节点和安装点
- 文件其实能够作一个有序字节串,字节串中第一个字节是文件的头,最后一个字节是文件的
尾;
- 文件经过目录组织起来。文件目录比如一个文件夹,用来容纳相关文件。由于目录也能够包
含其余目录,即子目录,因此目录能够层层嵌套,造成文件路径;因为VFS 把自录看成文件对待,因此能够对目录执行和文件相同的操做;
- Unix 系统将文件的相关信息和文件自己这两个概念加以区分,例如访问控制权限、大小、
拥有者、建立时间等信息,这些被称做文件的元数据(也就是说,文件的相关数据),被存储在一个单独的数据结构中,该结构被称为索引节点( inode);
2.VFS对象
- VFS采用的是面向对象的设计思路,使用一组数据结构来表明通用文件对象。包括:
- ·超级块对象,它表明一个具体的已安装文件系统。
- 索引节点对象,它表明一个具体文件。
- 目录项对象,它表明一个目录项,是路径的一个组成部分。
- 文件对象,它表明由进程打开的文件。
- 每一个主要对象中都包含一个操做对象,这些操做对象描述了内核针对主要对象可使用的
方法,操做对象做为一个结构体指针来实现,此结构体中包含指向操做其父对象的函数指针。(其实,对于其中许多方法来讲,能够继承使用VFS 提供的通用函数,若是通用函数提供的基本功能没法知足须要,那么就必须使用实际文件系统的独有方法填充这些函数指针,使其指向文件系统实例)
3.超级块对象
- 概述:
- 各类文件系统都必须实现超级块对象,该对象用于存储特定文件系统的信息,一般对应于存放在磁盘特定扇区中的文件系统超级块或文件系统控制块
- 建立、管理和撤销超级块对象的代码位于文件fs/super.c 中。
- 超级块对象经过函数alloc_super()建立并初始化。在文件系统安装时,文件系统会调用该函数以便从磁盘读取文件系统超级块,而且将其信息填充到内存中的超级块对象中。
- 操做:
- 超级块对象中最重要的一个域是s_op,它指向超级块的操做函数表。定义在文件<linux/fs.h>中;

- 当文件系统须要对其超级块执行操做时,首先要在超级块对象中寻找须要的操做方法;
因为在C 语言中没法直接获得操做函数的父对象,因此必须将父对象以参数形式传给操做函数;缓存
4.索引结点对象
- 索引节点对象包含了内核在操做文件或目录时须要的所有信息;
- 一个索引节点表明文件系统中(可是索引节点仅当文件被访问时,才在内存中建立〉的一个
文件,它也能够是设备或管道这样的特殊文件;
- 操做:
- 和超级块操做同样,索引节点对象中的inode_operations 项也很是重要,由于它描述了VFS用以操做索引节点对象的全部方搓,这些方能由文件系统实现;
- 与超级块相似, 对索引节点的操做调用方式以下:i ->i _op->truncate(i)。其中,i指向给定的索引节点, truncate()函数是由索引节点i 所在的文件系统定义的;
5.目录项对象
- 为了方便查找操做, VFS 引入了目录项的概念。每一个den世y 表明路径中的一个特定部分;
- 对前一个例子来讲,人bin 和vi 都属于目录项对象。前两个是目录,最后一个是普通文件。必须明确一点: 在路径中〈包括普通文件在内),每个部分都是目录项对象
- 目录项也可包括安装点。在路径/mmn/cdrom/foo 中,构成元素/、mmn、foo都属于
目录项对象。VFS 在执行目录操做时〈若是须要的话)会现场建立目录项对象;
- 目录项对象由den町结构体表示,定义在文件<linux/dcacbe.h>中;
- 目录项对象有三种有效状态:被使用、未被使用和负状态。
- 被使用状态:一个被使用的目录项对应一个有效的索引节点(即d_inode 指向相应的索引节点〉而且代表该对象存在一个或多个使用者(即d_count 为正值〉
- 未被使用状态:一个未被使用的目录项对应一个有效的索引节点( d_inode 指向一个索引节点可是应指明VFS 当前并未使用它( d_count )。该目录项对象仍然指向一个有效对象,并且被保留在缓存中以便须要时再使用它;
- 一个负状态的目录项没有对应的有效索引节点( d_inode 为NULL ),由于索引节点已被删除了,或路径再也不正确。
- 目录项缓存
- 目的:若是VFS 层遍历路径名中全部的元素并将它们逐个地解析成目录项对象,还要到达最深层目录,将是一件很是费力的工做,会浪费大量的时间。因此内核将目录项对象缓存在目录项缓存(简称dcache )中。
- 包含部分:
- 目录项操做
- dentry _operation 结构体指明了VFS 操做目录项的全部方法。该结构定义在文件<lin皿/dcache.h>中:

- int d_ revalidate(struct dentry *dentry,struct namidata•);该函数判断目录对象是否有效• VFS 准备从dcache 中使用一个目录项肘,会调用该函数。(大部分文件系统将该方法置NULL,由于它们认为dcache 中的目录项对象老是有效的。)
- int d hash(struct dentry dentry,struct qstr *name);该函数为目录项生成散列值,当目录项须要加入到散列表中肘, VFS 调用该函数。
- int d_compare(struct dentry •dentry,struct qstr namel,struct qstr name2);VFS 调用该函数来比较namel 和name2 这两个文件名
- int d_dele t e (struct dentry *dentry);当目录项对象的d_count 计数值等于0 时, VFS 调用该函数。注意使用该函数须要加dcache_lock 锁和目录项的d_lock
- void d_rel ease(struct dentry *dentry);当目录项对象将要被释放时, VFS 调用该函数,默认状况下,它什么也不傲
- void d_ iput(struct dentry dentry,struct inode inode);当一个目录项对象丢失了其相关的索引节点时(也就是说磁盘索引节庚、被删除了), VFS 调用该函数
6.文件对象
- 文件对象包含如访问模式, 当前偏移等信息;文件操做常见的系统调用read()、write()等也很相似;
- 文件对象仅仅在进程观点上表明已打开文件,它反过来指向目录项对象〈反过来指向索
引节点〉,其实只有目录项对象才表示巳打开的实际文件。虽然一个文件对应的文件对象不是惟
一的,但对应的索引节点和目录项对象无疑是惟一的;
- 文件操做
- 具体的文件系统能够为每一种操做作专门的实现,或者若是存在通用操做,也可使用通用操做
7.文件系统相关的数据结构
- 除了以上几种VFS 基础对象外,内核还使用了另一些标准数据结构来管理文件系统的其余相关数据。第一个对象是file_system_ type, 用来描述各类特定文件系统类型;第二个结构体是vfsmount,用来描述一个安装文件系统的实例。
- file_system_ type 结构体被定义在<linux/fs.h>中
- get_sb()函数从磁盘上读取超级块,而且在文件系统被安装时,在内存中组装超级块对象。剩余的函数描述文件系统的属性。
- 每种文件系统,无论有多少个实例安装到系统中,仍是根本就设有安装到系统中,都只有一个file_system_ type 结构。
- vfsmount 结构被定义在<linux/mount.h>中
- 理清文件系统和全部其余安装点阔的关系,是维护全部安装点链表中最复杂的工做。vfsmount 结构体中维护的各类链表就是为了可以跟踪这些关联信息。
8.和进程相关的数据结构
如下三个数据结构将VFS 层和系统的进程紧密联系在一块儿数据结构
- file_ struct 结构体定义在文件<linux/fdtable.h>中。该结构体由进程描述符中的files 目录项指向。全部与单个进程(per-process)的相关的信息〈如打开的文件及文件描述符〉都包含在其中;
- fs_struct. 该结构由进程描述符的fs域指向。它包含文件系统和进程相关的信息,定义在文件<linux/fs_ struct.h>中;
- 是namespace 结构体=定义在文件<linux/mmt_namespace.h>中,由进程描述符中的mmt_namespace 域指向。2 .4 版内核之后,单进程命名空间被加入到内核中,它使得每个进程在系统中都看到惟一的安装文件系统一一不只是惟一的根目录,并且是惟一的文件系统层次结构。
总结
本章主要是围绕虚拟文件系统——VFS展开的其一系列对象及操做方法的描述。VFS层提供给不一样文件系统一个统一的实现框架,并且也提供了能和标准系统调用交互工做的统一接口;这样一来,基于各类不一样版本、不一样架构的Linux系统的工做就变得简单、通用。架构