4.3 文件系统的实现

4.3 文件系统的实现
1. 文件系统布局
多数磁盘被划分成一个或多个分区,而每个分区有一个独立的文件系统。磁盘的0号扇区称为主引导记录(MBR),用来引导计算机。MBR结尾是分区表,给出每个分区的起始和结束地址。
计算机被引导时,BIOS读入并执行MBR,MBR做得第一件事是确定活动分区并读入它的第一个块,称为引导块,并执行之。引导块中的程序讲装载该分区中的操作系统。
每个分区都从一个启动块开始,即使它不含有一个可启动的操作系统。

超级块包含文件系统的所有关键参数,在计算机启动时,或者在该文件系统首次使用时,会把超级块读入内存。
2. 文件的实现
(1)连续分配
每个文件作为一连串数据块存储在磁盘上。
每个文件都要从一个新的块开始!!
这样记录每个文件只需要两个数字:第一块的磁盘地址和文件的块数

优点:实现简单;只需要一次寻找,性能高。
缺点:磁盘变得零碎,删除一个文件时留下了一堆空闲块。最终磁盘会背充满,要么压缩磁盘,但代价实在太高;另一个是重新使用空洞中的空闲空间,这需要维护一个空洞列表。
而且分配的时候还需要事先直到文件大概的大小。
(2)链表分配
为每个文件构造磁盘块链表,每个块的第一个字作为指向下一块的指针,其他部分则为数据。
优点:这可以充分利用每个磁盘块;目录项只需要记录一个起始块号
缺点:随机存取比较慢,因为每一次都必须从头开始读;指针占去了一些字节,这样剩余字节数不是2的整数次幂,有时会降低系统的运行效率。

(3)内存中采用表的链表分配
如果取出每个磁盘块的指针字,把它放在内存的一个表中,就可以解决上述缺点。
内存中这样一个表格称为文件分配表(FAT)。
优点:整个快都可以存放数据,随机存取也容易,不管文件多大,目录项只需要记录一个起始块号。
缺点:必须把整个表都放在内存里,占空间。

(4)i节点
给每个文件赋予一个称为i结点的数据结构,其中列出了文件的属性和文件块的磁盘地址。
i结点最后一个磁盘地址不指向数据块,而是一个包含磁盘块地址的块的地址。


优点:只有在对应文件打开时,其i结点才在内存中,所以占用少量的内存。
3. 目录的实现
打开文件时,操作系统利用用户给出的路径名先找到对应的 目录项,而目录项中提供了查找文件磁盘块所需要的信息。这些信息可能是:
  • 整个文件的磁盘地址(如连续分配)
  • 第一个块的编号(两种链表分配方案)
  • i结点号
但都是把ASCII文件名映射成定位文件数据所需要的信息。

文件属性放在哪?
(1)直接存放在目录项中,目录中有一个固定大小的目录项列表 (WINDOWS)
(2)对i结点系统还可以把文件属性存放在i结点中而不是目录项中。这时候目录项会更短,只有文件名和i节点号。(UNIX)

如何支持可变长度长文件名?
(1)
缺点:移走文件后,引入了一个长度可变的空隙(可变文件名那里),下一个来的文件不一定正好适合这个空隙。而且一个目录项可能会分布在多个页面上,在读取文件名的时候可能发生页面故障。
(2)
讲文件名放置在目录后面的堆中
优点:移走后两一个文件目录总可以适合这个空隙,当然要对堆进行管理
缺点:依旧可能出现页面故障

如何查找文件?
(1)线性地从头到尾对目录进行搜索
(2)在每个目录中使用散列表,散列处理文件名,以便选择一个散列表项,并检查该项对应链表。
优点:查找迅速
缺点:需要复杂的管理
一半只有在系统目录会有成百上千个时才使用散列表
(3)讲查找结果存入高速缓存,一半只有文件较少时才比较有效。

4. 共享文件
B的目录与共享文件联系称为一个联系。这样文件系统是一个有向无环图(DAG)。
两种实现方式:
(1)硬连接
硬连接是对于 同一文件系统的一个文件的连接,不能跨分区!!!
多个文件名与同一个文件(inode是唯一区分)进行链接,这些文件名可以在同一目录或不同目录


硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:
  • 文件有相同的 inode 及 data block;
  • 只能对已存在的文件进行创建(必须有一个实际存在的inode可以指嘛!);
  • 不能交叉文件系统进行硬链接的创建;
不能对目录进行创建,只可对文件创建(若系统允许对目录创建硬链接,则会产生目录环!);
  • 删除一个硬链接文件并不影响其他有相同 inode 号的文件。

缺点:B连接到共享文件时,i节点记录文件的所有者还是C,但会把i节点的连接计数加一。如果C试图删除这个文件,系统删除文件并清除i节点,B则有一个目录项指向一个无效的节点。如果该i结点以后分配给另一个文件,那么B的连接就指向一个错误的文件。(虽然通过i节点的计数知道它还在被引用,但没法去找到指向它的文件的全部目录项删除,因为指向目录的指针不能存储在i节点,它可能有无数多个目录)
措施: 只删除C的目录项但保留该i节点,知道计数变为0的时刻才会删除该文件。

(2)软连接(符号连接)
系统建立一个类型为LINK的新文件(也有自己的inode)放在B目录下,使B与C的一个文件存在连接。新文件中只包含它所连接的文件的路径名。当B读该连接文件时,操作系统直到是LINK类型的,就找到该文件所连接的文件的名字并且去读那个文件。

