1231.Linux环境下虚拟文件系统分析研究_第1页
1231.Linux环境下虚拟文件系统分析研究_第2页
1231.Linux环境下虚拟文件系统分析研究_第3页
1231.Linux环境下虚拟文件系统分析研究_第4页
1231.Linux环境下虚拟文件系统分析研究_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 本科生毕业论文(设计)本科生毕业论文(设计) 题 目 linux 环境下虚拟文件系统 分析研究 学生姓名 指导教师 学 院 专业班级 完成时间2006 年 6 月 目录 摘要.i abstract.ii 第一章 绪论.1 1.1 课题来源及研究背景 .1 1.1.1 虚拟文件系统概述.1 1.1.2 linux 研究现状.1 1.2 课题研究的目的和意义 .2 第二章 总体规划.4 2.1 设计思路 .4 2.2 实施方案 .6 第三章 对虚拟文件系统的分析 .8 3.1 虚拟文件系统数据结构 .8 3.1.1 超级块.8 3.1.2 索引节点.11 3.1.3 文件.15 3.2 文件系统

2、高速缓存 .17 3.2.1 缓冲区高速缓存.17 3.2.2 目录项高速缓存.18 3.2.3 索引节点高速缓存.19 3.3 挂载文件系统 .20 3.3.1 注册文件系统.20 3.3.2 装配文件系统.20 3.4 卸载文件系统 .21 第四章 系统详细设计.23 4.1 配置和编译 linux 内核.23 4.2 制作根文件系统 .26 4.3 制作 grub 引导 .28 4.4 配置并安装 busybox .30 4.5 向 busybox 中添加自己书写的命令 .32 4.6 制作内存磁盘映象文件 (ramdisk).34 4.7 运行与调试 .36 第五章 总结与展望.40

3、5.1 总结 .40 5.2 设计收获 .40 致谢.41 参考文献.42 摘要 本文在对linux内核源代码进行深入分析的基础上,对linux的虚拟 文件系统的内部实现机制进行研究,着重阐述linux虚拟文件系统是如 何支持各种实际的物理文件系统,最后从实践的角度说明,如何将虚拟 文件系统模块从linux内核中剥离出来,并对剥离出来的部分进行适当 修改,编写一些为之服务的实用程序,使之成为一个可以脱离其他操作 系统而独立运行的小型系统。该系统的作用是管理文件系统和协调多种 文件系统之间的共存。在具体实施过程中,采用过程分析的方法,通过 对虚拟文件系统中文件操作过程和文件访问过程的深入研究,抽

4、象出 linux的虚拟文件系统的工作方式和主要数据结构,总结出linux虚拟文 件系统相对于其他操作系统中文件系统的优点,以此达到更好地认识虚 拟文件系统。通过研究虚拟文件系统,可以达到掌握其设计思想,进而 改进的目的。 关关键键词词 虚拟文件系统,目录项,索引节点 abstract based on the deeply analysis of linux kernel source code,this article gives the research int the realization mechanism of the virtual file system switch(vfs)

5、 of linux and especially explaines how the vfs supports lots kinds of real file system.and then, it explaines how to separate the virtual file system form linux kernel and complement it with some modifications and program some utilities so as this new tiny system can run with out any other operating

6、 system. this systems purpose is to manage file system and coordinate their co-existence.during the deeply research,the article summarizes some merits in its working way and the main data structure of vfs of linux from the analysis of file access course and file operation course with the method of c

7、ourse analysis.through the research, we can know the characteristics of designing vfs,and improve it. key words virtual file system switch(vfs),dentry,inod 第一章 绪论 1.1 课题来源及研究背景 1.1.1 虚拟文件系统概述 linux 虚拟文件系统:虚拟的概念是指它的所有数据结构都是在运行以后在内存 中间建立的,并在卸载时删除,在磁盘上并没有存储相应的数据结构。以之相对应 的是具体的文件系统,ext2 ,minix ,msdos,vfa

8、t 等文件系统。虚拟文件系统是操作系 统与实际文件系统的一个接口层1。它在操作系统中起到了很重要的作用,概括起 来有以下几点: 对具体文件系统的数据结构进行抽象,以一种统一的数据结构进行管理。 接受用户层的系统调用,例如:write open stat link 等。 支持多种具体文件系统之间的相互访问。 接受内核其他子系统的操作请求,例如内存管理,和进程调度。 当用户调用一个文件时,他不需要因为文件属于不同的文件系统而按照不同的 方式读取。vfs 本身抽象了不同文件系统共同部分,对用户屏蔽了具体的操作2, 使得用户不用再去关心文件所属的文件系统的问题,实现了各个文件系统的良好兼 容。当一个最

