操作系统角度分析文件的操作

文件系统基础

页表就是一个存储物理页地址的表,我们知道,现在的程序使用的都是虚拟内存CPU 在取指令或者取数据的时候使用的是虚拟地址,为了能够从内存中取得数据,需要将虚拟地址转换为物理地址,虚拟地址和物理地址之间的映射关系就保存在页表中。每个进程都有自己的 页目录页表

物理内存其实也是需要被管理的,而它肯定也是一种数据结构,被操作系统维护的,通常来说物理内存被划分为一页一页,每页大小是 4KB,最后通过 mem 数组就能来维护这些页,而这些页我们称之为页框。

磁盘上的文件其实也是被划分为每一页每一页来进行管理,比如说一个可执行文件,其实不是简简单单的从文本文件编译成二进制文件的,首先,这个可执行文件里面所采用的地址其实都是虚拟地址,其次,我们编译好的程序其实都得按 4KB 为一个单位进行划分,一般这个 4KB 的区域我们叫做页帧

虚拟存储的实现需要依靠硬件的支持,对于不同的 CPU 来说是不同的,但是几乎所有的硬件都采用一个加 MMU(Memory Management Unit) 的部件来进行页映射!

img

在这里插入图片描述

快表: TLB是转换检测缓冲区(Translation Lookaside Buffer),又被称为快表,通常位于MMU中。

  • 为什么会出现TLB?答:因为访问内存时通过MMU中的多级页表进行映射速度太慢了,当CPU对一块内存进行频繁访问时,没必要总是查MMU,这就引出了TLB,他能完成一个小区域虚拟地址到物理地址的直接映射,他很快。
  • TLB和MMU是如何工作的?: 当一个虚拟地址放入MMU进入转换时,同时通过从TLB快表和MMU中的页表查询对应的物理地址,如果从TLB找到了,那慢表咱们就不查了;如果从TLB中没找到,那就通过慢表查,查到了将物理地址更新到快表,这样下次再映射这块儿虚拟内存不就快了嘛。(这只是简单的理解,实际TLB分为硬件TLB或软件TLB,TLB可能在MMU中,也可能由操作系统实现)(TLB可以视作对页表的告诉缓存,所有有人说TLB是页表的cache)

缺页异常
进程A通过CPU访问虚拟地址VA,通过MMU找到对应的物理地址,当内存页在物理内存中没有对应的页帧或者存在但无对应的访问权限,在这种情况下,CPU就会报告一个缺页的错误。Page Fault,指的是硬件错误、硬中断、分页错误、寻页缺失、缺页中断、页故障等,当软件试图访问已映射在虚拟地址空间中,但目前并未加载在物理内存中的一个分页时,由中央处理器的内存管理单元所发出的中断。

在这里插入图片描述

文件目录: 统一管理每个文件的元数据,以支持文件名到文件物理地址的转换 ;将所有文件的管理信息组织在一起,即构成文件目录。文件目录通常以文件的形式存放在磁盘上,当文件很多时,文件目录可能要占用大量的盘块,在查找的过程中,先将存放目录文件的第一个盘块中的目录调入内存,然后把用户所给定的文件名和目录项中的文件名逐一对比。若未找到指定文件,则再将下一个盘块中的目录项调入内存。在检索目录文件时,只用到了文件名,仅当找到一个目录项(即其中的文件名与指定要查找的文件名相匹配)时,才需要从该目录项中读出该文件的物理地址,而其他一些对该文件进行描述的信息,在检索目录时一概不用,显然,这些信息在检索目录时不需要调入内存。为此,在有的系统中,如UNIX系统,便采用了把文件名和文件描述信息分开的方法,亦即,使文件描述信息单独形成一个称为索引结点的数据结构,简称为i结点,在文件目录中的每个目录项由文件名和指向该文件所对应的i结点的指针所构成。

目录项: 构成文件目录的基本单元;目录项可以是FCB,目录是文件控制块的有序集合。检索目录的过程,只用到文件名,仅当找到一个目录项时,才需要从该目录项中读出该文件的物理地址,其它对描述文件的信息,检索目录时不许用。文件名和文件描述符分开,使文件描述信息单独形成一个称为索引节点的数据结构,简称 i节点。由于FCB占用内存太大,故引入索引节点。索引节点(i节点):把文件名与文件描述信息分开,使文件描述信息单独形成一个称为索引节点的数据结构。
在这里插入图片描述

