理解操作系统4--文件管理疑惑总结

来源:互联网 发布:java iterator用法 编辑:程序博客网 时间:2024/06/05 07:53

文件和文件系统

文件系统是操作系统的一个重要组成部分,负责管理系统里面的文件,为用户提供文件操作接口,文件系统由实施文件管理的软件和被管理的文件组成,为用户提供使用文件的操作接口,文件系统软件属于系统内核代码,文件按照特定的格式存放在磁盘分区。文件系统通常安装磁盘分区划分,每个分区对应一个独立的文件系统。

文件系统提供的功能:

  • 提供文件访问的接口,实现文件的“按名存取”
  • 实施对文件的操作,包括建立,读写,检索,修改,删除。
  • 管理文件分区的存储空间,实施存储空间的分配,回收,与重组
  • 实现对文件的共享,保密和保护措施

文件的描述

文件系统为每个文件建立了一个文件控制块(FCP),类似与进程里面的PCB,对FCB操作就是对文件操作,相应的对文件操作FCB内容也会变化,文件被删除对应的FCB消失。

文件目录

因为文件和PCB是一一对应的,管理文件就是管理FCB,文件系统采用目录组织文件,通过目录将所有的FCB分层次组织在一起,为了方便操作,目录信息也必须长久保存,所以目录也需要以文件的形式存储,系统定义了一种特殊的文件---目录文件,其内容是一个文件列表,每个表项是一个文件的PCB,在目录里成为目录项,因此目录可以作为另一个目录的目录项。从而构成目录的层次结构。目录的功能主要是实现文件的按名字存取,即用户只要提供文件名字就能够进行各种操作,目录实现了文件名到文件物理存放位置 映射,合理的组织了文件。


文件的结构


1.文件的格式

是终端用户通过应用程序来使用文件的,从他们角度看到的文件的格式,比如doc对应word,根据结构的格式分为结构化文件,如列表文件,数据库文件。半结构化文件,如web文档,图片,图像,无结构化文件,如纯文本文件。

2.文件的逻辑结构

逻辑结构是文件系统的直接用户应用程序,所看到的文件结构,逻辑结构取决与文件系统接口的设计,它决定了文件的存储方式,应用程序按照逻辑结构访问文件系统的文件,并且在此基础上,构造出各种应用结构呈现给应用程序用户,应用程序负责文件的格式和逻辑结构之间的映射,文件的逻辑结构有记录式文件和流式文件。记录式文件不好,只介绍流文件

流式文件

安装字节序列组成的文件,是无结构文件,用户程序访问文件的时候只要指定文件的偏移位置和要读写的字节数,文件系统可以很方便的存取指定部分的文件内容,流式文件就像一张白纸,没有任何格式上的限制,写文件的时候用户程序按照自己定义的结构组织数据,然后把他们组织成字节流写入文件,读取的时候,在按照自己的结构解释文件的内容就可以了。和记录式文件不同的是,流式文件将和文件格式有关的结构交给了用户程序由用户程序按照自己结构解释给人。而不必按照预先规定的格式读取存取了。

3.文件的物理结构

文件的物理结构是存储结构,是文件在外存上的存储组织形式,文件系统负责文件的逻辑结构和物理结构之间的映射。

根据磁盘的结构,确定磁盘扇区的参数有三个,柱面号,磁头号,扇区号。访问磁盘时,先将磁头移动到指定的柱面上,等待要访问的扇区移动到磁头下面,然后由指定的磁头
访问指定的扇区,由于磁盘是高速设备,一次读写可同时访问多个相邻的扇区,因此文件系统访问磁盘的时候是以块为单位来传输数据的,块由若干个相邻的扇区构成,块的大小取决于文件系统的设置和磁盘容量。必须是磁盘扇区大小的2的整数倍。为了便于磁盘的管理,磁盘的存储空间被分成几个分区,每个分区由一个文件系统管理,文件系统只能看到自己所在的分区内的空间,从文件系统来看磁盘分区的存储空间是许多逻辑上连续的块组成,文件系统以块为单位保存数据,访问文件的时候只要指定块号就可以了,屏蔽了扇区的结构。

