linux文件管理程序定义了一个单一的文件内部视图,应用程序用它来读取和修改卸载所有存储设备上的文件。每类存储设备在它的文件管理程序中实现相同的视图。
文件管理程序负责取放包含应用程序所读写的字节流部分的块。每当读写字节流的任何部分时,它判断应该读写哪个磁盘块。
linux文件管理程序设计为让应用程序使用一组有posix所制定的固定函数来操作文件。Open,close,lseek,read,write,ioctl等等。文件管理程序中一个与文件系统独立的部分处理普通工作部分,如检查访问权限和决定何时需要读写磁盘块。文件管理程序的另一部分处理所有与文件系统相关的工作部分,如判断块在磁盘上的定位和知道设备驱动程序读写特定块。两部分结合起来是的在处理磁盘上的文件时,linux在API级别提供了一组固定的操作,即文件使用windows OS/MINIX或其他操作系统写入。
linux文件管理程序API简历在虚拟文件系统VFS输出的抽象文件模型上。VFS执行与系统独立的文件操作,操作系统设计人员对VFS提供了扩展以完成所以需要的与文件系统相关的操作。发行版本2.x可以读写符合各种格式的磁盘文件,包括MS-DOS,MINIX,/PROC,以及叫做ext2的linux特定格式和其他一些格式。当然,在版本2.2.12中包含特定的与文件系统相关的不见用以在所支持的各种外部格式之间翻译VFS操作和格式。
VFS的核心是转换。转换switch为用户空间程序提供了标准文件管理程序API并简历内部接口。该借口由支持MS-DOS/MINIX/EXT2等文件的不同文件系统翻译程序所使用。通过实现一个新的与文件系统相关(翻译程序)的不见可以提供对一种新文件系统的支持。每个这样的翻译程序提供了VFS转换可调用的功能。并可以降外部文件表达形式翻译为内部形式的函数。因此,翻译程序负责:
决定用于组织磁盘设备上磁盘块的策略
读写磁盘属性
读写外部文件描述符信息
读写包含文件数据的磁盘块
VFS文件系统模型模仿传统的UNIX文件系统,一个VFS文件描述符称为一个inode(虽然他有自己独特的格式支持多文件系统方法)。虽然VFS包含它自己格式的文件描述符,当文件打开时,每个与系统相关的文件翻译程序将外部描述符的内容转换成VFS inode格式。所以它假设外部文件目录至少包含每个存储于该目录文件的名字和其文件描述符的地址。
VFS至少具备以下有关磁盘组织的结构:
磁盘上的第一个山区是用于存储引导程序的引导块。文件系统不使用这个引导块,但它假设引导块在每个文件系统上都存在。一个超级快包含磁盘相关信息,如一个磁盘块中的字节数
磁盘上的外部文件描述符描述每个文件的特性。
数据块链接到每个包含数据的文件。
在VFS管理特定的文件系统前,必须编写该类型的翻译程序并在VFS中注册。VFS的register_filesystem()函数告知VFS它所需要的基本信息,包括文件系统类型的名称和文件系统read_super()函数的入口点,该函数并在文件系统装载时使用。
当装载文件系统是,VFS创建sturck super_block数据结构的一个示例来容纳管理新文件系统所需要的信息。然后VFS调用新闻间凶的read_super()函数来获取包含在文件系统中类似超级块中的信息,翻译该信息并且将它保存在struct super_block数据结构中。
该超级块包含VFS需要用来管理文件系统的各种字段,尤其是字段
struct super_operations *s_op;
这个s_op字段制订了一组函数用于写回超级块到磁盘/读写磁盘上的inode/检查超级块的状态等等。所以read_super()是在文件系统类型注册时绑定到VFS的引导函数。在装载时,VFS读取超级块之后,它可以在需要时使用super_operation 函数来操作磁盘上的超级块。super_operations定义了私有的,磁盘上超级块抽象数据类型的一个公共接口。从而使得转换成徐可以按照其选择实现超级块和inode。
为了打开一个文件,文件管理程序在存储系统上搜索指定的路径名。搜索可能是一个扩展的过程。这是因为它需要,比如说,打开路径名中的每个目录(从路径中的最高明明目录开始),在路径名中搜索下一个文件或目录的路径,以及打开哪个目录或文件。如果搜索遇到一个安装点,那么它从一种文件系统转移到另一种文件系统并继续搜索。因此搜索可能从,如Ext2文件开始,但最终在一个MS-DOS文件系统中找到文件。
一旦文件管理程序已经在一个目录中定位到文件,VFS检查文件和用户权限以确保用户京城有权限打开文件。如果进程具有正确的权限,那么VFS将会简历各种表项来管理I/O。首先,在进程的文件描述附表中创建一表项。 每个进程都有一个文件描述符表。二每个打开的文件都在表中有一表项。表项由一个调用返回的小整数值识别。之后对该文件的引用都使用该值。注意当创建进程时,所创建的文件描述符表具有以下三个表项:
stdin 具有表项识别符0
stdout 具有值1
stderr 具有值2
随后成功的open()和pipe()调用降在文件描述符表的为止3创建一表项。
文件描述符表中的表项指向打开文件表中一个叫做文件结构(struct file)的表项。文件结构表项容纳了与打开文件的进程相关的状态信息,如这个进程使用的文件位置值。如果两个不同的进程打开同一个文件,那么每个进程都将有它自己的文件结构表项,从而有它自己对于该文件位置的拷贝。文件结构表在贮存中穿件以后,它引用VFS的inode。
VFS通过读取外部文件描述符(通过使用在超级块s_op列表中指定的read_inode()函数在内存你中穿件inode并将其翻译成VFS inode格式。正如超级块为super_operation列表提供一个字段,inode提供以下字段定义一个inode操作列表):
struct inode_operations *i_op;
struct inode_operations是一个VFS需要用来操纵文件块的操作列表,如create()lookuo()link()和mkdir()。同事提供的还有在i_op列表不提供操作时所使用的默认操作列表。
在VFS中分配的inode被分配给一个单一的大链接列表。每当VFS打算扫描所有的inode时这是游泳的,但是,当VFS想要引用一个特定的inode时访问减慢。所以inode引用也被装入一个打开的哈希表中,在这里他们通过一些(也可能是一个)表探针(probe)访问。
文件管理程序改变内存中inode版本的当时,这些改变不会被复制到存储设备上的外部文件描述符中。相反,当文件关闭或者应用程序产生一个syc命令时,内存中的inode版本被欧诺个与周期性的分别费续保辅存上的外部文件描述符。当一个文件打开并且最近对inode做出了更改时,机器停机,内存中inode版本可能和磁盘上的外部文件描述符不同,结果可能导致不一致的文件系统,因为在内存中的inode破坏时降丢失有关文件的最新消息。例如,如果内存中indoe的块指针已经改变(对磁盘块也做出了相应的改变),那么磁盘上可能有一个外部文件描述符与磁盘上的各种存储块指针不一致。
当文件打开时,创建struct file的一个实例(文件结构表中的表项)。在该文件中,字段struct file_operations *f_ops;
指定read(),write(),lseek(),select()等的入口点,它们用于执行和系统相关的i/o操作。同事包括的嗨哟一组在inode中指定的默认file_operations,这样如果任何特定文件系统(如Lseek())没有在f_ops列表中指定,那么将使用来自默认列表中的函数。
这些例程的实质目标是在用户空间地址和辅存块之间移动信息。read()调用与文件系统相关的操作降数据从磁盘转移到系统缓冲区。在哪里数据被写入磁盘。这些例程还必须排列和分散字节流。
一个文件被组织为连续的字节留。这表明应用程序通常把文件作为一个字节流来读写,二不是随机访问文件中的字符。结果是,使用缓冲的方法可以极大地提高系统的性能。在度缓冲中,文件系统在字节留之前读取,去除包换出现在当前文件指针所指字节之后字节流部分的磁盘块。在写缓存中,每当磁盘设备可用时一个满磁盘块就准备写。因此,应用程序不必等待进入缓冲,因为在他们被引用时就已经读取。另外,也不必等待写操作,因为在应用程序逻辑上将字节写入流之后,它们将作为一个后动作发生。
linux试图使用最大限度的内存来提供I/O缓存区。它创建一个动态缓冲区告诉缓存,其大小依赖于当前要求提供虚拟存储的页框的数量。虚拟存储系统不需要的页面可以用作缓冲区高速缓存。当发生一个缺页错误时,缓冲区告诉缓存是虚拟存储系统首先搜寻页框的地方之一。
块缓存是一个相对复杂的任务。这部分的文件管理程序必须满足以下每个约束条件:
每个为读操作打开的文件应该具有一个或多个缓冲区,他们含有在进程时机请求信息之前已经从磁盘读取的信息。
每个为写操作打开的文件具有一组缓冲区,他们包含在设备可用时写到设备的信息。
与存储设备上的块相同的满输出块不应该被写回。
当虚拟内存不需要所有的物理内存时,缓冲区告诉缓冲应该扩大。当虚拟内存需要更多的物理内存时,缓冲区高速缓存应该减小(但不影响将要进行的I/O)
缓冲区大小可变
缓冲区可以在进程间共享
Ext2文件系统
Ext2文件系统模仿BSD快速文件系统。每个磁盘被格式化为可以容纳一组块组(block group),每个都包括一个超级块,组描述符信息,块组中文件inode的表以及数据块。
超级块包含下列信息:
inode数量
空闲inode数量
块细节
分配限制
最后安装时间和最后一次写入时间
错误和状态
其他管理信息
块描述符包含特定块组中块的细节信息。对于磁盘块大小为1024字节(每个块的大小为1024=EXT2_MIN_BLOCK_SIZE<EXT2_BLOCK_SIZE<EXT2_MAX_BLOCK_SIZE=4096)的块的描述符,一个块可能容纳多达8192个。块描述符也包含块组中文件的inode集合。
inode使用一种变体的索引分配方案来组织块,它包括指向15个不同存储块的指针。文件的钱12个块直接索引自inode中15个指针的前12个,后三个指针通过索引块用做简介指针。如果文件管理程序每个块配置为最大尺寸的4kb,则inode中的12个直接指针最大可容纳48KB的文件。如果一个文件请求超过12个块。那么文件系统分配一个索引块并将其链接到一次间接(第13个)指针。因此,块13~K通过由inode中第13个指针确定的间接块从inode间接地址。类似地,更大的文件使用第14个指针指向一个二次间接块,二最大的文件使用第15个指针只想一个三次间接块。
阅读(913) | 评论(0) | 转发(0) |