9、新推出的文件系统普遍被采用时,linux 借助 vfs 的强大功能,可以 毫不费力的实现新文件系统在本地的组织运行,同时能不干扰其他已经装配在本地 的其他文件系统,可以说以 vfs 组织文件系统是非常具有可扩展性,并具有优良的 发展前景。 1.1.21.1.2 linuxlinux 研究现状 linux 操作系统的全称是 gnu/linux,它是由 gnu 工程和 linux 内核两个部 分共同组成的一个操作系统,虽然这个系统诞生于 1992 年,比 windows 操作系统 要晚,但是与 windows 相比它有很多独到的优势。首先,对于普通用户而言它有以 下几个优点:1.极高的稳定性:回顾

10、 linux 的历史我们会发现,linux 操作系统的架 构完全沿袭了 unix 的系统架构,所以先天就具有成熟稳定的特点,在这方面不是 另起炉灶的 windows 系列操作系统可以比拟的。2.先天的安全性:可以说一个操作 系统的架构就已经预先决定了它的安全性。linux 系统在设计的时候就是针对多用户 环境的,所以对系统文件,用户文件都做了明确的区分,每个文件都有不同的用户 属性。作为一个普通用户通常只能读写自己的文件,而对一般的系统文件只能读取 而不能改动,一些敏感的系统文件甚至连读取都是被禁止的。这种设计在根本上保 证了系统的安全,即使一个用户文件出现了问题,也不会泱及整个系统。linu

11、x 操 作系统从出现以后,由于其的开源性,使得 linux 操作系统功能越来越强大,性能 越来越稳定,目前 linux 操作系统已经能够支持大多数的主流硬件平台,这使得其 应用范围越来越广泛,目前它已经在中小型计算机上占据相当大的市场份额;同时, 在桌面操作系统上,它也打破了 windows 操作系统的垄断。据统计到 2001 年,全 球 linux 的安装数量已经超过 2000 万台3。总的说来,linux 操作系统是一个迅速 发展,性能卓越,具有巨大发展潜力的操作系统。 从 linux 内核(kernel)0.13 版开始,就已经实现了虚拟文件系统,随着 linux 内核版本的不断更新,虚

12、拟文件系统也不断得到加强和完善。到目前(linux 2.6.16 版) ,其内核中的虚拟文件系统已经可以支持几乎所有的常见文件系统4,例如: linux 中的 ext2,ext3;windows 中的 fat16,fat32,ntfs;光盘中的 iso9660;网络 文件系统(nfs)等。虽然目前虚拟文件系统的功能已经十分强大,但远没有达到完 美的境界,还有大量可以改进的地方。同时,就目前全球 linux 分布的情况分析看, 欧洲最发达,北美次之,而亚洲相对较少,而在亚洲分布的情况看,主要集中在中 国,日本,韩国。虽然 linux1992 年就出现了,但一直到 1998 年,其才真正进入 中国

13、。在欧洲,已经有许多专注于 linux 开发的公司和研究机构,例如:redhat, 美国的许多大型 it 巨头也开始拥抱 linux,ibm 公司,sun 公司,motorola 公司,intel 公司,amd 公司,dell 公司,hp 公司等都推出了各自的 linux 计划。 在国内,虽然也有一些专注于 linux 的公司,例如:红旗 linux,但相对于世界先 进水平还有很大的差距。 1.2 课题研究的目的和意义 目前,linux 操作系统 凭借其稳定可靠的性能, linux 操作系统的应用越 来越广泛,特别是在网络服务器领域。它的崛起,蚕食了许多原来是其他操作 系统占据的市场空间 5。

14、现在,其他类型的操作系统为了与 linux 竞争市场, 也在努力提高它们的文件系统,而出色的文件系统管理功能正是linux 相对 于其他操作系统的优势所在。在这种背景下,我们非常有必要深入研究 linux 的虚拟文件系统,努力去改进提高它的性能。只有这样,才能保持 linux 操作系统的优势。 一提到 linux 操作系统,就不得不谈它的文件系统,因 为 linux 对文件的管理是最出色的,这也是 linux 的精华所在。linux 在管理文件 系统方面的最大特征就是实现了虚拟文件抽象机制,这种机制不仅使得 linux 可以 支持所有类型的文件系统,更重要的一点,通过动态挂载和卸载文件系统,可