连续文件 

将文件的内容按照逻辑顺序放在连续的存储块。假设磁盘空间采用4kb大小的块,文件A的大小是25K,系统为它分配了连续的7块,起始块号和占用的块号记录在FCB里面。
优点:因为连续,磁头移动较少,存储性能号
缺点:限制了文件的动态增长,会产生磁盘碎片。
连续文件主要用于顺序存储设备,如磁带或者只读存储设备--光盘。

链接文件

主要就是文件不必放在连续的块,可以用指针连起来,造成磁头移动较多,顺序存取方便,但是随机存取缓慢,指针占据了一些字节,每个块的字节数不是2的幂,因为很多程序都是按照2的幂为长度读写的,所以增加了读写的复杂读。
对链接文件的改进就是把指针提取出来,单独放在一个链表里面,链接表里面对应的每一项都是下一个存储块,链接表占用的空间小可以放在内存里。需要访问文件的时候只要访问链表就可以了,WINDOWS 下的FAT就是这样的。

链接文件允许文件动态变化,外存利用空间高,缺点是存储效率低,尤其是直接存储,适合小文件,文件越大效率越低。为了解决长时间的动态增长或者缩减操作后效率低下问题,Windows FAT采用磁盘整理的方法。

索引文件

索引文件类似与页分配内存,索引表类似与页表,索引文件有链接文件的优点,定位快,顺序存储和随即存储效率高,缺点是占用存储空间多,对于小文件较多的系统来说优点体现的不明显,空间浪费明显,适合大中型文件系统。

Linux文件系统的结构


磁盘文件系统

位于磁盘上的文件系统,每个磁盘分区由一个文件系统管理,所有针对文件的操作都要通过磁盘文件系统,整个文件系统体系结构中,磁盘文件系统是一个映射层,上层的文件系统利用它将用户请求的文件操作映射到磁盘上去。

虚拟文件系统

硬盘文件系统通常是为不同的操作系统设计和使用的,它们具有不同的组织结构和文件操作接口函数,相互之间差别往往很大,VFS屏蔽了这些文件系统的差异,为访问文件提供了统一的接口。Linux/Unix风格的文件系统与VFS有这相同的概念和很好的对应关系,可以直接从他们对应的结构构造出VFS文件系统的对象,但FAT和NTFS这样的非Unix风格的系统必须经过封装

同内存管理中描述的类似,VFS也采用了面向对象的描述方式。VFS将文件系统看作由一些对象构成,每个对象是一个结构体,结构体包含了对象的属性数据,包含了对象操作集。

VFS超级块:代表一个已经挂载的文件系统

VFS目录项:代表文件目录的一个分量

VFS索引节点:代表一个实际的文件

VFS文件 :代表进程打开的一个文件

VFS对象的实例以结构体形式存在内存,在适当的时候被建立起来,建立的时候结构体的数据由实际文件系统相应数据填充,或由VFS现场生成,结构体的操作集被设置为一组函数指针,指向实际文件系统中设置的对象的操作函数,VFS依靠这些对象提供的信息和操作函数完成所有的文件操作。

VFS超级块

VFS超级块代表一个特定的文件系统,与实际文件系统的超级块对应,包含了所有操作该文件系统的信息。VFS为每个已挂载的文件系统建立一个VFS超级块,通过它来访问和管理实际的文件系统,在挂载文件系统时建立,文件系统卸载后撤销。在此期间,文件操作会修改VFS超级块的内容,造成磁盘上的内容和超级块内容不一致,所以会周期性检验,把改变的写会磁盘保证一致性。



VFS索引节点

VFS索引节点对象代表了实际文件系统的一个具体的文件,与实际文件系统的INODE点相对应,包含了操作文件所需要的全部信息。VFS用inode结构表示索引节点,

inode包含了实际的磁盘的i节点的信息,如节点号,访问权限,硬链接数,属主,大小,时间戳等,另外还包含了VFS用到的信息,如i节点的引用计数,i节点操作指针i_op,文件操作集指针i_fop,地址空间映射以及构成结构的各种指针。