FCB: 为了便于对文件进行控制和管理,在文件系统内部,给每个文件惟一地设置一个文件控制块。FCB包含了索引表的位置信息。其中一个文件的信息存放在若干不连续物理块中;系统为每个文件建立一个专用数据结构—索引表,并将这些物理块的块号存放在该索引表中;索引表就是磁盘块地址数组,其中第i个条目指向文件的第i块。unix文件系统中FCB 由 目录项 和i节点组成。其中目录项包括文件名 和 i节点号。目录文件由目录项构成 ;i节点描述文件的相关信息 。每个文件由一个目录项、一个i节点和若干磁盘块构成 。

在这里插入图片描述
文件控制块 fcb / 索引节点 inode是一类数据结构的两种表现形式。

  • 使用fcb的系统:目录项是fcb
  • 使用inode的系统:目录项是文件名+*inode
  • 在打开文件时,open()会根据目录项将文件的属性从外存复制到内存的打开文件表,并返回索引。这里文件的属性直接理解成fcb/inode也没啥问题,但书上没明确这么说,应该只是有一些细微的差别。
    在这里插入图片描述

在这里插入图片描述

系统打开文件表和用户打开文件表:
在这里插入图片描述

文件是存放在物理磁盘上的,包括文件控制块(FCB)和数据块。文件控制块通常包括文件权限、日期(创建、读取、修改)、拥有者、文件大小、数据块信息。数据块用来存储实际的内容。对于打开的文件,操作系统是这样管理的:系统维护了两张表,一张是系统级打开文件表,一张是进程级打开文件表(每个进程有一个)。

  • 系统级打开文件表复制了文件控制块的信息FCB等;进程级打开文件表保存了指向系统级文件表的指针及其他信息。

  • 系统级文件表每一项都保存一个计数器,即该文件打开的次数。我们初次打开一个文件时,系统首先查看该文件是否已在系统级文件表中,如果不在,则创建该项信息,否则,计数器加1。当我们关闭一个文件时,相应的计数也会减1,当减到0时,系统将系统级文件表中的项删除。

  • 进程打开一个文件时,会在进程级文件表中添加一项。每项的信息包括当前文件偏移量(读写文件的位置)、存取权限、和一个指向系统级文件表中对应文件项的指针。系统级文件表中的每一项通过文件描述符(一个非负整数)来标识。

page cache其中存储的数据在I/O完成后并不回收,而是一直保存在内存中,除非内存紧张,才开始回收占用的内存。inode模块可链接到address_space模块,方便查找自身文件数据是否已经缓存。address_space是Linux内核中的一个关键抽象,它被作为文件系统和页缓存的中间适配器,用来指示一个文件在页缓存中已经缓存了的物理页。因此,它是页缓存和外部设备中文件系统的桥梁。如果将文件系统可以理解成数据源,那么address_space可以说关联了内存系统和文件系统。地址空间address_space链接到页缓存基数树和inode,因此address_space通过指针可以方便的获取文件inode和page的信息。读文件的流程:

1、进程调用库函数向内核发起读文件请求;

2、内核通过检查进程的文件描述符定位到虚拟文件系统的已打开文件列表表项;

3、调用该文件可用的系统调用函数read()

3、read()函数通过文件表项链接到目录项模块,根据传入的文件路径,在目录项模块中检索,找到该文件的inode;

4、在inode中,通过文件内容偏移量计算出要读取的页;

5、通过inode找到文件对应的address_space;

6、在address_space中访问该文件的页缓存树,查找对应的页缓存结点:

(1)如果页缓存命中,那么直接返回文件内容;

(2)如果页缓存缺失,那么产生一个页缺失异常,创建一个页缓存页,同时通过inode找到文件该页的磁盘地址,读取相应的页填充该缓存页;重新进行第6步查找页缓存;

7、文件内容读取成功。