15、以明 显减少操作系统对资源的占有量,显著提高操作系统运行效率。由于 linux 操作系 统的完全开源性,这使得我们可以有机会对 linux 系统内部的具体实现机制进行研 究并加以修改,逐步完善并提升 linux 的功能。 总的说来,对 linux 操作系统进行分析研究,是很有意义的,特别的是对 linux 操作系统的精华虚拟文件系统进行分析研究,是很有必要的。通过分析 和研究,可以设计出更加优秀的 linux 系统。也可以给我们在进行其他系统软件设 计过程中提供许多值得借鉴的和思考的东西。同时,目前国内 linux 的普及度还不 高,人们对其了解也不深,研究 linux 有助于提高我国在这一领

16、域的技术水平,缩 短同世界先进水平之间的差距。由于其开源性,对它进行研究,困难程度不是很大, 但意义却很大,因为 linux 作为操作系统家族中的一员,我们可以通过对 linux 的 研究加强自身在操作系统研发方面的能力,打破美国在这一核心领域的垄断地位。 第二章 总体规划 2.1 设计思路 由于 linux 操作系统的一个重要特点就是模块化,这些模块可以编译时静态 地链接,也可以在运行时动态链接,当系统运行需要用到某个模块所提供的功能 时,内核就临时把该模块从外存中加载到内存中,当不再需要这个模块时, linux 内核又会将它卸载6。例如,通常情况下,桌面 linux 对 ntfs 文件系统

17、的 支持就是模块化的,当我们没有去访问 ntfs 文件系统中的内容时,内存中就没 有加载该模块,但是,一旦挂载了 ntfs 文件系统,其相应模块就会被加载入内 存,以支持对 ntfs 文件系统的操作;一旦斜载 ntfs 文件系统后,如果 linux 系统中也没有别的地方需要用到 ntfs 文件系统,内核中的 模块管理程序就会 把该模块从内存中清除。linux 内核对动态加载模块的支持使得 linux 的内核可 以变得很小,运行起来更加高效。而且 linux 内核具有其他很多操作系统不具备 的功能,它可以进行重新编译,可以进行剪裁,可以根据自己的需要进行裁减, 增加自己需要的功能,删除不需要的功

18、能,例如在这里,我需要做一个用于管理 文件系统的小型系统,那么我就可以通过重新编译 linux 内核,去掉网络,声音, 游戏,usb 设备等很多不需要的内容,而增加那些在默认情况下没有进行支持的 文件系统的支持。 linux 内核对模块的加载是具有“堆砌”性的7。 (其含义可以用图 3 来说明: )比如,系统在运行时发现需要用到模块 a,但是模块 a 又不在内存中,那么系 统就需要加载模块 a,加载进来后,系统又发现,模块 a 在其实现过程中又用到 了模块 b 和模块 c,那么系统又会自动地把模块 b 和模块 c 加载进来。模块 a 和模块 b , c 的关系称为模块 a 位于模块 b,c 之

19、上(be on the top of),也称为模 块 b,c 为模块 a 所用(be used by)。为了实现自动动态加载模块,linux 为每个模 块建立了一些数据结构,这个结构体中有一个 count 成员,但 count 为 0 的时候, 证明此时已经没有进程或者别的模块使用该模块,系统将把这个模块卸载;否则, 表示该模块正被使用,系统不能将它卸载。系统只有在 count 成员为 0 后才会把 该模块从内存中删除。 module a module bmodule c 系统加载模块系统加载模块 a 后,发现后,发现 a 用到了用到了 b,c;而;而 b,c 都不在内存中,于都不在内存中,于

20、 是接着加载是接着加载 b,c 图 2.1 linux 内核模块的“堆砌”性 一个典型的桌面 linux 系统包括 3 个主要的软件层-linux 内核、c 库 和应用程序代码8。内核是唯一可以完全控制硬件的层,内核驱动程序代表 应用程序与硬件之间进行会话。内核之上是 c 库,负责把 posix api 转换为 内核可以识别的形式,然后调用内核,从应用程序向内核传递参数。应用程 序依靠驱动内核来完成特定的任务,但是根据实际情况,这样做需要较大的 内核,所以这里采用应用程序直接跟内核会话,这样既可以减少内核大小, 还可以提高运行速度。 所以我把毕业设计的目标定在尽量对 linux 内核进行裁减,

21、去除进程调 度,内存分配等许多内容和模块,使其只剩下文件管理功能,但它应该保留 虚拟文件系统的特征,能够访问多种不同格式的实际文件系统。而且它不需 要其他操作系统平台支持就可以单独运行。此时的这个文件系统管理程序应 该至少具有以下几大功能: 以 linux 方式组织文件。 复制文件。 删除文件。 编辑文件。 重命名文件。 创建和删除文件夹。 挂载和卸载其他种类的文件系统。 在具体实现上,我选用的 linux 内核版本为 2.4.20,这个版本发布与 2002 年 11 月 28 号,之所以选择它,因为它是公认的目前 linux 内核中最稳 定的一个高端版本,并且它的功能十分强大,这个内核版本支

