为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

文件系统

2011-11-14 4页 pdf 111KB 29阅读

用户头像

is_264626

暂无简介

举报
文件系统 文件系统在操作系统中是一个非常重要的概念。简单地说,文件系统是操作系统中用于明确 磁盘或分区上的文件的方法和数据结构,即磁盘上组织文件的方法。文件系统的存在,使得 数据可以被有效而透明的存取访问。 Linux根文件系统应该包括支持 Linux系统正常运行的基本内容,如系统使用的软件和库,用 户使用的应用软件。具体内容如下: 1. 基本的文件系统结构,包含一些必要的目录如:/dev、/bin、/etc、/lib、/usr、/tmp等 2. 基本库,如 glibc库 3. 基本的系统配置文件,如 rc、initta...
文件系统
文件系统在操作系统中是一个非常重要的概念。简单地说,文件系统是操作系统中用于明确 磁盘或分区上的文件的方法和数据结构,即磁盘上组织文件的方法。文件系统的存在,使得 数据可以被有效而透明的存取访问。 Linux根文件系统应该包括支持 Linux系统正常运行的基本内容,如系统使用的软件和库,用 户使用的应用软件。具体内容如下: 1. 基本的文件系统结构,包含一些必要的目录如:/dev、/bin、/etc、/lib、/usr、/tmp等 2. 基本库,如 glibc库 3. 基本的系统配置文件,如 rc、inittab等脚本文件。 4. 必要的设备文件支持,如/dev/fd0。 5. 基本的应用程序,如 ls 、cp、mv 文件存放规则 为了实现各种 Linux 版本系统的标准化,各种不同的 Linux 版本都会根据 FHS(Filesystem Hierarchy Standard)标准来进行系统管理,这也使得 Linux系统的兼容性大大提高。FHS规 定了两级目录,第一级是根目录下的主要目录,根据目录名称可以得知其中应该放置什么样 的文件,如/etc 应该放置各种配置文件,/bin/sbin 目录应该放置相应的可执行文件等。第二 级目录主要针对/usr、/var做出更深层次目录的定义。 应用程序通常需要共享库才可以工作,所以添加共享库对根文件系统是必需的。 每个 Linux或嵌入式 Linux系统都需要一个 C库,C库提供了常用的文件操作,内存管理操 作等函数,许多基于 X86架构的 Linux系统使用 glibc库, glibc库对于内存的消耗比较多, 对于嵌入式开发来说,如果内存资源受到严格限制,采用 glibc是不可接受的。uClibc是针 对嵌入式系统开发的完整且紧凑的 C库,可代替 glibc。 虚拟文件系统(VFS)作为内核子系统,为用户空间程序提供了文件系统接口,系统中的所 有文件系统依靠 VFS 系统协同工作。通过虚拟文件系统,我们可以利用标准的 UNIX 系统 调用对不同介质上的不同文件系统进行读写操作,如下图所示: ext3的硬盘 ext2格式的软盘 虚拟文件系统VFS cp命令 VFS执行的动作:使用 cp命令从 ext3文件系统格 式的硬盘拷贝数据到 ext2文件系统格式的软盘上 VFS使得用户可以直接使用 open( )、read( )、write( )这样的系统调用而无需考虑具体的 文件系统和实际物理介质。这听起来并没有什么新奇的——我们早就认为这是理所当然的— —但是,使得这些通用的系统调用可以跨所有的介质和文件系统执行,绝非微不足道的成绩。 更了不起的是,系统调用可以在这些不同的文件系统和介质之间执行——我们可以使用标准 的系统调用从一个文件系统拷贝或移动数据到另一个文件系统。老式的操作系统如 DOS是 无力完成上述工作的。正是由于包括 Linux在内的现代操作系统引入了抽象层,通过虚拟接 口访问文件系统,才使这种协作性和通用性成为可能。 之所以可以使用通用接口对所有类型的文件系统进行操作,是因为内核在它的底层文件 系统接口上建立了一个抽象层,该抽象层使 Linux能够支持各种文件系统,即使它们在功能 和行为上存在很大差别。为了支持多文件系统,VFS 提供了一个通用文件系统模型,该模 型包括了我们所能想到的文件系统的常用功能和行为,当然,该模型源于 UNIX风格的文件 系统。 VFS 抽象层之所以可以衔接各种文件系统,是因为它定义了所有文件系统都支持的基 本抽象接口和数据结构。同时实际文件系统也将自身的诸如“如何打开文件”,“目录是什么” 等概念在形式上与 VFS 的定义保持一致。因为实际文件系统的代码在统一的接口和数据结 构下隐藏了具体的实现细节,所以在 VFS 层和内核的其它部分看来,所有文件系统都是相 同的,它们都支持像文件和目录这样的概念,同时也支持像创建文件和删除文件这样的操作。 内核通过抽象层能够方便、简单地支持各种类型的文件系统,实际文件系统通过编程 提供 VFS 所期望的抽像接口和数据结构,这样,内核就可以毫不费力地和任何文件系统协 同工作。并且,这样提供给用户空间的接口,也可以和任何文件系统无缝地连接在一起,完 成实际工作。 其实在内核中,除了文件系统本身外,其他部分并不需要了解文件系统的内部细节。 比如一个的用户空间程序执行如下操作: write(f, &buf, len) 该代码将 buf指针指向的长度为 len字节的数据写入文件描述符 f对应的文件的当前位置。 这个用户调用首先被一个通用系统调用 sys_write()处理,sys_write()函数要找到 f所在 的文件系统实际给出的是哪个写操作,然后再执行该操作。实际文件系统的写方法是文件系 统实现的一部分,数据最终通过该操作写入介质(或执行这个文件系统想要完成的写动作)。 下图描述了从用户空间的 write()调用到数据被写入磁盘介质的整个流程。 write( ) sys_write( ) 文件系统的 写方法 物理 介质 用户空间 VFS 文件系统 物理介质 write()调用将来自用户空间的数据流,首先通过 VFS的通用系 统调用,再通过文件系统的特殊写方法,最后写入物理介质 UNIX系统将文件的相关信息(如访问权限、大小、拥有者、创建时间等信息)和文件 本身这两个概念加以区分。文件的相关信息,被存储在一个单独的数据结构中,该结构被称 为索引节点(inode)它其实是 index node的缩写。 文件的控制信息存储在超级块中,超级块是一种包含文件系统信息的数据结构。超级块 中包含了关于该硬盘或分区上的文件系统的整体信息,如文件系统的大小等 在 UNIX文件系统的实现中,文件信息按照索引节点形式存储在单独的块中,控制信息 被集中存储在磁盘的超级块中。Linux的 VFS的目标就是要保证能与支持和实现了这些 概念的文件系统协同工作。像如 FAT 或 NTFS 这样的非 UNIX 风格的文件系统,虽然也可 以在 Linux上工作,但是它们必须经过封装,提供一个符合这些概念的界面。比如,即使一 个文件系统不支持索引节点,它也必须在内存中装配索引节点结构体,就像它本身包含索引 结点一样。再比如,如果一个文件系统将目录看作是一种特殊对象,那么要使用 VFS,就 必须将目录重新示为文件形式,通常,这种转换需要使用引入一些特殊处理,使得非 UNIX 文件系统能兼容 UNIX 文件系统的使用规则并满足 VFS 的要求。通过这些处理,非 UNIX 文件系统便可以和 VFS一同工作了,只是性能上多少会受一些影响。 VFS 其实采用的是面向对象的设计思路,使用一族数据结构来代表通用文件对象。这 些数据结构表现得就像是对象。因为内核是使用 C 代码实现的,没有直接利用面向对象的 语义,所以内核中的数据结构都使用 C 结构体实现。但这些结构体包含数据的同时也包含 操作这些数据的函数指针,其中的操作函数由具体文件系统实现。 VFS有四个主要的对象类型,它们分别是: z 超级块对象,它代表一个已安装的文件系统。 z 索引节点对象,它代表一个文件。 z 目录项对象,它代表一个目录项。 z 文件对象,它代表由进程打开的文件。 超级块对象 各种文件系统都必须实现超级块,该对象用于存储特定文件系统的信息,通常对应于存 放在磁盘特定扇区中的文件系统超级块或文件系统控制块。 超级块对象由 super_block 结构体表示,定义在文件中。创建、管理和销毁 超级块对象的代码位于文件 fs/super.c中。超级块对象通过 alloc_super()函数创建并初始化, 在文件系统安装时,内核会调用该函数以便从磁盘读取文件系统超级块,并且将其信息填充 到内存中的超级块对象中。 超级块对象中最重要的一个域是 s_op,它指向超级块的操作函数表。超级块的操作函 数表由 super_operations 结构体表示,定义在文件中。该结构体的每一项都是一 个指向超级块操作函数的指针,超级块操作函数执行文件系统和索引节点的低层操作。 索引节点对象 索引节点对象包含了内核在操作文件或目录时需要的全部信息。对于 UNIX 风格的文 件系统来说,这些信息可以从磁盘索引节点直接读入到 VFS 的索引节点对象中。如果一个 文件系统没有索引结点,那么,不论这些相关信息在磁盘上是怎么存放的,文件系统都必须 从中提取这些信息。一个索引结点代表文件系统中的一个文件。 索引节点对象由 inode结构体表示,定义在文件中。和超级块操作一样,索 引节点对象中的 i_op项非常重要,它描述了 VFS用以操作索引结点对象的所有方法——这 些方法由文件系统实现。索引节的点的操作函数表由 inode_operations 结构体表示,定义在 文件中。 目录项对象 VFS把目录当作文件对待,所以在路径/bin/vi中,bin和 vi都属于文件,bin是特殊的 目录文件,而 vi 是一个普通文件,路径中的每个组成部分都由一个索引节点对象表示。虽 然它们可以统一由索引节点表示,但是 VFS 经常需要执行目录相关的操作,比如路径名查 找等。路径名查找需要解析路径中的每一个组成部分,不但要确保它有效,而且还需要进一 步寻找路径的下一部分。为了方便进行目录相关的操作,VFS 引入了目录项的概念,每个 dentry代表路径中的一个特定部分。对前一个例子来说,/,bin和 vi都属于目录项对象。前 两个是目录,最后一个是普通文件。必须明确一点,在路径中,包括普通文件在内,每一个 部分都是目录项对象。 目录项对象由 dentry 结构体表示,定义在文件中。不同于前面的两个 对象,目录项对象没有对应的磁盘数据结构,VFS 根据字符串形式的路径名现场创建它。 而且由于目录项对象并非真正保存在磁盘上,所以目录项结构体没有是否被修改的标志。 dentry_operation 结构体指明了 VFS 操作目录项的所有方法。该结构体定义在文件 中。 文件对象 文件对象表示进程中已打开的文件。如果我们站在用户空间来看 VFS,文件对象就会 进入我们的视野。进程直接处理的是文件,而不是超级块、索引节点或目录项。所以不奇怪: 文件对象包含我们非常熟悉的信息(如访问模式,当前偏移等),同样道理,文件操作和我 们非常熟悉的系统调用 read()和 write()等也很类似。 文件对象是已打开的文件在内存中的表示。该对象(不是物理文件)由相应的 open() 系统调用创建,由 close()系统调用销毁,所有这些文件相关的系统调用实际上都是文件操作 表中定义的方法。因为多个进程可以同时打开和操作同一个文件,所以同一个文件也可能存 在多个对应的文件对象。文件对象仅仅在进程观点上代表已打开的文件,它反过来指向目录 项对象(反过来指向索引节点),其实只有目录项对象才表示已打开的实际文件。虽然一个 文件对应的文件对象不是唯一的,但对应的索引节点和目录项对象无疑是唯一的。 文件对象由 file结构体表示,定义在文件中,类似于目录项对象,文件对象 实际上没有对应的磁盘数据。所以在结构体中没有代表其对象是否为脏,是否要写回磁盘的 标志。文件对象通过 f_dentry指针指向相关的目录项对象。目录项会指向相关的索引节点, 索引节点会记录文件是否是脏的。 和其它 VFS 对象一样,文件操作表在文件对象中也非常重要。跟 file 结构体相关的操 作与系统调用很类似,这些操作是标准 UNIX 系统调用的基础。文件对象的操作由 file_operations结构体表示,定义在文件中。
/
本文档为【文件系统】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索