i节点的操作集用inode_operations结构描述,包含了一组文件操作函数指针,i节点的主要操作函数是针对文件整体进行操作的函数,建立,查询,链接,删除,建立目录,删除目录等。另外一个文件操作集file_operations包含了对文件内容的各种操作,系统中每打开一个文件,对应一个inode,在文件被打开时,VFS读入该文件的磁盘i节点的信息,为它在内存建立了inode,文件关闭后inode也被撤销。与超级块相同,inode也存在同步更新问题。



VFS目录项

定位一个文件时需要沿文件的路径名逐级访问路径中的各个目录,如果每次都从磁盘读取目录文件的话,访问效率很低,所以VFS引入了dentry的概念,dentry代表了一个路径分量路径由一系列分量构成,每个分量都是一个目录或者文件,当VFS首次解析一个路径名的时候,依次读取路径中的每个目录或者文件,为他们逐一建立相应的dentry结构,
并将文件或目录的inode关联起来,VFS将这些已经建立的dentry安装目录结构关系链接在一起,以后VFS查找时候主要沿着dentry的链接结构查找就可以了。

dentry并不存在实际文件系统的任何成分,而是根据路径名字的字符串在内存现场创建的,所以并不存在同步更新的问题。

VFS文件

从用户进程的角度来说看VFS,直接看到的是文件,而不是超级块,索引节点,目录项,进程关系的只是文件的访问模式,读写位置,文件属性,以及读写操作,VFS用一个file对象来描述进程关心的文件,每当进程打开一个文件,VFS都将为它建立一个结构。

文件操作集用file_operations结构描述,由一组对文件内容进行操作的函数指针,函数指针包括open,read,write,llseek操作,文件操作集中包含的函数指针是VFS定义的,但是这些指针指向哪些操作函数则由具体的文件系统定义,内核提供了通用操作函数,具体的操作函数可以具体使用这些通用函数,也可以专门的实现,另外操作集的设置也和文件类型有关,普通文件,目录文件,设备和特殊文件所带有的文件操作函数均有不同。file对象也没有对应的磁盘数据,不需要提供写会磁盘的操作。



VFS对象的关联结构




VFS与进程的接口



文件系统的注册,挂载和卸载

为了使得VFS能够支持某个类型的文件系统,文件系统必须想VFS注册,Linux内核内在的支持一些文件系统类型,这些支持的在系统启动的时候自动注册到VFS,其他类型采用可加载模块的方式动态的加载到系统上,在模块加载时进行注册,一个文件系统必须先挂载才能用,挂载的作用是建立它的VFS超级块,系统在初始化的时候挂载到‘/'目录下,其余的挂载在根文件系统的某个目录下,VFS用file_system_type描述每个已注册的文件系统,文件系统挂载的时候,VFS根据文件系统类型找到相应的注册结构,然后调用get_sb函数为它建立VFS超级块,再将它的根目录挂载到
挂载点目录下。VFS用vfsmount描述每个挂载的文件系统,记录了文件系统所在的设备名字,挂载点目录的dentry指针,超级块的指针信息,VFS通过vfsmount找到文件系统的超级块,然后就可以对该文件系统操作了。

文件的操作

1.文件的打开和关闭

系统函数open,打开文件就是在内存中构建文件的VFS对象,建立他们和进程之间的联系,并用文件描述符来标识这个连接,具体细节是:根据文件的路径名找到或者建立该文件的dentry,inode,file对象,在进程的file_struct结构找到一个空闲的fd数组项,填入file的对象指针,然后返回数组下标,就是文件描述符。若打开一个已经被打开的文件,则file结构已经存在,只需要找到该文件的file结构,并将其连接到该进程的fd数组项,然后file里面的引用次数加一,返回数组下标就行。关闭文件就是断开连接,释放文件描述符,如果file结构的引用次数为0,还要释放file结构。


2.文件的读写

