操作系统-文件系统详解

Chapter 4文件系统

长期存储信息的基本要求:

  • 能够存储大量信息
  • 使用信息的进程终止,信息仍旧存在
  • 使多个进程并发访问相关信息

储存信息的一种方式:磁盘。

磁盘的功能:读块+写块——能实现长期存储
在 服 务 器 等 大 型 系 统 上 使 用 磁 盘 解 决 长 期 存 储 存 在 的 问 题 : { 如 何 找 到 信 息 如 何 防 止 一 个 用 户 读 取 另 一 个 用 户 的 信 息 如 何 知 道 哪 些 块 是 空 闲 的 在服务器等大型系统上使用磁盘解决长期存储存在的问题:\begin{cases} 如何找到信息\\ 如何防止一个用户读取另一个用户的信息\\ 如何知道哪些块是空闲的\\ \end{cases} 使
解决问题:提供新的抽象——文件。

文件:进程创建的信息逻辑单元
特 点 { 每 个 文 件 独 立 于 其 他 文 件 文 件 是 对 磁 盘 的 建 模 存 储 信 息 持 久 , 不 因 进 程 的 创 建 与 终 止 而 消 亡 受 到 操 作 系 统 管 理 { 构 造 命 名 访 问 使 用 保 护 实 现 管 理 特点\begin{cases} 每个文件独立于其他文件\\ 文件是对磁盘的建模\\ 存储信息持久,不因进程的创建与终止而消亡\\ 受到操作系统管理\begin{cases}构造\\命名\\访问\\使用\\保护\\实现\\管理\end{cases}\\ \end{cases} 访使
对于用户:文件系统最重要的是在用户眼中的表现形式
{ 文 件 组 成 文 件 命 名 如 何 保 护 文 件 操 作 \begin{cases} 文件组成\\ 文件命名\\ 如何保护\\ 文件操作\\ \end{cases}
即文件系统要为用户提供方便可用的接口。

4.1文件

用户角度分析

4.1.1 文件命名

  • 对象的命名方式

    文件命名规则在各个系统中不同。

    UNIX系统文件命名区分大小写,有的操作系统则不区别。

    扩展名的作用是:提醒所有者,而不传送什么信息给计算机

4.1.2文件结构

文 件 结 构 { 字 节 序 列 B y t e s e q u e n c e 记 录 序 列 R e c o r d s e q u e n c e 树 t r e e 文件结构 \begin{cases} 字节序列\qquad Byte\quad sequence\\ 记录序列\qquad Record\quad sequence\\ 树\qquad\qquad tree \end{cases} BytesequenceRecordsequencetree

  • 字节序列

    灵活性最大,用户可以向文件中加入任何内容,以任何形式命名

  • 记录序列

    文件是具有固定长度记录的序列,每个记录有其内部结构
    { 读 操 作 : 返 回 一 个 记 录 写 操 作 : 重 写 或 追 加 一 个 记 录 \begin{cases} 读操作:返回一个记录\\ 写操作:重写或追加一个记录 \end{cases} {

  • 树:记录树。每个记录的长度不必相等

    记录固定位置有一个键字段:依据键排序,对键查找。

    用户不能指定将记录添加在哪个位置——OS决定

4.1.3文件类型

操作系统支持的文件类型:普通文件,目录,字符特殊文件(Charactor special file),块特殊文件。
{ 普 通 文 件 : 包 含 用 户 信 息 { 二 进 制 文 件 : 打 印 出 来 无 法 理 解 , 使 用 文 件 的 程 序 才 知 道 内 部 结 构 A S C I I 文 件 : 文 本 编 辑 器 可 编 辑 , 可 以 显 示 和 打 印 目 录 : 管 理 文 件 系 统 结 构 的 系 统 文 件 字 符 特 殊 文 件 : I / O 设 备 有 关 块 特 殊 文 件 : 磁 盘 类 设 备 \begin{cases} 普通文件:包含用户信息\begin{cases}二进制文件:打印出来无法理解,使用文件的程序才知道内部结构\\ASCII文件:文本编辑器可编辑,可以显示和打印\end{cases}\\ 目录:管理文件系统结构的系统文件\\ 字符特殊文件:I/O设备有关\\ 块特殊文件:磁盘类设备 \end{cases} {使ASCIII/O

二进制文件的例子:

在这里插入图片描述

  • 一个可执行文件

    字节序列,文件头以魔数(magic number)开始。后有各段长度和执行起始地址等。

    装入内存后会被重定位

  • 一个存档文件

    编译但未链接的库过程模块组成。模块头开始:记录名称,创建日期,保护码和文件大小。

OS必须至少能识别自己的可执行文件的文件类型。

4.1.4 文件访问

文 件 的 访 问 方 式 : { 顺 序 访 问 随 机 访 问 文件的访问方式:\begin{cases} 顺序访问\\ 随机访问 \end{cases} 访{访访

  • 顺序访问

    从头到尾,按顺序访问全部内容,不可跳过。

    存储介质是磁带不是磁盘时比较有效。

  • 随机访问形式

    任何次序读取字节或记录的文件:随机访问文件(random access file)

    指示从何处开始读文件:

    • read给出
    • 特殊的seek操作设置当前位置

4.1.5 文件属性

文件:含有文件名和数据,还有创建时间等附加信息

附加信息:属性/元数据

在这里插入图片描述

4.1.6 文件操作

文 件 系 统 常 见 系 统 调 用 : { c r e a t e : 创 建 文 件 但 是 不 包 含 任 何 数 据 d e l e t e : 删 除 文 件 释 放 磁 盘 空 间 o p e n : 将 文 件 属 性 h e 磁 盘 地 址 表 装 入 内 存 c l o s e : 访 问 后 关 闭 文 件 释 放 内 部 表 空 间 r e a d : 在 文 件 中 读 取 数 据 w r i t e : 文 件 中 写 … … 文件系统常见系统调用:\begin{cases} create:创建文件但是不包含任何数据\\ delete:删除文件释放磁盘空间\\ open:将文件属性he磁盘地址表装入内存\\ close:访问后关闭文件释放内部表空间\\ read:在文件中读取数据\\ write:文件中写\\ …… \end{cases} createdelete:openheclose:访readwrite

4.1.7 文件系统调用程序的例子

复制文件的简单程序:

/*复制文件程序,有基本的错误检查和错误报告*/
#include <sys/types.h>
/*包括必要的头文件*/
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argVD);
/* ANSI原型*/
#define BUF_ SIZE 4096
/*使用一个4096字节大小的缓冲区*/
#define OUTPUT_ MODE 0700
/*输出文件的保护位*/
int main(int argc, char *argvD)
{
    int in. _fd, out. fd, rd_ count, wt_ count;
    char buffer[BUF . SIZE];
    if (argc != 3) exit(1);   /*如果argc不等于3,语法错*/
    /*打开输入文件并创建输出文件*/
    in_fd = open(argv[1], O_ RDONLY); /* 打开源文件*/
    if(in_fd < 0) exit();/*如果该文件不能打开,退出*/
    out. _fd = creat(argv[2], OUTPUT_MODE); /* 创建目标文件*/
    if (out _fd < 0) exit(3);
    /*如果该文件不能被创建,退出*/
    /*循环复制*/
    while (TRUE){
    rd count= read(in _fd, buffer, BUF_ SIZE);/* 读一块数据*/
    if (rd. count <= 0) break;
    /*如果文件结束或读时出错,退出循环*/
    wt_ count = write(out .fd, buffer, rd_ count); /*写数据*/
    if (wt count <= 0) exit(4);
    /*wt_ count <=0是一个错误*/
    }
    /*关闭文件*/
    close(in_ fd);
    close(out_ .fd);
    if(rd_ count== 0)
    /*没有读取错误*/
    exit(0);
    else
    exit(5);
    /*有读取错发生*/
}

in_fd是一个标识,当成功打开时,系统分配的一个整数,后续使用这个标识,让程序知道是哪个文件。

4.2 目录

记录文件的位置:目录/文件夹

很多系统中:目录也是文件。

4.2.1一级目录系统

一个目录中包含所有文件:根目录(此时目录的名字就不重要了)

4.2.2层次目录系统

用目录把文件分组。

在这里插入图片描述

层次目录系统中,其中的A,B,C分属于不同的用户。

4.2.3 路径名

{ 绝 对 路 径 : 从 根 目 录 到 文 件 , 第 一 个 字 符 是 分 隔 符 , 路 径 是 绝 对 路 径 相 对 路 径 : 和 工 作 目 录 / 当 前 目 录 一 起 使 用 \begin{cases} 绝对路径:从根目录到文件,第一个字符是分隔符,路径是绝对路径\\ 相对路径:和工作目录/当前目录一起使用 \end{cases} {,/使

每个进程都有自己的工作目录。

层次目录结构的特殊项:

  • “.”:dot,指向当前目录
  • “…”:dotdot,指向父目录,除非是根目录。

4.2.4 目录操作

管 理 目 录 的 系 统 调 用 { c r e a t e : 创 建 目 录 项 d e l e t e : 删 除 目 录 。 只 有 空 目 录 可 以 删 除 。 o p e n d i r : 读 目 录 前 打 开 目 录 c l o s e d i r : 关 闭 目 录 , 释 放 内 部 空 间 r e a d d i r : 打 开 目 录 的 下 一 个 目 录 项 r e n a m e l i n k : 允 许 在 多 个 目 录 中 出 现 同 一 个 文 件 ; 增 加 该 文 件 i 节 点 计 数 器 的 计 数 , 硬 链 接 u n l i n k { 只 出 现 在 一 个 目 录 中 : 删 除 文 件 出 现 在 多 个 目 录 : 只 删 除 指 定 路 径 名 的 链 接 管理目录的系统调用 \begin{cases} create:创建目录项\\ delete:删除目录。只有空目录可以删除。\\ opendir:读目录前打开目录\\ closedir:关闭目录,释放内部空间\\ readdir:打开目录的下一个目录项\\ rename\\ link:允许在多个目录中出现同一个文件;增加该文件i节点计数器的计数,硬链接\\ unlink\begin{cases} 只出现在一个目录中:删除文件\\ 出现在多个目录:只删除指定路径名的链接 \end{cases} \end{cases} createdeleteopendirclosedirreaddirrenamelinkiunlink{

链接文件的方式:

  • 硬链接

    增加该文件i节点的计数器计数。两个文件名指向同一个内部数据

  • 符号链接

    一个文件名指向命名另一个文件的一个小文件。使用小文件时,文件系统沿着路径最终找到文件名。

    跨越磁盘的界限。

4.3文件系统实现

实现者角度

4.3.1 文件系统布局

磁盘分区—>>每个分区中有独立文件系统。

主引导记录(Master Boot Record, MBR):磁盘的0号扇区,用来引导计算机。MBR末尾是分区表。

分区表:给出了每个分区的起始和结束地址。表中的一个分区被标记为活动分区。

计算机被引导时BIOS读入并执行MBR。MBR确定活动分区。读入MBR的第一个块:引导块。

文件系统含有的项目:
在这里插入图片描述

  • 引导块

    引导块中程序装载该分区中的操作系统。每一个分区从一个引导块开始。

  • 超级块

    典型信息:魔数,文件系统中的块数量,管理信息

  • 空闲内存管理

    空闲块的信息:用位图或者指针列表给出。

  • i节点

  • 根目录

  • 文件和目录

4.3.2 文件的实现

文件存储的关键问题:记录各个文件分别用到哪些磁盘块

1.连续分配

概念:把每个文件作为一连串的数据块存储在磁盘上。

如下图为连续分配。且注意:每个文件都以一个崭新的块作为开始。假如A文件的最后一个块还有2/3没用,那么B文件也不会用这个块。

在这里插入图片描述

也就是说,会造成一定的内存浪费。

优点:

  • 实现简单,记录每个文件用到的磁盘块只需要两个数字:第一块的磁盘地址和文件的块数
  • 读操作性能好:单个操作中就可整个读出。只需要一次寻块,之后没有寻道和旋转延迟。

缺点:

  • 磁盘变得零碎

    文件被删除时,空间释放,剩下一堆空闲块。磁盘不会挤压这个空洞。

    磁盘空洞的解决方法:

    • 压缩磁盘:代价高
    • 重新使用空洞:维护空洞列表。且有必要知道新放入文件的最终大小,以寻找合适的空洞。
2.链表分配

概念:每一个块的第一个字作为指向下一个块的指针,块的其他部分存储数据。

在这里插入图片描述

优点:

  • 充分利用每一个磁盘块,不会有磁盘碎片(文件末尾空块除外)
  • 顺序读文件比较方便

缺点:

  • 随机访问缓慢
  • 由于指针占去字节,存储的数据不再是2的整数次幂
3.采用内存中的表进行链表分配

将指针字提取放到内存的一个表中,用表维护。

在这里插入图片描述

优点:

  • 随机访问变得简单些
  • 整个块都可以存放数据

缺点:

  • 必须把整个表都放在内存里,空间消耗大。表的大小正比于磁盘自身的大小。
4.i节点

在这里插入图片描述

只有当文件打开,其i节点才在内存中。

内存中的i节点个数正比于可能要同时打开的最大文件个数。与磁盘自身大小无关。

  • 当文件的磁盘个数超过i节点所能容纳的数目的解决方法:

    最后一个i节点不指向数据块,而是指向一个包含额外磁盘块地址的块的地址。

4.3.3 目录的实现

  • 目录系统的功能

目录系统的主要功能:把ASCII文件名映射成定位文件需要的信息。

目录项提供查找文件磁盘块所需要的信息:
信 息 的 种 类 { 连 续 存 储 : 整 个 文 件 的 磁 盘 地 址 链 表 分 配 方 案 : 第 一 个 块 的 编 号 i 节 点 号 信息的种类\begin{cases} 连续存储:整个文件的磁盘地址\\ 链表分配方案:第一个块的编号\\ i节点号\\ \end{cases} i

  • 在何处存放文件属性

{ 文 件 属 性 放 在 目 录 项 中 : 这 种 方 式 下 , 目 录 项 的 大 小 固 定 , 包 含 { 文 件 名 文 件 属 性 的 结 构 体 磁 盘 块 位 置 的 一 个 至 多 个 磁 盘 地 址 文 件 属 性 放 在 i 节 点 中 : 目 录 项 更 短 , 只 有 文 件 名 和 i 节 点 号 。 \begin{cases} 文件属性放在目录项中:这种方式下,目录项的大小固定,包含\begin{cases}文件名\\文件属性的结构体\\磁盘块位置的一个至多个磁盘地址\end{cases}\\ 文件属性放在i节点中: 目录项更短,只有文件名和i节点号。 \end{cases} ii

  • 可变长文件名的实现

    • 法一:给文件名一个长度限制,典型长度225:文件名大多不会这么长,浪费目录空间

    • 法二:放弃目录项长度相等

      每个目录项只有一个固定部分:目录项的长度和固定格式的数据,包括:所有者,创建时间,保护信息,其他属性

      固定的头后面是任意长度的实际文件名

在这里插入图片描述

- 缺点:

  ① 不固定长度导致这个文件移走后留下空隙,但是下一个到来的文件项不一定适合这个空隙。(和连续磁盘文件的问题一样)

  解决:对目录进行紧凑

  ② 一个目录项可能分布在多个页面上,读取时造成缺页中断
  • 法三:使目录项自身具有固定长度

    文件名放在目录后面的堆中

在这里插入图片描述

- 优点:文件移走,另一个文件的目录项总是适合这个空隙。

- 缺点:对堆进行维护,处理文件名时,缺页中断仍会发生。

查找文件时,对目录的查找可以使用散列表,使用散列表构成目录项。

查找结果放入高速缓存是另一种方法。查找前先在高速缓存中查看。

4.3.4 共享文件

1.概念

链接:目录与共享文件之间的联系

文件系统成了有向无环图,维护难度提升。

2.共享文件的问题

目录中包含地址,必须把C目录中的磁盘地址复制到B目录中。如果B或者C之后又往文件中加入新的内容,新的数据块只会列入添加工作的用户的目录这种。其他用户对此不知道。违背了共享的目的。
在这里插入图片描述

3.解决方案
(1)i节点法(硬链接)

磁盘块不列入目录,而是列入i节点,目录指向i节点

缺点:B链接到共享文件时,i节点的所有者是C。

建立一个连接不会改变所有关系。只是将i节点的链接数+1,OS知道目前有多少个目录指向这个文件。

C以后试图删除时,如果系统删除文件并清除i节点,B有一个无效的i节点,后续可能发生错误。

唯一做法是删除C的目录项,但保存i节点,i节点链接数-1。但所有者仍是C,C为B付账,直到计数为0,被删除。
在这里插入图片描述

(2)符号链接

系统建立一个Link类型的新文件。把文件放在B的目录下,是的B与C的一个文件存在链接。

Link中只有它所连接文件的路径名。

OS通过路径名找文件。

符号链接没有上述的i节点法的问题。连接到B的只有路径,没有i节点。文件和i节点删除时,试图通过该链接访问将失败。

符号链接的缺点:

  • 由路径搜寻需要开销。额外磁盘消耗。

4.3.5日志结构文件系统

磁盘的寻道时间没有得到发展限制了文件系统性能。

缓解方法:日志结构文件系统(Log-structured File System, LFS)

CPU运行速度越来越快,RAM容量变得更大,磁盘高速缓存增多。从磁盘的读操作变少,更多的是零碎的写操作。

日志结构文件系统是对零碎写操作的优化。

  • 日志结构文件系统的工作

将所有零碎的写操作缓冲到一个段中,周期性的把已缓冲的段作为在日志末位一个邻接段写入磁盘。
段 的 内 容 { i 节 点 目 录 块 数 据 块 … … 段的内容 \begin{cases} i节点\\ 目录块\\ 数据块\\ …… \end{cases} i
i节点分散在日志中:需要维护i节点图,方便查找i节点。

  • 段中存在着不存在的块的信息

LFS 有清理线程,周期性扫描日志进行磁盘压缩。

4.3.6日志文件系统

日志文件系统面对出错的鲁棒性可以被借鉴:保存一个用于记录系统下一步要做什么的日志

崩溃时查看日志获得崩溃前的计划,并完成。

  • 实例介绍:移除文件

移除文件的步骤:

  • 目录中删除文件
  • 释放i节点到空闲节点池
  • 将所有磁盘归还空闲磁盘块池

系统崩溃会带来问题,如果有日志,那么可以检查日志,把未完成的任务完成。只有当这个移除的任务完成,日志才会被擦除。

原子事务:一组动作必须完成所有被界定的动作,或者什么也不做。

4.3.7虚拟文件系统

一个OS中也可能有不同的文件系统:

  • Windows通过制定不同的盘符来处理文件系统,比如C:,D:等。进程打开文件时,盘符是隐式的,OS知道向哪个文件系统传递请求。

  • Linux将很多的文件系统整合到一个统一的结构中。

    不同的文件系统在不同的目录下,用户却不知道。

1.VFS介绍

内容:抽象出文件系统共有部分,并将代码放在单独的一层。

VFS对用户进程有上层接口:POSIX接口。

VFS的下层接口:包含功能调用,使每个文件接口完成任务。

2.VFS的工作过程
  • 系统启动/注册,在VFS中注册

    注册:提供VFS需要的函数地址的列表

  • 装在后可以使用,比如装在在usr中,进程调用:

    open("/usr/include/unistd.h,O_RDONLY")

  • 解析路径

4.4文件系统管理和优化

4.4.1 磁盘空间管理

存储n字节的文件有两种策略:

  • 分配n字节的连续磁盘空间——文件扩大时,需要在磁盘上移动文件
  • 文件系统分成很多个连续/不连续的块——文件扩大问题也存在,但内存中段的移动要快得多。

采取对文件分块的策略

1.块大小

块过大:小文件来说浪费空间

块过小:分散多,寻道时间增加

2.记录空闲块

(1)磁盘块链表存储

通常情况下使用空闲块存储磁盘块链表

(2)位图法

位图中已分配的块用0表示,空闲的块用1表示。(或者反之)

在这里插入图片描述

一般情况下位图比磁盘块链表更省空间,除非磁盘块满了,几乎没有空闲块。

如果空闲块倾向于增长为连续的长的分块,那么空闲列表系统可以改为记录连续空闲块的数目。

基本上空的磁盘的表达:一个数表示第一个空闲块的地址,第二个数表示空闲块的个数

磁盘碎片较多:上述表达效率较低,两个数都记录就浪费了。

  • 空闲表的指针块

内存中使用指针块表示空闲块的信息。

有时会产生不必要的IO。
在这里插入图片描述

解决方法:拆分满了的指针块。释放三个块时变为状态C,而非B。

思想:保持磁盘上的大多数指针块为满的状态(减少磁盘的使用),但是内存中保存一个半满的指针块。它既可以处理文件的创建有同事处理文件的删除动作,而不会为空闲表进行磁盘的I/O

3.磁盘配额
  • 背景:防止用户贪心占有过多的磁盘空间。OS提供强制性磁盘配额机制。

  • 思想:系统管理员给用户拥有的文件和块的最大数量。OS确保不超过限额。

  • 机制:

    • 文件表:用户打开文件,系统把文件属性和磁盘地址送入内存中的打开文件表。告诉其文件所有者是谁。任何增长记录到配额上,防止用户垄断i节点。
    • 配额表:磁盘配额文件中提取

    在打开文件表建立新的表项时,产生一个该文件所有者配额记录的指针。每次文件中数据块总数增加,引发配额硬限制和软限制的检查。

4.4.2文件系统备份

1、情形:
  • 从意外灾难中回复
  • 从错误操作中回复
2、方法:
  • Windows专门设计了回收站,删除的文件并不立马删除,而是放到这个目录下。
3、注意点:
  • 备份整个文件系统还是一部分?

    只备份特定目录下及其下的全部文件,而不是备份文件系统。

  • 对前一次备份后未更改的目录再做一次备份是浪费

    增量转储的思想

  • 海量数据压缩后写入磁带

    压缩算法易破坏,需谨慎

在这里插入图片描述

方框为目录,圆形为文件

  • 对活动文件做备份

    转出过程中添加、修改、删除文件和目录会导致文件系统的不一致性。

    所以①脱机时转储/②关键时刻快照

  • 非技术问题

4、磁盘转储的两种方案:
  • 物理转储

    从磁盘的第0块开始,一直复制,直到复制完。

    注意点:

    • 未使用的磁盘块无需备份
    • 磁带上的第k块不等于磁盘上的第k块,需要记录关系
    • 坏块不存储。要确保坏块决不被分配。
  • 逻辑转储

    从一个或者几个制定的目录开始,递归地转储其自给定基准日期后有所更改的文件或目录

    • 逻辑转储算法研究

      阴影的代表基准日期后被修改过,需要转储;无阴影不需要转储。

      转储时还要转储通向修改文件或目录上的所有目录。

      原因:

      • 转储文件可恢复到另一台计算机的新的文件系统中。
      • 可对单个文件进行增量恢复。
5、转储算法
  • 维持以i节点号为索引的位图,每个i节点包含几位。算法执行中,位图中这些位被设置或清除

  • 算法四个阶段

    • 第一个阶段

      从目录开始检查所有目录项,对修改的文件(包括路径上的目录,不管是否被修改),进行标记
      在这里插入图片描述

    • 第二个阶段

      去掉目录树中任何不包含被修改的文件或目录的目录上的标记。此时10,11,14……已被去掉标记。不会被转储。

在这里插入图片描述

  • 第三个阶段

    标记要转储的目录,对目录转储

  • 第四个阶段

    标记要转储的文件,对文件转储

6、转储的过程
  • 首先在磁盘上创建一个空的文件系统,恢复最近一次的完整转存。
  • 首先恢复目录
  • 在恢复文件本身
7、相关问题
  • 空闲块列表要重新构建
  • 恢复时,对链接的文件只恢复一次

4.4.3文件系统的一致性

1、不一致出现原因:

文件从磁盘读取,修改后写回磁盘,写回前崩溃。文件系统可能处于不一致状态。

2、UNIX的fsck的介绍

块的一致性检查+文件的一致性检查

  • 块的一致性检查

    构造两张表:空闲块表和记录块在文件中出现次数的表

    从i节点中信息构造块在文件中出现次数的表,从空闲块表中构建块的空闲表

  • 出现的状况:块丢失,块在空闲表中出现两次,多个文件中出现一个数据块

在这里插入图片描述

  • 目录的一致性检查

    用文件记录而非块记录。

    沿着目录树递归下降,检查文件系统中的每个目录。对每个目录中的每个文件,文件使用计数器加一。

    最终得到一张i节点号索引的表,表明每个文件被多少个目录包含。然后,检验程序将这些数字于存储在文件i节点中的链接数目比较。一致时应该相等(硬链接要考虑,符号链接不考虑)。

    不一致:i节点中的链接数过大或过小

    • i节点的链接数大于目录数:错误不严重,i节点中的链接计数纠正

    • i节点的链接数小于目录数:当i节点计数变为0时,实际并不为零,但这个块空间会被释放。解决方法仍是设定为正确值。

  • 块检查和目录检查合二为一,扫描一次i节点

3、i节点的访问权限

4.4.4文件系统性能

访问盘比访问内存慢得多。下面介绍优化方法

1、高速缓存

管理高速缓存的方法:check all request,看在高速缓存中是否有该块,有则执行操作。没有则先读到高速缓存,再复制到所需的地方。

高速缓存块过多:散列表处理所有的设备和磁盘地址。

在这里插入图片描述

块已满:和页面置换算法一样,采取FIFO,LRU等算法替换出块

散列表的冲突链外设置的双向链表:把所有块按照使用时间的先后连接起来,使用少的在链表前端,使用多的在链表后端。使用时从双向链表中移走,放置到表的尾部。以维护LRU顺序

2、块提前读

顺序读的情况:需要用到块之前,试图将其提前写入高速缓存,提高命中率。

在文件中生成块k时,为块k+1安排预读处理

随机访问文件,提前读不起作用。

使用文件关联的某个位,跟踪文件是“顺序访问方式”还是“随机访问”。

3、减少磁盘臂运动

有可能顺序访问的块放在一起,最好是同一个柱面上,减少磁盘臂的移动次数。

  • 内存中的位图容易找到临近的空闲块,磁盘中的空闲表最不容易找到空闲块。

  • 解决空闲表问题的技术:块簇技术

    不适用块而用连续块簇来跟踪磁盘存储区

    在分配块时,系统尽量将一个文件中的连续块存放在一个柱面上。

访问i节点可能是另一个瓶颈:两次磁盘访问,一次访问i节点,另一次访问块。
在这里插入图片描述

4.4.5 磁盘碎片整理

长时间运行,磁盘上产生大量碎片,新建的文件会过于分散,效率降低。

磁盘性能的恢复:移动文件使他们相邻。并把大部分的空闲空间放到一个或多个大的连续区域内。

移动页文件,休眠文件,日志代价较高,不移动比较好。

:50%;" />

块已满:和页面置换算法一样,采取FIFO,LRU等算法替换出块

散列表的冲突链外设置的双向链表:把所有块按照使用时间的先后连接起来,使用少的在链表前端,使用多的在链表后端。使用时从双向链表中移走,放置到表的尾部。以维护LRU顺序

2、块提前读

顺序读的情况:需要用到块之前,试图将其提前写入高速缓存,提高命中率。

在文件中生成块k时,为块k+1安排预读处理

随机访问文件,提前读不起作用。

使用文件关联的某个位,跟踪文件是“顺序访问方式”还是“随机访问”。

3、减少磁盘臂运动

有可能顺序访问的块放在一起,最好是同一个柱面上,减少磁盘臂的移动次数。

  • 内存中的位图容易找到临近的空闲块,磁盘中的空闲表最不容易找到空闲块。

  • 解决空闲表问题的技术:块簇技术

    不适用块而用连续块簇来跟踪磁盘存储区

    在分配块时,系统尽量将一个文件中的连续块存放在一个柱面上。

访问i节点可能是另一个瓶颈:两次磁盘访问,一次访问i节点,另一次访问块。

image-20210602111105692

4.4.5 磁盘碎片整理

长时间运行,磁盘上产生大量碎片,新建的文件会过于分散,效率降低。

磁盘性能的恢复:移动文件使他们相邻。并把大部分的空闲空间放到一个或多个大的连续区域内。

移动页文件,休眠文件,日志成本较高,不移动比较好。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blanche117

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值