22、持几乎所有在 市场上可以买到的处理器芯片;支持模块化调用;支持各种类型的网络;支 持许多种的文件系统;支持多种外部设备;支持即插即用设备;支持图形用 户界面,还支持很多种新型技术:例如蓝牙技术、红外线技术、ipv6 等。 2.2 实施方案 我的方案就是:先利用 linux 内核重编译技术,裁减 linux 内核,去掉 linux 内核对网络的支持,对 usb 接口的支持,对声音的支持,对 scsi 设 备的支持,对热插拔技术的支持,对新型技术的支持等;总之:裁减之后的 内核应该尽量只支持对文件的管理功能,当然,为了能正常运行,这个内核 还应该支持主流的 cpu 例如 x86 系列,为了实现虚拟

23、文件系统,它还应该 支持 ide 接口的硬盘,支持内存管理。第二步:通过分析内核相关部分的源 代码,修改其中一些部分,这样可以进一步缩减内核大小。这次裁减之后的 新内核应该具有如下的特征:除了管理文件系统所需要的底层支撑功能外, 其他与文件系统并列的其他功能都尽量去除了,它的功能就是对多种实际文 件系统进行管理,协调它们在计算机系统中共存。最后一步:将这个裁减后 的内核移植到一张软盘上面,使其可以单独运行,为了达到这个目的,我必 须先为这个系统制作一个引导程序,然后加上一个根文件系统和一些用于文 件系统的常用命令。因为我做这个系统的主要目的是研究 linux 中的虚拟文 件系统,所以对这个功能

24、的支持的必须的。在虚拟文件系统下面应该尽可能 地多支持实际文件系统,我的初步设想是至少应该包含多以下几种文件系统 的支持:windows 中的 fat16/32 文件系统,windows 中使用的 ntfs 文件 系统,linux 中用的 ext2/3 文件系统,linux 中使用的 minix 文件系统,光 盘上使用 iso9660 文件系统,管理设备时用到的设备文件系统。对于其他种 类的文件系统,视软盘的空间组织情况来决定是否提供支持。 概括起来说,这个小型系统分为四个部分:系统启动部分、系统内核部 分、外围程序部分、根文件系统。 对于系统启动部分:完成起来比较简单,可以选择使用 grub

25、,lilo,syslinux 等,也可以自己编写,鉴于时间上的关系,我决定使 用 grub 进行系统引导,利用 grub 程序将引导程序写入软盘的主引导扇 区(mbr)中去。 对于系统内核部分:需要先对内核进行重新编译,去除那些不必要的功 能,增加那些对文件系统的支持。 对于外围程序部分:使用一个在嵌入式 linux 领域使用很广泛的软件 busybox,它包含了一个 shell 程序和一些 linux 中常用的命令,但是它的 总大小却只有几百 kb,而且 busybox 也同时支持动态编译和静态编译,由 于 busybox 并没有包含所有的 linux 中的命令,在这里,还需要为管理文件 系

26、统自己添加几个命令,如 mount,umount 命令。 根文件系统采用 ext2 文件系统,创建必要的目录和文件,然后增加一些 用与系统初始化的脚本程序,如 inittab,fstab 文件。 当把上面四个部分都准备好以后,还需要将四者组装到一起,考虑到节 省空间的问题,这里准备使用 linux 内核所支持的虚拟磁盘技术(ram disk), 将外围程序部分先进行高度压缩,在系统启动后,把内核和压缩后的外围程 序部分都装入内存,然后解压外围程序部分,然后运行。 概括起来说,要做好这个小型系统,首先要编译出一个合适的内核,在 这里,为了空间大小的关系,最好是采用静态编译,制作好引导程序,有了

27、这两步,系统就基本可以运行了,但这时无法与用户交互,为此,还必须有 一个根文件系统和一个 shell,以上几个部件都准备好以后,系统也就基 本完成了。 第三章 对虚拟文件系统 的分析 3.1 虚拟文件系统 数据结构 linux vfs 提供了一种接口面向所有 linux 内核所能支持的文件系统。 竟管各种不同操作系统有着不同的格式与具体实现,但面向她们的接口保持 一致。 vfs 提供了一系列的数据结构和虚拟方法来访问文件系统。在 vfs 层提 供了一些默认的文件系统操作的实现,某个具体文件系统覆盖这些默认的实 现仅仅当它需要定制自己的实现过程时9。因为 linux 内核是用 c 写的, lin

