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} 文件结构⎩⎪⎨⎪⎧字节序列Bytesequence记录序列Recordsequence树tree
-
字节序列
灵活性最大,用户可以向文件中加入任何内容,以任何形式命名
-
记录序列
文件是具有固定长度记录的序列,每个记录有其内部结构。
{ 读 操 作 : 返 回 一 个 记 录 写 操 作 : 重 写 或 追 加 一 个 记 录 \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}
⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧普通文件:包含用户信息{二进制文件:打印出来无法理解,使用文件的程序才知道内部结构ASCII文件:文本编辑器可编辑,可以显示和打印目录:管理文件系统结构的系统文件字符特殊文件:I/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} 文件系统常见系统调用:⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧create:创建文件但是不包含任何数据delete:删除文件释放磁盘空间open:将文件属性he磁盘地址表装入内存close:访问后关闭文件释放内部表空间read:在文件中读取数据write:文件中写……
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} 管理目录的系统调用⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧create:创建目录项delete:删除目录。只有空目录可以删除。opendir:读目录前打开目录closedir:关闭目录,释放内部空间readdir:打开目录的下一个目录项renamelink:允许在多个目录中出现同一个文件;增加该文件i节点计数器的计数,硬链接unlink{只出现在一个目录中:删除文件出现在多个目录:只删除指定路径名的链接
链接文件的方式:
-
硬链接
增加该文件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} ⎩⎪⎪⎪⎨⎪⎪⎪⎧文件属性放在目录项中:这种方式下,目录项的大小固定,包含⎩⎪⎨⎪⎧文件名文件属性的结构体磁盘块位置的一个至多个磁盘地址文件属性放在i节点中:目录项更短,只有文件名和i节点号。
-
可变长文件名的实现
-
法一:给文件名一个长度限制,典型长度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节点,另一次访问块。
4.4.5 磁盘碎片整理
长时间运行,磁盘上产生大量碎片,新建的文件会过于分散,效率降低。
磁盘性能的恢复:移动文件使他们相邻。并把大部分的空闲空间放到一个或多个大的连续区域内。
移动页文件,休眠文件,日志成本较高,不移动比较好。