软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块

  • 软链接有自己的文件属性及权限等;
  • 可对不存在的文件或目录创建软链接(毕竟就是存一个路径);
  • 软链接可交叉文件系统;
  • 软链接可对文件或目录创建;
  • 创建软链接时,链接计数 i_nlink 不会增加(只有硬连接才会使引用计数增加!!);
  • 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。

优点:不会出现硬连接出现的关于删除的问题,因为只有真正的文件所有者才会有一个指向i节点的指针。当文件所有者删除文件时文件被销毁,以后试图通过符号连接访问该文件都会导致失败。

缺点:需要额外的开销,必须读取包含路径的文件再找到i节点(而不是一个直接指向i节点的指针);而且因为链接文件包含有原文件的路径信息,所以当原文件从一个目录下移到其他目录中,再访问链接文件,系统就找不到了,而硬连接则一直指着它。


(3)两种方式异同
异:
  • 硬链接原文件&链接文件公用一个inode号,说明他们是同一个文件,而软链接原文件&链接文件拥有不同的inode号,表明他们是两个不同的文件
  • 在文件属性上软链接明确写出了是链接文件,而硬链接没有写出来,因为在本质上硬链接文件和原文件是完全平等关系
  • 链接数目是不一样的,软链接的链接数目不会增加
  • 文件大小是不一样的,硬链接文件显示的大小是跟原文件是一样的而这里软链接显示的大小与原文件不同(只是存放一个路径)

同: 文件有多个路径这样被复制到磁盘上可能会复制多次。

(4)TIPS
硬链接就是一面墙上有一个洞,洞里放着一个苹果。从墙的这一面看是这个苹果,从墙的另一面看还是同一个苹果。
硬链接在删除的时候只是删除了一个名字。只有一块数据的所有名字都删除了的时候,数据才会被删除。(删除的时候相当于把墙的这一面糊上,但苹果本身不动,只有两面都糊上了,你才会看不到)

符号链接就是:我声称我有一个苹果,但是当你找我要的时候,我对你说,到某个建筑物的仓库就可以拿到那个苹果了。可见我并不真正拥有一个苹果,我只是拥有“某个地方有一个苹果”这个信息。但对于外部的观察者来说,这跟我实际上拥有一个苹果并无差异。
符号链接的删除:假设我死了,不会影响到原始数据。假设原始数据没了,那我这个符号链接就变成了一张空头支票,也就是悬空的符号链接。

5. 日志文件系统
基本思想是保存一个用于记录系统下一步要做什么的日志。当系统在完成他们即将完成的任务前崩溃,重新启动后,可以通过查看日志获取崩溃前计划完成的任务并完成他们。(如微软的NTFS文件系统,Linux的ext3等)
为了让日志文件系统工作,被写入日志的操作必须是幂等的,即可以重复执行很多次并不会带来破坏。
为了增加可信性,引入数据库中原子事务概念。
(日志结构文件系统(LFS)基本思想是把整个磁盘结构化为一个日志,每隔一段时间或有特殊需要时,把被缓冲在内存中的所有未决的写操作放到一个单独的段中,作为在日志末尾的一个邻接段写入磁盘。)

6. 虚拟文件系统(VFS)
VFS有两个不同的接口:上层给用户进程的接口和下层给实际文件系统的接口。

由于实际文件系统在统一的接口和数据结构下隐藏了具体的实现细节,所以在VFS 层和内核的其他部分看来,所有文件系统都是相同的。
正是由于在内核中引入了VFS,跨文件系统的文件操作才能实现。
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向 内核 为每一个 进程 所维护的该进程打开文件的记录表。)

VFS依靠四个主要的数据结构和一些辅助的数据结构来描述其结构信息,这些数据结构表现得就像是对象; 每个主要对象中都包含由操作函数表构成的操作对象,这些操作对象描述了内核针对这几个主要的对象可以进行的操作。
  • 超级块对象:存储一个已安装的文件系统的控制信息,代表一个已安装的文件系统;每次一个实际的文件系统被安装时, 内核会从磁盘的特定位置读取一些控制信息来填充内存中的超级块对象。一个安装实例和一个超级块对象一一对应。 
  • 索引节点对象:索引节点对象存储了文件的相关信息,代表了存储设备上的一个实际的物理文件。当一个 文件首次被访问时,内核会在内存中组装相应的索引节点对象,以便向内核提供对一个文件进行操 作时所必需的全部信息;这些信息一部分存储在磁盘特定位置,另外一部分是在加载时动态填充的。
  • 目录项对象:引入目录项的概念主要是出于方便查找文件的目的。目录项对象没有对应的磁盘数据结构,VFS在遍 历路径名的过程中现场将它们逐个地解析成目录项对象。
  • 文件对象:文件对象是已打开的文件在内存中的表示,主要用于建立进程和磁盘上的文件的对应关系。

进程通过task_struct中的一个域files_struct files来了解它当前所打开的文件对象;而我们通常所说的文件 描述符其实是进程打开的文件对象数组的索引值。文件对象通过域f_dentry找到它对应的dentry对象,再由dentry对象的域d_inode找 到它对应的索引结点,这样就建立了文件对象与实际的物理文件的关联。最后,还有一点很重要的是, 文件对象所对应的文件操作函数 列表是通过索引结点的域i_fop得到的。图6对第三部分源码的理解起到很大的作用。
补充:
UNIX下目录也是一个文件,所以也会有一个上一级目录项中的inode指向它~它作为一种特殊的数据块
UNIX系统中,根目录的i节点放在一个固定的磁盘位置

2018/03/16 09:30
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值