28、ux 中虚拟方法的实现机制与那些用面向对象语言实现的虚拟方法有所不 同。在这里是用函数指针来实现虚拟函数的。 3.1.1 超级块 linux vfs 中一个最重要的概念就是超级块。总的来看,超级块包含所 有关于一个文件系统的关键信息。当某个文件系统被挂载时,超级块将被读 (通过一个系统调用 filesystem_read_super)并且,超级块包含访问文件系统其 他部分的必要的信息10。有些文件系统(例如 ms-dos fat)没有超级块,这 时,vfs 将为他们创建一个“虚拟”超级块。同时,由于在一个计算机系统 中可能存在多个文件系统,在虚拟文件系统中也就对应有多个超级块,为了 便于管理,

29、系统用一个双向链表存储它们。 super_block 结构体定义在。出来包含关于所有文件系统的 通用信息外,它还包含一个联合体,这个联合体中存放一些与某特定文件系 统具体相关信息的结构体。 struct super_block struct list_heads_list; kdev_ts_dev; unsigned longs_blocksize; unsigned chars_blocksize_bits; unsigned char s_lock; unsigned chars_rd_only; unsigned char s_dirty; struct file_system_type

30、 * s_type; struct super_operations * s_op; struct dquot_operations * dq_op; unsigned longs_flags; unsigned long s_magic; unsigned long s_time; struct dentry *s_root; struct wait_queue *s_wait; struct inode *s_ibasket; short ints_ibasket_count; short ints_ibasket_max; struct list_heads_dirty; union s

31、truct minix_sb_info minix_sb; struct ext2_sb_info ext2_sb; void *generic_sbp; u; ; s_list:这个成员被用来维持一个超级块双向链表,它包含 next,previous 指针。 s_dev:这是该文件系统的实际物理设备,有些文件系统(最著名的就是 pro 文件系统)不需要物理设备。对于那样的文件系统,这个成员将被忽略。 s_blocksize:这个成员包含该文件系统的块大小(以 byte 为单位)。 s_blocksize_bits:与前一成员具有相同的值,只是它是一 bit 为单位。 s_lock:这个成员被

32、用来给超级块加锁,从而保证对超级块的顺序访问。 s_rd_only:这个成员目前没有用。 s_dirty:这是一个标志,用来指示该超级块是否变脏,超级块是脏的如果 从它最后一次写入磁盘后已经发生了内容改变。 s_type:这是一个指针指向这个文件系统的 file_system_type 目录项。 s_op:这是一个指向该文件系统超级块操作集结构体的指针。 dq_op:这是一个指向磁盘配额结构体的指针。 s_flags:这个成员包含该文件系统的挂载标志,这些信息包含一些信息, 比如:这个文件系统是否需要一个设备,或者这个文件系统是否以只读方式 挂载。 s_magic:这是一个魔数用来标识呈现在设

33、备上的文件系统的类型。 s_time:标示超级块最后一个被修改的时间。 s_root:这是一个指向该文件系统跟目录的指针。 s_wait:这是一个包含当前正在等待访问超级块的任务的等待队列。 s_ibasket:这个成员暂时没有用到。 s_ibasket_count: 这个成员暂时没有用到。 s_ibaskte_max: 这个成员暂时没有用到。 s_dirty:这是该文件系统当前所有脏 i 节点所组成的链表。 super_operartions 结构体是放在中,它实际上是一个虚拟 函数表,该表包含所有用来操作超级块的函数。每个特定的文件系统都希望 覆盖这些函数并提供它们自己的函数指针集。 st

34、ruct super_operations void (* read_inode) struct inode *; void (* write_inode) struct inode *; void (* put_inode) struct inode *; void (* delete_inode) struct inode *; int (*notify_change) struct dentry*,struct iaddr *; void (*put_super) struct super_block *; void (*write_super) struct super_block *

35、; int (*statfs) struct super_block *,struct statfs *,int; int (*remount_fs) struct super_block *,int,char *; void (*clear_inode) struct inode *; void (*umout_begin) struct super_block *; ; read_inode:当一个索引节点从文件系统被读入时这个函数被调用。这个 函数负责填充索引节点结构体大多数成员(包括 inode_operation 指针)。 write_inode:这个函数用来将一个索引节点写出到磁盘

36、中。 put_inode:将索引节点从索引节点高速缓存中移出。 delete_inode:当某个文件被删除时,这个函数将被调用。它将释放文件 的索引节点和数据块并将空间归还给内存。 notify_change:当一个索引节点的属性改变时,这个函数将被调用。 put_super:当卸载一个文件系统释放超级块给内存时,这个函数将被调用。 write_super:这个函数将超级快写出到磁盘中。 statfs:这个函数用来统计该文件系统的有关信息。 remount_fs:当一个文件系统被重新挂载时(为了改变挂载标志)将被调用。 clear_inode:这个函数与 delete_inode 类似,但是它