文件目录检索:用户给出文件名,按文件名查找到目录项/FCB。根据路径名检索:全路径名或相对路径名。**文件寻址:**根据目录项/FCB中文件物理地址等信息,计算出文件中任意记录或字符在存储介质上的地址。寻址过程:首先,系统应先读入第一个文件分量名usr,用它与根目录文件(或当前目录文件)中各目录项中的文件名顺序地进行比较,从中找到匹配者,并得到匹配项的索引结点号是6,再从6号索引结点中得到usr目录文件放在132号盘块中,将该盘块内容读入内存。接着,系统再将路径名中的第二个分量名ast读入,用它与放在132号盘块中的第二级目录文件中各目录项的文件名顺序进行比较,又找到匹配项,从中得到ast的目录文件放在26号索引结点中,再从26号索引结点中得知/usr/ast是存放在496号盘块中,再读入496号盘块。然后,将文件的第三个分量名mbox读入,用它与第三季目录文件/usr/ast中各目录项的文件名进行比较,最后得到/usr/ast/mbox的索引结点号为60,即在60号索引结点中存放了指定文件的物理地址,目录查询操作到此结束,如果在顺序查找过程中发现有一个文件分量名没有找到,则停止查找,并返回文件未找到信息。
在这里插入图片描述

磁盘数据传输:

寻道(时间):磁头移动定位到指定磁道
旋转延迟(时间):等待指定扇区从磁头下旋转经过
数据传输(时间):数据在磁盘与内存之间的实际传输 。

块高速缓存: 又称为文件缓存、磁盘高速缓存、缓冲区高速缓存 是指:在内存中为磁盘块设置的一个缓冲区,保存了磁盘中某些块的副本 。检查所有的读请求,看所需块是否在块高速缓存中。如果在,则可直接进行读操作;否则,先将数据块读入块高速缓存,再拷贝到所需的地方。由于访问的局部性原理,当一数据块被读入块高速缓存以满足一个I/O请求时,很可能将来还会再次访问到这一数据块。

文件操作的实现;

一、创建文件:

建立系统与文件的联系,实质是建立文件的FCB 。在目录中为新文件建立一个目录项,根据提供的参数及需要填写相关内容。分配必要的存储空间。

二、打开文件:

当用户要访问一个已存在的文件时,系统首先利用用户提供的文件名对目录进行查询,找出该文件的文件控制块或对应索引结点,然后,根据FCB或索引结点中所记录的文件物理地址(盘块号),换算出文件在磁盘上的物理位置,最后,再通过磁盘驱动程序,将所需文件读入内存。根据文件名在文件目录中检索,并将该文件的目录项读入内存,建立相应的数据结构,为后续的文件操作做好准备 。

① 根据文件路径名查目录,找到目录项 (或I节点号) ;
② 根据文件号查系统打开文件表,看文件是否已被打开;是 → 共享计数加1。否则 → 将目录项 (或I节点)等信息填入系统打开文件表空表项,共享计数置为1;
③ 根据打开方式、共享说明和用户身份检查访问合法性;
④ 在用户打开文件表中获取一空表项,填写打开方式等,并指向系统打开文件表对应表项
返回信息:fd:文件描述符,是一个非负整数,用于以后读写文件

三、读文件

① 根据打开文件时得到的文件描述符,找到相应的文件控制块(目录项),确定读操作的合法性。读操作合法→②,否则→出错处理。
② 将文件的逻辑块号转换为物理块号
根据参数中的读指针、长度与文件控制块中的信息,确定块号、块数、块内位移
③ 申请缓冲区
④ 启动磁盘I/O操作,把磁盘块中的信息读入缓冲区,再传送到指定的内存区(多次读盘)
⑤ 反复执行③、④直至读出所需数量的数据或读至文件尾

四、文件的写入策略

1、通写(write-through):内存中的修改立即写到磁盘 ,缺点:速度性能差 。例: FAT文件系统
2、延迟写(lazy-write) :利用回写(write back)缓存的方法得到高速 ,可恢复性差 。
3、可恢复写(transaction log) :采用事务日志来实现文件系统的写入 。既考虑安全性,又考虑速度性能 。例:NTFS

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值