第17章 虚拟文件系统
- 格式:pdf
- 大小:630.75 KB
- 文档页数:42
Linux虚拟文件系统原理作者:侯旗陈慈发艾伟来源:《数字技术与应用》2011年第09期摘要:分析了Linux虚拟文件系统如何实现把各种不同物理文件系统转换为对Linux内核和进程具有统一接口的过程,用框图的形式清晰地勾勒出其中涉及到的数据结构之间的联系。
关键词:Linux 虚拟文件系统 inode node dentry中图分类号:TP313 文献标识码:A 文章编号:1007-9416(2011)09-0186-01随着嵌入式技术的发展,由于Linux众多优势,越来越多的嵌入式设备采用Linux操作系统。
Linux支持的物理文件系统具有不同的组织结构和处理方式。
为了兼容支持不同的文件系统,Linux设计了在系统启动时由系统在内存中创建文件系统,即虚拟文件系统,以对不同的物理文件系统的所有特性进行抽象,屏蔽各种文件系统的差别,向Linux内核和进程提供了统一的文件系统接口,实现对不同文件系统的支持。
理解Linux虚拟文件系统机制对于学习Linux系统起着重要的作用。
在这个背景下,本文对Linux虚拟文件系统原理作了比较详尽的分析。
1、LinuxVFS基本原理Linux以EXT2作为基本的文件系统,组成VFS的超级块、索引节点、目录项等数据结构,兼容于各种文件系统的相应数据结构,从而实现对多种文件系统的透明调用。
Linux所支持的文件系统的一般结构,Linux继承了UINX,把文件名和文件控制信息分开管理。
一个Linux所支持的物理文件系统,使用的块设备上的一个独立的逻辑分区可大致分为:引导块、超级块、inode块、data块等四部分[1]。
LinuxVFS采用超级块(super_block)和索引节点(inode)来描述文件系统,这里的super_block和inode不同于物理文件系统中的super_block和inode数据结构:VFSsuper_block 是VFS把不同文件系统中的整体组织和结构信息进行抽象后形成的兼顾不同文件系统的统一的超级块结构。
虚拟文件系统课程设计的研究背景一、引言虚拟文件系统(Virtual File System,VFS)是操作系统中的一个重要组成部分,它为用户和应用程序提供了统一的文件系统接口。
VFS可以隐藏底层文件系统的差异,使得用户可以方便地访问不同类型的文件系统,如磁盘文件系统、网络文件系统等。
虚拟文件系统的设计和实现对于操作系统的性能和可扩展性具有重要影响。
二、虚拟文件系统的概念与特点2.1 虚拟文件系统的定义虚拟文件系统是操作系统中的一个抽象层,它将不同类型的文件系统统一抽象为一个统一的接口,使得用户和应用程序可以通过相同的方式访问不同类型的文件系统。
2.2 虚拟文件系统的特点•统一接口:虚拟文件系统为用户和应用程序提供了统一的文件系统接口,使得它们可以方便地访问不同类型的文件系统。
•隐藏差异:虚拟文件系统可以隐藏底层文件系统的差异,使得用户无需关心底层文件系统的具体实现细节。
•可扩展性:虚拟文件系统的设计可以支持不同类型的文件系统,并且可以方便地添加新的文件系统类型。
•高性能:虚拟文件系统的设计和实现对于操作系统的性能具有重要影响,可以通过优化算法和数据结构来提高文件系统的访问速度。
三、虚拟文件系统的设计与实现3.1 虚拟文件系统的层次结构虚拟文件系统可以分为多个层次,每个层次负责不同的功能。
常见的虚拟文件系统的层次结构包括以下几个层次: 1. 用户接口层:提供用户与文件系统交互的接口,如命令行界面、图形界面等。
2. 文件系统接口层:提供统一的文件系统接口,隐藏底层文件系统的差异。
3. 文件系统抽象层:将底层文件系统抽象为一个统一的接口,提供文件的访问、创建、删除等操作。
4. 文件系统实现层:具体实现不同类型的文件系统,如磁盘文件系统、网络文件系统等。
3.2 虚拟文件系统的功能模块虚拟文件系统的设计包括以下几个功能模块: 1. 文件系统初始化:初始化虚拟文件系统,加载底层文件系统。
2. 文件的访问控制:实现文件的权限控制和访问控制列表。
虚拟文件系统一基本概念传统的操作系统仅能支持一种类型的文件系统,随着信息技术的发展和应用需求的增长,对文件系统的使用提出了新的要求,例如,要求在UNIX系统中支持非UNIX类文件系统,以便运行UNIX的机器上也可访问DOS分区;要求Windows 2000/XP支持高性能文件系统的同时支持FAT文件系统;Linux在设计时便瞄准能同时支持几十种文件系统;随着网络的发展,迫切要求计算机之间共享网络文件系统;甚至一些用户希望能定制自己的文件系统。
为了能同时支持多种文件系统,不同操作系统采用不同技术方案来提供虚拟文件系统,它要实现以下目标:把多种个文件系统纳入统一框架中,不同的磁盘分区可以包含不同的文件系统,对它们的使用和传统单一文件系统没有区别;用户可以通过同一组系统调用来对不同的文件系统及文件进行操作,更进一步,系统调用可以跨物理介质和跨文件系统执行,如从一个文件系统拷贝或移动数据到另一个文件系统;对网络共享文件提供完全支持,访问远程节点上的文件应与访问本地节点的文件一致;开发出新的文件系统后,可以模块方式加入到操作系统中。
虚拟文件系统VFS也称为虚拟文件系统开关(Virtual filesystem Switch),它是内核的一个子系统,提供了一个通用文件系统模型,该模型囊括了所能见到的文件系统常用功能和行为,并为应用程序提供一致性的文件系统接口,安装的所有物理文件系统不但依赖于VFS共存,而且也依靠VFS协同工作。
它的主要设计思想有以下3点:(1)应用层:VFS模型源于UNIX文件系统,使得用户可以直接使用标准UNIX 文件系统调用来操作文件,无需考虑具体文件系统特性和物理存储介质,通过VFS访问文件系统,才使得不同文件系统之间的协作性和通用性成为可能。
(2)虚拟层:在对所有具体文件系统的共同特性进行抽象的基础上,形成一个与具体文件系统实现无关的虚拟层,并在此层次上定义与用户的一致性接口;(3)实现层:该层使用类似开关表技术进行具体文件系统转接,实现各种文件系统的物理操作细节,每个文件系统是自包含的,包含文件系统实现的各种设施,如超级块、节点区、数据区以及各种数据结构和文件类的操作函数。
理解操作系统中的虚拟文件系统和文件描述符虚拟文件系统(Virtual File System,简称VFS)和文件描述符(File Descriptor)是操作系统中与文件操作相关的两个重要概念。
首先,我们来了解一下虚拟文件系统(VFS)。
虚拟文件系统是操作系统中提供的抽象层,用于屏蔽底层不同文件系统的差异,使得用户程序可以以统一的方式访问不同存储介质上的文件。
VFS为用户程序提供了一套通用的文件系统接口,无论是访问硬盘上的文件、网络上的文件还是其他设备上的文件,用户程序都可以通过VFS接口来进行操作,而不需要关心文件实际存储位置的细节。
VFS充分体现了操作系统设计中的抽象和封装思想,提高了文件系统的可移植性和应用的灵活性。
在Linux系统中,VFS的设计将所有的文件操作都转换为一系列的系统调用接口,比如打开文件、读取文件等。
这些系统调用接口被封装在glibc等标准库中,用户程序通过调用这些库函数来进行文件操作。
而这些库函数最终会调用到系统内核中的相关函数来完成实际的文件系统操作。
这样,VFS作为操作系统内核的一部分,为用户提供了一种简单、一致的文件操作接口。
接下来,我们介绍文件描述符(File Descriptor)。
文件描述符是操作系统中用来标识打开文件的一种机制。
每个被打开的文件都会被操作系统分配一个唯一的文件描述符,用于标识该文件在系统中的位置和状态。
文件描述符是一个非负整数,其值可以通过系统调用接口(如open、read、write等)返回或传递给其他相关函数来进行文件的操作。
用户程序通过文件描述符与文件进行交互,比如将文件描述符传递给read函数来读取文件内容,或者传递给write函数来写入文件数据。
在Linux系统中,文件描述符是进程级别的,每个进程都有自己独立的文件描述符表。
文件描述符表是一个以整数索引的数组,每个索引位置上存放着相应的文件描述符。
文件描述符的索引位置从0开始,通常用标准输入(stdin)、标准输出(stdout)和标准错误(stderr)的文件描述符分别对应0、1、2。
虚拟文件系统的原理和功能虚拟文件系统(Virtual File System,VFS)是操作系统中的一个重要组成部分,它是操作系统与文件系统之间的接口层。
它的主要功能是将不同文件系统的细节隐藏起来,为用户提供统一的文件操作接口,使得用户不需要关心文件系统的具体实现细节。
虚拟文件系统在不同的操作系统中有不同的实现方式,但其基本原理和功能都是相似的。
虚拟文件系统的主要原理是通过对文件的抽象和封装,将不同文件系统的差异统一起来,使得用户可以透明地访问和操作不同文件系统中的文件。
虚拟文件系统将所有的文件操作都看作是对抽象文件对象(简称Vnode)的操作,而不需要关心实际的物理文件。
Vnode是一个抽象概念,它代表了一个文件或目录,包含了文件的各种属性信息以及文件系统相关的操作方法。
不同的文件系统可以有不同的Vnode实现,但它们都需要实现虚拟文件系统定义的接口。
虚拟文件系统的功能包括:1. 统一的文件访问接口:虚拟文件系统为用户提供了统一的文件操作接口,无论是访问本地文件系统还是网络文件系统,用户都可以使用相同的接口进行文件的读写和管理操作。
这样可以方便用户进行文件操作,而无需考虑不同文件系统的差异。
2. 文件系统抽象:虚拟文件系统将不同文件系统的差异抽象成统一的概念,用户可以通过虚拟文件系统访问和管理各种类型的文件,如磁盘文件、目录、设备文件等。
这样可以简化用户的操作,提高用户的使用效率。
3. 文件系统透明性:虚拟文件系统隐藏了底层文件系统的具体实现细节,用户对文件的操作是透明的,无需关心实际的物理文件和文件系统的存储结构。
这样可以提高系统的可移植性和可扩展性,使得操作系统可以支持不同的文件系统。
4. 文件缓存管理:虚拟文件系统通过文件缓存来提高文件的读写效率。
文件缓存是指将文件的一部分数据缓存在内存中,当需要访问文件时,首先在缓存中查找,如果找到则直接返回,如果没有找到则从文件系统中读取。
通过文件缓存可以减少对底层文件系统的访问次数,提高文件的读写性能。
虚拟文件系统1、概述什么是虚拟文件系统?虚拟文件系统(VFS,virtual filesystem),是一个内核软件层,是物理文件系统与服务之间的一个接口层,它对Linux的每个文件系统的所有细节进行抽象,使得不同的文件系统在Linux核心以及系统中运行的其他进程看来,都是相同的。
严格说来,VFS并不是一种实际的文件系统。
它只存在于内存中,不存在于任何外存空间。
VFS在系统启动时建立,在系统关闭时消亡。
VFS支持文件系统主要有三种类型:磁盘文件系统:管理本地磁盘分区中可用的存储空间或者其他可以起到磁盘作用的的设备(USB闪存)。
常见磁盘文件系统有Ext2,Ext3,SystemV,BSD,等。
网络文件系统: 访问属于其他网络计算机的文件系统所包含的文件。
常用的网络文件系统有NFS,AFS,CIFS,等。
特殊文件系统:不管理本地或者远程磁盘空间。
/proc文件系统是特殊文件系统的一个典型的范例。
基本概念文件:一组在逻辑上具有完整意义的信息项的系列。
在Linux中,除了普通文件,其他诸如目录、设备、套接字等也以文件被对待。
总之,“一切皆文件”。
目录:目录好比一个文件夹,用来容纳相关文件。
因为目录可以包含子目录,所以目录是可以层层嵌套,形成文件路径。
在Linux中,目录也是以一种特殊文件被对待的,所以用于文件的操作同样也可以用在目录上。
目录项:在一个文件路径中,路径中的每一部分都被称为目录项;如路径/home/source/helloworld.c中,目录 /, home, source和文件 helloworld.c都是一个目录项。
索引节点:用于存储文件的元数据的一个数据结构。
文件的元数据,也就是文件的相关信息,和文件本身是两个不同的概念。
它包含的是诸如文件的大小、拥有者、创建时间、磁盘位置等和文件相关的信息。
超级块:用于存储文件系统的控制信息的数据结构。
描述文件系统的状态、文件系统类型、大小、区块数、索引节点数等,存放于磁盘的特定扇区中。
理解操作系统中的虚拟文件系统和文件描述符一、介绍在操作系统中,虚拟文件系统(VFS)和文件描述符是两个关键概念。
虚拟文件系统是操作系统提供给用户应用程序的抽象出的文件系统接口,而文件描述符则是应用程序用于操作文件的标识符。
虚拟文件系统提供了一种统一的方式来访问不同类型的存储设备和文件系统,而文件描述符则用于表示文件在应用程序中的打开和操作。
二、虚拟文件系统1.虚拟文件系统的定义虚拟文件系统是一种操作系统层面的抽象,它提供了一种统一的接口来访问不同类型的存储设备和文件系统。
它隐藏了不同文件系统之间的实现细节,使得用户应用程序可以通过同样的方式来操作不同类型的文件。
2.虚拟文件系统的组成虚拟文件系统由三个主要组件组成:文件对象(file object)、文件系统对象(file system object)和虚拟文件系统接口(VFS interface)。
-文件对象是操作系统中表示打开文件的数据结构,它包含了文件的状态信息和指向文件系统对象的指针。
-文件系统对象是表示文件系统的数据结构,它包含了文件系统的具体实现和方法。
-虚拟文件系统接口是用户应用程序与操作系统之间进行交互的接口,它定义了一组标准的文件操作函数,如打开、读取、写入、关闭等。
3.虚拟文件系统的优点虚拟文件系统具有以下几个优点:-提供了统一的文件系统接口,使得用户应用程序可以通过同样的方式来操作不同类型的文件。
-隐藏了不同文件系统之间的实现细节,使得用户应用程序可以更加方便地进行文件操作。
-允许用户应用程序在不同文件系统之间进行文件的复制、移动等操作,而不需要了解文件系统的具体细节。
三、文件描述符1.文件描述符的定义文件描述符是一个用于表示打开文件或其他设备的整数。
在Unix-like操作系统中,每个进程都有一个文件描述符表,其中包含了与它打开的文件或设备相关的信息。
2.文件描述符的使用文件描述符是应用程序与操作系统进行文件操作的接口,它通过系统调用来进行打开、读取、写入、关闭等操作。
基于vfs实现⾃⼰的⽂件系统1.Linux ⽂件系统组成结构linux⽂件系统有两个重要的特点:⼀个是⽂件系统抽象出了⼀个通⽤⽂件表⽰层——虚拟⽂件系统或称做VFS。
另外⼀个重要特点就是它的⽂件系统⽀持动态安装(或说挂载等),⼤多数⽂件系统都可以作为根⽂件系统的叶⼦节点被挂在到根⽂件⽬录树下的⼦⽬录上。
1.1.虚拟⽂件系统虚拟⽂件系统为⽤户空间程序提供了⽂件系统接⼝。
系统中所有⽂件系统不但依赖VFS共存,⽽且也依靠VFS系统协同⼯作。
通过虚拟⽂件系统我们可以利⽤标准的UNIX⽂件系统调⽤对不同介质上的不同⽂件系统进⾏读写操作。
虚拟⽂件系统的⽬的是为了屏蔽各种各样不同⽂件系统的相异操作形式,使得异构的⽂件系统可以在统⼀的形式下,以标准化的⽅法访问、操作。
实现虚拟⽂件系统利⽤的主要思想是引⼊⼀个通⽤⽂件模型——该模型抽象出了⽂件系统的所有基本操作(该通⽤模型源于Unix风格的⽂件系统),⽐如读、写操作等。
同时实际⽂件系统如果希望利⽤虚拟⽂件系统,即被虚拟⽂件系统⽀持,也必须将⾃⾝的诸如“打开⽂件”、“读写⽂件”等操作⾏为以及“什么是⽂件”,“什么是⽬录”等概念“修饰”成虚拟⽂件系统所要求的(定义的)形式,这样才能够被虚拟⽂件系统⽀持和使⽤。
我们可以借⽤⾯向对象的思想来理解虚拟⽂件系统,可以想象成⾯向对象中的多态。
1.2.虚拟⽂件系统的相关对象虚拟⽂件系统的核⼼概念1、 VFS 通过树状结构来管理⽂件系统,树状结构的任何⼀个节点都是“⽬录节点”2、树状结构具有⼀个“根节点”3、 VFS 通过“超级块”来了解⼀个具体⽂件系统的所有需要的信息。
具体⽂件系统必须先向VFS注册,注册后,VFS就可以获得该⽂件系统的“超级块”。
4、具体⽂件系统可被安装到某个“⽬录节点”上,安装后,具体⽂件系统才可以被使⽤5、⽤户对⽂件的操作,就是通过VFS 的接⼝,找到对应⽂件的“⽬录节点”,然后调⽤该“⽬录节点”对应的操作接⼝。
第17章虚拟文件系统实验目的•理解虚拟文件系统的概念和原理•理解虚拟文件系统对象及其数据结构•理解虚拟文件系统的操作接口•通过编程实现一个虚拟文件系统主要内容•背景知识–虚拟文件系统概念–VFS的组成(数据结构)–modutils软件包•实验内容•实现一个虚拟文件系统虚拟文件系统实现目标VFS作为内核子系统,其功能是将不同具体文件系统的接口统一起来,隐蔽它们的实现细节,为应用程序提供标准的、统一的、抽象的文件操作。
•同时支持多种文件系统;且文件系统可交叉工作;•新开发出的文件系统可模块方式加入到操作系统中;•提供通过网络共享文件的支持,访问远程结点上的文件系统应与访问本地结点的文件系统一致;跨文件系统的文件复制示意图根文件系统:Ext3文件格式VFS CP软盘文件系统:FAT文件格式infile=open("/user/test",O_RDONLY,0);i fi(//O O0)outfile=open("/work/test",O_WRONLY|O_CREAT|O TRUNC0600);O_TRUNC,0600);while ((charnum=read(infile,buf,4096))>0)write outfile,buf,charnum(,,)close(infile);close(outfile);VFS工作流程(1)write()sys_write()具体文件系统的write( )统的write()虚拟文件系统用户空间具体文件系统物理介质VFS工作流程(2)读写操作的执行过程:•打开的文件用系统打开文件表file数据结构来表示,它有一个成员是指向文件操作表的指针file_operation *f_op,其中包含指向各种函数如read( )、write( )、open( )、close( )等file operation 的入口,每种具体文件系统都有自己的file operation结构,也就是有自己的操作函数。
•当进程使用open()打开文件时,将与具体文件建立连接,并以一个file结构作为纽带,将其中的f_op设置成指向某个具体的file_operation结构,也就指定了这个文件所属的文件系统。
•当应用程序调用read()函数时,就会陷入内核而调用sys_read()内核函数,而sys_read()就会通过file结构中的指针f_op去调用DOS文件系统的读函数,即:f opfile→f_op→read()函数。
同样道理,write()操作也会引发一个与输出文件相关的Ext3的file→f_op→write()写函数的执行。
VFS结构•虚拟文件系统的功能VFS实质上是仅存于主存的,支持多种类型具体文件系统的运行环境,功能有:•记录安装的文件系统类型;•建立设备与文件系统的联系;•实现面向文件的通用操作;•涉及特定文件系统的操作时映射到具体文件系统中去。
主要内容•背景知识–虚拟文件系统概念–VFS的组成(数据结构)–modutils软件包•实验内容•实现一个虚拟文件系统VFS的组成超级块对象代表一个文件系统。
•-•索引节点对象-代表一个文件。
•目录项对象-代表路径中的一个组成部分。
•文件对象-代表由进程已打开的一个文件。
VFS主要数据结构(1)•超级块(super block)对象-代表一个文件系统。
存放已安装的文件系统信息,该对象对应于磁盘上的文件系统控制块,每个文件系统都对应一个超级块对象。
如文件系统类型、超级块操作表指针、目录挂载点、设备和设备标识符、块大小。
•索引节点(inode)对象-代表一个文件。
存放通用的文件信息,该对象对应于磁盘上的文件FCB,即每个文件的inode对象,每个inode都有inode索引节点号,惟一地标识某个文件系统中的指定文件。
如引用计数、硬链接数、用户ID、文件大小、文件属inode性、块大小、文件块数、超级块指针、操作表指针。
VFS主要数据结构(2)•目录项(dentry)对象-代表路径中的一个组成部分。
存放目录项与对应文件进行链接的信息,最近最常使用的dentry对象放在目录项高速缓存中,加快文件路径名搜索过程,提高系统性能。
如相关inode、父目录/子目录信息、inode别名表、dentry操作表指针、超级块指针、dentry标志、散列表。
文件(file)对象代表由进程已打开的一个文件。
存放•-已打开文件与进程的交互信息,这些信息仅当进程访问文件期间才存于主存中。
如相关dentry、file操作表指针、引用次数、访问模式、当前位移、用户。
ID超级块、索引节点、目录项和文件对象关系(1)磁盘文件超级块对象索引节点对象进程1文件对象文件对象进程2目录项对象目录项对象进程3文件对象对象关系(2)对象关系(3)fs_struct dentrytask struct count umask*root d_inode 根目录的inodetask_structdentry…fs *pwd *altrootd inodefil t t 当前目录的inodefile files …count close_on_exec _files_struct f mode dentryinode数据open_fdsfd[0]f_mode f_pos f_flages d_inode d_op union i_op文件描述符…fd[255]f_count f_owner f_dentryread writefile_operation 文件的inodef_op用户空间核心空间函数和数据对象、以及数据对象中操作对象的关系Sparrow文件系统中4个基本对象需要实现的函数主要内容•背景知识–虚拟文件系统概念–VFS的组成(数据结构)–modutils软件包•实验内容•实现一个虚拟文件系统modutils软件包•insmod命令-载入模块rmmod命令卸载模块•-•lsmod命令-显示模块信息(模块模块名、大小和引用计数等)主要内容•背景知识–虚拟文件系统概念–VFS的组成(数据结构)–modutils软件包•实验内容•实现一个虚拟文件系统实验实现个虚拟文件系统实现一个虚拟文件系统需要完成以下内容:–1)完成Sparrow文件系统的编程、调试和挂载p–2)让Sparrow文件系统具有文件链接功能•软链接(Symbolic Links,又称为符号链接)•硬链接(Hard Links)。
Sparrow 文件系统•Sparrow 文件系统是基于Linux 操作系统平台的,仅具有基本功能的文件系统,能够支持也仅仅支持以下功能:–1)文件系统的初始化和安装、挂载/卸载;–2)文件的创建和删除;–3)目录的创建和删除。
•Sparrow p 文件系统是驻留在主存中的文件系统,当被卸载时,其中的文件将会丢失。
•Sparrow 文件使用Linux 内核模块技术来安装和挂载,首先,需要在内核中加载Sparrow 文件系统这个内核模块,然后,使用mount 命令把它添加进内核。
参考源程序(1)•#include <linux/module.h>•#include <linux/init.h>#include<linux/init.h>•#include <linux/fs.h>•#include<linux/pagemap.h>#include <linux/pagemap.h>•#include <linux/version.h>•#include <linux/nls.h>•#include <linux/proc_fs.h>•#include <linux/backing-dev.h>•#include "sfs.h"#include"sfs.h"•#define SAMPLEFS_MAGIC 0x73616d70•extern struct inode_operations sfs_dir_inode_ops;extern struct inode_operations sfs_dir_inode_ops;•extern struct inode_operations sfs_file_inode_ops;•extern struct file_operations sfs_file_operations;•extern struct address_space_operations sfs_aops;参考源程序(2)•1) init_module函数•static struct file_system_type sfs_fs_type = {static struct sfs_fs_type={•.owner = THIS_MODULE,•.name = "sfs",•.get_sb = sfs_get_sb,•.kill_sb = kill_litter_super,•};•static int __init init_sfs_fs(void) {•printk(KERN_INFO "init samplefs\n");/* some filesystems pass optional parms at load time */•/*some filesystems pass optional parms at load time*/•if(sample_parm > 256) {•printk("sample_parm %d too large, reset to 10\n", sample_parm);•sample_parm = 10;sample_parm=10;•}•return register_filesystem(&samplefs_fs_type);•}•module_init(init_sfs_fs);参考源程序(3)2)cleanup_module函数•2) cleanup_module函数•static void __exit exit_sfs_fs(void)•{•printk(KERN_INFO "unloading sfs\n");•#ifdef CONFIG_PROC_FS#ifdef CONFIG_PROC_FS•//sfs_proc_clean( );•#endif•unregister_filesystem(&sfs_fs_type);•}•module_exit(exit_sfs_fs)参考源程序(4)参考序()•3)file_system_type.get_sb函数•static int sfs_fill_super(struct super_block * sb, void * data, int silent) •{•struct inode * inode;struct inode*inode;•struct sfs_sb_info * sfs_sb;•sb->s_maxbytes = MAX_LFS_FILESIZE;•sb->s_blocksize = PAGE_CACHE_SIZE;•sb->s_blocksize_bits = PAGE_CACHE_SHIFT;sb->s_blocksize_bits=PAGE_CACHE_SHIFT;•sb->s_magic = SAMPLEFS_MAGIC;•sb->s_op = &sfs_super_ops;•sb->s_time_gran = 1;•sb->s_fs_info = kzalloc(sizeof(struct sfs_sb_info),GFP_KERNEL);sb->s_fs_info=kzalloc(sizeof(struct sfs_sb_info),GFP_KERNEL);•sfs_sb = SFS_SB(sb);•if(!sfs_sb) {•return -ENOMEM;•}•inode = sfs_get_inode(sb, S_IFDIR | 0755, 0);•if(!inode) {•kfree(sfs_sb);•return -ENOMEM;return-ENOMEM;•}•sb->s_root = d_alloc_root(inode);•if (!sb->s_root) {•iput(inode);•kfree(sfs_sb);•return -ENOMEM;•}参考源程序(5)•4) file_system_type.kill_sb函数•static struct file_system_type sfs_fs_type = {•.owner = THIS_MODULE,•.name = "sfs",.name="sfs",•.get_sb = sfs_get_sb,•kill_sb=kill_litter_super,.kill_sb = kill_litter_super,•};页高速缓存(6)•5)address_space_operations.readpage函数•6)address_space_mit_write函数•struct address_space_operations sfs_aops = { .readpage=simple_readpage,•.readpage = simple_readpage,•.prepare_write = simple_prepare_write,.commit_write = simple_commit_write•.commit_write=simple_commit_write参考源程序(7)•7) inode_operations.lookup函数static struct•static struct•dentry *sfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)•{•struct sfs_sb_info * sfs_sb = SFS_SB(dir->i_sb);•if (dentry->d_name.len > NAME_MAX)if(dentry->d_name.len>NAME_MAX)•return ERR_PTR(-ENAMETOOLONG);if(sfs_sb->flags & SFS_MNT_CASE)•if(sfs_sb->flags&SFS_MNT_CASE)•dentry->d_op = &sfs_ci_dentry_ops;•else•dentry->d_op = &sfs_dentry_ops;•d_add(dentry, NULL);•return NULL;return NULL;•}参考源程序(8)•8) file_operations.read函数•9) file_operations.write函数•struct file_operations sfs_file_operations = {•.read = do_sync_read,•.aio_read= generic_file_aio_read,•.write = do_sync_write,.aio_write=generic_file_aio_write,•= generic_file_aio_write,•.mmap = generic_file_mmap,.fsync=simple_sync_file,•.fsync = simple_sync_file,•.sendfile = generic_file_sendfile,•.llseek=generic_file_llseek,.llseek = generic_file_llseek,•};参考源程序(9)struct inode_operations sfs_dir_inode_ops={•struct inode_operations sfs_dir_inode_ops = {•.create = sfs_create,•.lookup=sfs_lookup,.lookup = sfs_lookup,•.link= simple_link,.unlink = simple_unlink,•.unlink=simple_unlink,•.symlink= sfs_symlink,.mkdir = sfs_mkdir,•.mkdir=sfs_mkdir,•.rmdir = simple_rmdir,•.mknod=sfs_mknod,.mknod = sfs_mknod,•.rename = simple_rename,•};参考源程序(10)•10)创建特殊文件static int•static int•sfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) •{•struct inode * inode = sfs_get_inode(dir->i_sb, mode, dev);•int error = -ENOSPC;int error=-ENOSPC;•printk(KERN_INFO "sfs: mknod\n");•if (inode) {•if (dir->i_mode & S_ISGID) {if(dir->i_mode&S_ISGID){•inode->i_gid = dir->i_gid;•if (S_ISDIR(mode))•inode->i_mode |= S_ISGID;•}•d_instantiate(dentry, inode);•dget(dentry); /* Extra count -pin the dentry in core */•error = 0;•dir->i_mtime = dir->i_ctime = CURRENT_TIME;dir->i_mtime=dir->i_ctime=CURRENT_TIME;•/* real filesystems would normally use i_size_write function */•dir->i_size += 0x20; /* bogus small size for each dir entry */•}•return error;•}参考源程序(11)static int sfs_create(struct inode *dir, struct •static int sfs_create(struct inode*dir,struct dentry *dentry, int mode, struct nameidata *nd) {•/*调用sfs_mknod函数*/•}•/*用以支持链接功能*/•static int sfs_symlink(struct inode * dir, struct dentry*dentry,const char*symname){dentry *dentry, const char * symname) {•………•}参考源程序(12)•/*挂载时返回超级块对象*/•#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)#if LINUX_VERSION_CODE<KERNEL_VERSION(2,6,18)•struct super_block * sfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)•{•return get_sb_nodev(fs_type, flags, data, sfs_fill_super);•}•#else•int sfs_get_sb(struct file_system_type *fs_type,int flags, const char *dev_name, void *data, struct vfsmount *mnt)•{•return get_sb_nodev(fs_type, flags, data, sfs_fill_super, mnt);•}•#endif参考源程序(13)•13)创建目录•static int sfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)•{•int retval = 0;•retval = sfs_mknod(dir, dentry, mode |retval=sfs_mknod(dir,dentry,mode| S_IFDIR, 0);/*link count is two for dir,for dot and •/* link count is two for dir, for dot and dot dot */•if (!retval)if(!retval)•dir->i_nlink++;•return retval;return retval;•}参考源程序(14)•14)创建新的inode•static int sfs_create(struct inode *dir, struct dentry *dentry, int mode,•struct nameidata *nd)•{•return sfs_mknod(dir, dentry, mode | S_IFREG, 0);•}()参考源程序(15)•15)建立符号联结•static int sfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)•{•struct inode *inode;•int error = -ENOSPC;•inode = sfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);•if (inode) {•int l = strlen(symname)+1;•error = page_symlink(inode, symname, l);•if (!error) {•if (dir->i_mode & S_ISGID)•inode->i_gid = dir->i_gid;inode->i_gid=dir->i_gid;•d_instantiate(dentry, inode);•dget(dentry);•dir->i_mtime = dir->i_ctime = CURRENT_TIME;•} else•iput(inode);•}return error;•return error;•}实验操作(1)•创建一个makefile文件•ifneq (${KERNELRELEASE},)•obj-m += samplefs.o•samplefs-objs := super.o inode.o file.o•else•KERNEL_SOURCE := /lib/modules/$(shell uname -r)/build KERNEL_SOURCE:=/lib/modules/$(shell uname-r)/build •PWD := $(shell pwd)•default:•$(MAKE) -C ${KERNEL_SOURCE} SUBDIRS=$(PWD) modules •clean :•rm *.o *.ko•endif实验操作(2)•1)$ make–编译的结果是产生sfs.ko文件。