37、是在索引节点被反散 列后并且所有对它的引用被清除了后调用的。 umount_begin:当 vfs 开始卸载一个文件系统时,这个函数将被调用。 3.1.2 索引节点 vfs 中另外一个重要概念就是索引节点。一个索引节点代表一个独立的 文件系统实体11,例如一个文件,目录,管道,套接字。文件系统中的每一 个实体有一个唯一的索引节点,但是通过使用硬链接和符号链接,使得通过 多个名字访问同一个实体成为现实。 索引节点结构体也存放在中。它包含很多信息,这些信息被 多种类型的文件系统的不同 i 节点使用。与 super_block 结构体一样,它也包 含一个联合体(成员由与特定文件系统相关,类型相关的结

38、构体)。 struct inode struct list_headi_hash; struct list_headi_list; struct list_headi_dentry; unsigned long i_ino; unsigned int i_count; kedv_ti_dev; umode_ti_mode; nlink_ti_nlink; uid_ti_uid; gid_ti_gid; kdev_ti_rdev; off_ti_size; time_ti_atime; time_ti_mtime; time_ti_ctime; unsigned longi_blksize; u

39、nsigned longi_blocks; unsigned longi_version; unsigned longi_nrpages; struct semaphorei_sem; struct semaphorei_atomic_write; struct inode_operation *i_op; struct super_block *i_sb; struct wait_queue *i_wait; struct file_lock *i_flock; struct vm_area_struct *i_mmap; struct page *i_pages; struct dquot

40、 *i_dquotmaxquotas; unsigned longi_state; unsigned inti_flags; unsigned chari_pipe; unsigned chari_sock; inti_writecount; unsigned inti_attr_flags; _u32i_generation; union struct pipe_inode_infopipe_i; struct minix_inode_infominix_i; void*generic_ip; u; ; i_hash:这个成员用来维持一个双向队列以解决因为散列冲突。 i_list:这个用来将

41、索引节点放到三个双向队列中。 i_dentry:这是一个与该索引节点对应的目录项链表。 i_no:这是一个用来标示该索引节点的数字,它在同一个文件系统中保持 唯一。 i_count: 该索引节点的引用数,当它变成 0 时,我们可以将它从内存中 移出。 i_dev:这是该索引节点所属文件系统的物理设备标示。 i_mode:这个成员包含文件类型和访问权限。 i_nlink:这是该索引节点的硬链接数,如果它为 0,该索引节点可以删除 了。 i_uid:该索引节点的主人的 user id。 i_gid: 该索引节点的主人的 group id。 i_rdev:如果该索引节点是一个设备文件对应的 i 节点

42、,它就是该设备标 示。 i_size:该索引节点对应的文件的字节数。 i_atime:上次访问的时间。 i_mtime:上次修改的时间。 i_ctime:文件创建的时间。 i_blksize:文件系统每个块的字节数。 i_blocks:文件所含有块数。 i_version:用来检查失效信息,当索引节点出现相关变化时,它将被更新。 i_nrpages:当前实际用来映射该文件的内存页数。 i_sem:这是一个信号量,它用来控制对索引节点的访问,阻止在读的时 候对 i 节点进行修改。 i_atomic_write:它用来标记一个对管道的原子性写操作正在被请求。它 必须在获得其他通用索引节点信号量前完

43、成。 i_op:这是一个指向该索引节点操作集的指针。 i_sb:指向该索引节点所属文件系统的超级块的指针。 i_wait:这是一个等待队列,该队列包含所有因访问该索引节点而等待的 任务,当该 i 节点变的可用时,这些任务将会被通知。 i_flock:这是一个文件锁链表,文件锁被同时保存在每个索引节点的单向 链表和系统为所有文件锁所设立的双向链表中。 i_mmap:指向用来映射该文件的内存区域。 i_pages:该文件所对应内存页链表。 i_dquot:磁盘配额信息。 i_state:用来标示该索引节点的当前状态,有关于该索引节点是否变脏, 是否被锁,是否存在与一个已经被释放的进程中等标志。 i

44、_flags:标示索引节点的的属性,当前属性包括:文件不变性,异步写, 不更新文件访问时间,文件是追加,该文件的配额被初始化。 i_pipe: 表示这个索引节点代表一个管道文件。 i_sock: 表示这个索引节点代表一个套接字文件。 i_writecount:为负表示写不允许,为正表示当前正在被写,为 0 表示其 他情况。 i_attr_flags:文件的属性信息,目前与 i_flags 相似。 inode_operations 结构体同样存在与中。它同样是一个虚函 数表包含操作 i 节点的函数。每个具体的文件系统不是只提供一组 i 节点操 作,她们通常提供一些不同的操作针对与不同的 i 节点