读写文件的read和write,文件的读写前必须是打开的,系统根据fd的值,在进程的file_struct中检索fd数组,得到文件的file结构,根据file.f_mode,检查文件的访问权限,然后执行file.f_op->read或者file_op->write操作函数,完成读写操作,读写操作的起始位置是,当前文件的file.f_pos,文件打开的时候,值为0,读写结束后,会相应的更新,可以用lseek函数定位。

读文件过程:首先通过address_space在缓存中查找,命中就从缓存读数据,传送到用户进程的buf,不命中就调用address_space的readpage()函数,触发一次真正的磁盘操作,此时读数据的进程被阻塞,等待磁盘上数据到来的时候传送到缓存页面,数据读入缓存后,再从缓存复制到用户进程的buf,唤醒等待的进程。
写文件操作:通过address_space将数据直接写到缓存页,之后就返回了,当然也会适当的时候调用address_space的writepage,触发一次真正的写盘操作。

磁盘高速缓存

加快了文件的访问速度,减少了磁盘访问次数,提高了I/O性能。

I/O系统

I/O系统由通用块层,I/O调用层和设备驱动层组成组成,通用块层是文件系统与I/O系统的接口,隐藏不同设备的差异,为文件系统提供一个统一的关于块设备的文件抽象,需要读写设备时,文件系统向通用块层的抽象块设备发出文件I/O请求,交给I/O调度层处理,I/O调度层负责对块设备的I/O请求传达给设备驱动,设备驱动直接控制设备完成具体的I/O请求。


EXT文件系统

EXT文件的逻辑结构是无结构的流式文件。

Ext文件描述

采用了改进的FCB描述,考虑到目录下文件很多时。目录文件就会很大,往往需要多个存储块,将FCB分为主部和次部。主部包含除文件名字之外的所有的信息,成为Inode(索引节点),次部只包含文件名和主部的标识(节点号),文件目录由文件的次部组成,主要实现按名检索的目的,次部(目录项)很小,目录文件也很小,检索速度快。


Ext文件的定位


按名查找是文件系统提供的基本功能,文件系统根据路径名,从根目录或者当前目录开始逐级查找文件所在的目录,查找下一级目录的时候要根据上一级目录的数据块内容,目录文件的数据块记录的就是下一级目录名字或者文件名字,最终找到目标文件的Inode,就可以通过Inode访问数据块内容就可以操作文件了。

文件的链接

建立链接文件的命令是:
ln -[选项] 目标文件 链接文件

符号链接

符号链接文件是一类特殊的文件,其存放的内容是另一个文件的路径名字。访问符号链接文件时,系统根据记载内容去跳转。符号链接文件和目标文件是两个对应的文件,有各自的目录项,Inode和数据块。路径比较短的时候目标路径在Inode,长的时候才在数据块里面。符合链接文件的优点是灵活,可以 跨越文件系统和目录,缺点是空间开销大,每个符号链接都建立一个新的文件,通过链接文件访问目标文件要两次文件访问。

硬链接

将两个或者多个文件的Inode节点物理的连接在一起,硬链接文件具有不同的文件路径名和同一个Inode,通过其中任何一个访问得到的都是同一个内容,造成一个文件具有多个别名的效果。硬链接不能跨越文件系统。(因为对应的同一个Inode必然是在同一个文件系统的),硬链接是Linux系统整合文件系统结构的基本机制,允许一个文件具有多个
访问路径,节省空间且效率高,但是受文件系统范围的限制,不能对目录进行链接操作。

EXT文件系统的磁盘布局

为了方便管理大型磁盘的存储块,Ext3文件系统将它们分为若干块组,每个块组包含一定数量的连续的存储块,块组包含的块数取决于块的大小,限制来源于块位图. 

块位图 用来标识组中所有块占用情况,必须放在一个单独的块里面,如果快的大小是4K,则块位图可以描述32K个块,对应的块组大小就是128M(相乘),块组的数目取决于

分区的大小和块组的大小(被除数和商)





存储分配策略

分配方法是根据位视图中的记录找到空闲的inoed节点,和数据块分配给文件。尽量把同一个文件所使用的块,同一个目录相关联的节点存放在相邻的单元里面,至少是一个块组,总之就是尽量的好。



































0 0
原创粉丝点击