45、类型(目录,文件,管 道,套接字)。 struct inode_operations struct file_operations * default_file_ops; int (*create) struct inode *,struct dentry *,int; int (*lookup) struct inode *,struct dentry * ; int (*link) struct dentry *,struct inode *,struct dentry *; int (*unlink) struct inode *,struct dentry *; int (*symli

46、nk) struct inode *,struct dentry *,const char *; int (*mkdir) struct inode *,struct dentry *,int; int (*rmdir) struct inode *,struct dentry * ; int (*mknode) struct inode *,struct dentry *,int ,int; int (*rename) struct inode *,struct dentry *, struct inode *,struct dentry *; int (*readlink) struct

47、dentry *,char *,int; struct dentry *(*follow_link) struct dentry *, struct dentry *,unsigned int; int (*readpage) struct file *,struct page *; int (*writepage) struct file *,struct page *; int (*bmp) struct inode *,int; void (*truncate) struct inode *; int (*permission) struct inode *,int; int (*smp

48、) struct inode *,int ; int (*updatepage) struct file*,struct page *, unsigned long,unsigned int ,int; int (*revalidate) struct dentry *; ; default_file_ops:这是一些默认的文件操作用来打开一个文件,打开操作 会根据文件类型提供恰当的操作。 create:用来创建一个新的索引节点。 lookup:该函数用来查找目录项并返回对应的索引节点,此操作只提供给 目录。 link:用来建立一个硬链接,从一个目录项到一个特定索引节点,在执行 操作之前必须进

49、行检查以保证硬链接与原文件在同一个文件系统中。 unlink:从一个文件系统中删除一个索引节点。 symlink:建立一个目录项到某索引节点的符号链接。 mkdir:建立一个子目录。 rmdir:删除一个特定子目录。 mknode:用来创建一个设备文件,命名管道,套接字。 rename:通过删除原目录项,建立新目录项来改变一个文件的名字。 readlink:用来出来一个有符号链接所指向的文件。 readpage:被内存映象文件用来读取一页进入内存。 writepage: 被内存映象文件用来写一页到磁盘中。 bmp:用来将文件中某块映射到调用者的地址空间中。 truncate:用来调整文件的长度

50、,它可以缩短或者提升文件的长度。 permission:检查某个特定 i 节点的的访问权限。 smp:与 bmp 类似,只是它以扇区为单位。 updatepage:与 writepage 类似,但是它会做附加的检查来看是否真需要 写。 revalidate:用来保证某个文件的高速缓存是最新的。 3.1.3 文件 vfs 中第三个重要对象就是文件了。任何时候,当一个进程打开一个文 件,一个新的文件对象就创建了,这就意味着多个文件对象可以对应与同一 个物理的文件。并且允许多个进程(或者同一个进程)去同时访问一个文件的 不同部分12。文件结构体,同样也存在与比 super_block 结构体 和 i

51、node 结构体要简单。 struct file struct file*f_next,*f_pprev; struct dentry *f_dentry; struct file_operations * f_op; mode_tf_mode; loff_tf_pos; unsigned intfcount,f_flags; unsigned longf_reada,f_ramax,f_raend,f_ralen,f_rawin; struct fown_structf_ower; unsigned longf_version; void*private_data; ; f_next,f_p

52、prev:用来实现一个双向的文件结构体链表。 f_dentry:目录项(我们通过这个目录项打开对应的文件)。 f_op:指向文件操作表的指针。 f_mode:包括该文件的访问权限。 f_pos:存放目前文件的偏移量的指针 fcount:该文件的引用次数。 f_flags:包含一些标志:是否打开为读,是否打开为写,是否写之前清空。 f_reada:一个标志用来指示是否使用提前读。 f_ramax:当前的提前读的最大页面数。 f_raend:指向提前读入的页面之后的页面中第一个字节。 f_ralen:提前读入的最后一块的大小。 f_rawin:目前的提前读窗口大小。 f_ower:这个结构体包括:

53、用户 id,进程 id,它还包括异步 i/o 中发送 给进程的实时信号(该信号用来通知进程,文件已经准备好 i/o)。 f_version:用来检查失效信息,当一个对文件的改变发生后,它被更新。 private_data:指向一些不透明数据的指针,vfs 将保留但不访问这个指 针。 file_operations 结构体定义在,同样,它是一个虚函数表包含 用来操作文件的函数。 struct file_operations loff_t (*llseek) struct file *,loff_t,int; ssize_t (*read) struct file *,char *,size_t,

54、loff_t *; ssize_t (*write) struct file *,char *,size_t,loff_t *; int (*readdir) struct file *,void *,filldir_t; unsigned int (*poll) struct file *,struct poll_table_struct *; int (*ioctl) struct inode*,struct file*,unsigned int,unsigned long; int (*mmap) struct file *,struct vm_area_struct *; int (*

55、open) struct inode *,struct file*; int (*flush) struct file*; int (*release) struct inode *,struct file*; int (*fsync) struct file*,struct dentry*; int (*fasync) int,struct file*,int; int (*check_media_change) kdev_t dev; int (*revalidate) kdev_t dev ; int (*lock) struct file *,int,struct file_lock

56、*; ; llseek 负责设置文件的当前偏移量指针。: read:将文件中的数据复制到特定缓冲区。 write:将缓冲区中的数据写入文件指针所指的位置。 readdir:从目录中读取下一个目录项。 poll:检查目前是否可以将数据读入或者写出。 ioctl:用来设置和读取设备文件。 mmap:将文件中的一个扇区映射到当前进程的用户地址空间。 open:当一个文件被打开是这个函数被调用。 flush:当 vfs 关闭一个文件时将调用这个函数。 release:当一个文件的引用计数器为 0 且即将从内存中移出时此函数被调 用。 fsync:用来保证一个文件所有被修改的缓冲区都被写回磁盘。 fas

57、ync:用来打开或者关闭异步文件更新机制。 check_media_change:这个函数只用在支持移动介质的块设备,它检查从 上次访问后介质是否有改变。 revalidate:这个函数只用在块设备上,当设备介质改变后它将被调用来更 新必要的设备参数。 lock:用来在一个文件上获取文件锁。 3.2 文件系统高速缓存 为了提高文件系统的性能,linux 提供两中文件系统高速缓存,缓冲区 高速缓存用来暂存那些正在读取或者写入到某文件的数据,目录高速缓存 (dcache)暂存目录项信息,从而提高了文件查找的效率13。 3.2.1 缓冲区高速缓存 缓冲区高速缓作为一个接口存在与文件系统和实际物理设备

58、之间,当一 个文件系统想从一个设备中读取或者想向一个设备写入数据时,它将调用一 些为缓冲区高速缓设置的函数,缓冲区高速缓存所隐含的主要思想是把进程 从存取慢速磁盘数据的等待中解放出来。因此,如果同时写入太多数据,结 果反而是欲速则不达。反之,可以把数据划分成小片并周期性地写入磁盘, 以使 i/o 操作对用户进程速度的影响最小,用户所感受的响应时间最小。 内核为每一个缓冲区维护很多信息,这些信息用来缓和写操作,这些信 息包括一个“脏(dirty) ”位,表示内存中的缓冲区已经被修改,必须写到 磁盘中去,还包括一个时间标志,表示缓冲区被刷新到磁盘之前在内存中停 留了多长的时间。缓冲区高速缓存的大小

59、可以变化。当需要新缓冲区而现在 又没有可用缓冲区时,页框按需要被分配。当空闲内存变得不足时,就释放 缓冲区并反复使用相应的页框。 缓冲区数据结构中一个重要域就是 b_count,它是对应缓冲区所使用的 一个引用计数器,在对缓冲区操作之前加 1,操作之后减 1。它主要起到安 全所的作用,因为只要引用计数器不为 0,内核就永远不会撤销这个缓冲区。 相反,内核会周期性或在空闲内存不足的时候检测已用缓冲区,只有那些引 用计数器为 0 的缓冲区才能被撤销,也就是说,虽然引用计数器为 0 是一个 缓冲区可以属于缓冲区高速缓存,但是,不能确定这个缓冲区在高速缓存中 可以存在多长时间。 缓冲区高速缓存包括两种

60、数据结构14: 描述高速缓存中缓冲区的一组缓冲区首部。缓冲区首部 描述了与一对给定的设备号和块号相关的缓冲区。 有助于内核快速找到缓冲区首部的散列表。 通常情况下,缓冲区首部可能为以下状态之一。 未用的缓冲区首部:该对象是可用的,但其域中的值没 有什么意义。 空闲缓冲区的缓冲区首部:其 b_data 域指向一个空闲缓 冲区,而 b_dev 域的值是 b_free,其实这个时候,这个缓冲区 是可用的,但其缓冲区首部本身是不可用的。 已用缓冲区的缓冲区首部:其 b_data 域指向一个存放缓 冲区高速缓冲中缓冲区。 异步缓冲区首部:其 b_data 域指向一个用来实现页 i/o 操作的临时缓冲区。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论