OS操作系统系列文章目录
【OS操作系统】Operating System 第一章:操作系统的概述
【OS操作系统】Operating System 第二章:启动、中断、异常和系统调用
【OS操作系统】Operating System 第三章:连续内存分配
【OS操作系统】Operating System 第四章:非连续内容分配
【OS操作系统】Operating System 第五章:虚存技术
【OS操作系统】Operating System 第六章:页面置换算法
【OS操作系统】Operating System 第七章:进程与线程
【OS操作系统】Operating System 第八章:处理机调度
【OS操作系统】Operating System 第九章:同步互斥问题
【OS操作系统】Operating System 第十章:信号量与管程
【OS操作系统】Operating System 第十一章:死锁与进程通信
【OS操作系统】Operating System 第十二章:文件系统
目录
第十二章:文件系统
基本概念
不同的操作系统,有不同的文件系统,还可能有多个文件系统;
文件系统与文件
- 文件系统:
一种用于持久性存储的系统抽象;- 在存储器上:组织、控制、导航、访问和检索数据;
- 大多数计算机系统都包含文件系统;
- 个人电脑、服务器、笔记本电脑;
- iPod、TiVo(机顶盒)、手机(掌上电脑);
- Google可能是由一个文件系统构成的;
- 一首音乐和一张图片都是一个文件,都是以文件的形式存放在硬盘上的,但是和桌面级不一样,但是读写命名创建的形式都是一样的
- 文件:
文件系统中一个单元的相关数据在操作系统中的抽象;
文件系统的功能
- 分配文件磁盘空间:
- 管理文件夹(哪一块属于哪一个文件);
- 管理空闲空间(哪一块是空闲的);
- 分配算法(策略);
- 管理文件集合:
- 定位文件及其内容:
用户如何找到该文件; - 命名:
通过名字找到文件的接口;
通过路径的名字找到这个文件; - 最常见:分层文件系统,
文件是否需要分层,一个目录; - 文件系统类型(组织文件的不同方式);
- 定位文件及其内容:
- 提供的遍历及特征:
- 保护:
分层来保护数据安全; - 可靠性(持久性):
保持文件的持久,即使发生崩溃、媒体错误、双击等;
- 保护:
文件和块
文件的属性一般会包含在文件头或文件块上,用以保存基本的属性;
- 文件属性:
名称、类型、位置、大小、保护、创建者、创建时间、最近修改时间等等; - 文件头:
- 在存储元数据中保存了每个文件的信息;
- 保存文件的属性;
- 跟踪哪一存储块属于逻辑上文件结构的哪个偏移;
文件描述符
- 文件的使用模式
打开这个文件之后,为了更容易地进行读写操作,会返回一个文件描述符,其代表文件给应用程序做访问和控制;
文件描述符不仅仅是一个数据,操作系统对待打开的文件会有一个表,称为打开文件表,而返回的文件描述符就是该表的索引;
文件描述符指出了在该表的第几项代表了这个文件,里面有很多的文件信息;
- 元数据来管理打开文件:
- 文件指针:
指向当前最近的一次读写的位置; - 文件打开次数:
多少个进程打开了该文件,即文件打开次数,文件是共享资源,允许多个进程打开同一个文件;同样地只有文件打开次数为零时,才会从打开文件表中删除; - 文件磁盘位置:
缓存数据访问信息; - 访问权限:
每个程序的访问模式信息;
- 文件指针:
- 用户视图:
持久的数据结构; - 系统访问接口:
- 字节的集合(UNIX);
- 系统不会关心你想存储在磁盘上的任何数据结构;
- 操作系统内部视角:
- 块的集合(块是逻辑转换单元,而扇区是物理转换单元);
- 块大小<>扇区大小:
在UNIX中,块的大小为4KB;
多用户系统中的文件共享是必要的
- 访问控制:
- 谁能获得哪些文件的哪些访问权限;
- 访问模式:
读、写、执行、删除、列举等;
- 文件访问控制列表(ACL):
<文件实体,权限>; - UNIX模式:
- <用户 | 组 | 所有人,读 | 写 | 可执行>;
- 用户ID识别用户,表明每个用户所允许的权限及保护模式;
- 组ID允许用户组成组,并指定了组访问权限;
- 指定多用户、客户如何同时访问共享文件:
- 和过程同步算法类似;
- 因磁盘IO和网络延迟而设计简单;
- UNIX文件系统(UFS)语义:
- 对打开文件的写入内容,立即对其它文件打开同一文件的用户可见;
- 共享文件指针允许多用户同时读取和写入文件;
- 会话语义:
写入内容只有当文件关闭时可见; - 锁:
一些操作系统和文件系统提供该功能;
目录
- 目录的介绍:
通过分层的方式,进行存储,使得层次更加清晰简洁;
- 目录的操作:
- 典型操作:
- 搜索文件;
- 创建文件;
- 删除文件;
- 枚举目录;
- 重命名文件;
- 在文件系统中遍历一个路径;
- 操作系统应该只允许内核模式修改目录:
- 确保映射的完整性;
- 应用程序能够读目录;
- 典型操作:
- 如何存储目录的文件:
根据文件系统不同而有所差异;- 文件名的线性列表,包含了指向数据块的指针:
- 编程简答;
- 执行耗时;
- Hash表 —— hash数据结构的线性表:
- 减少目录搜索时间;
- 碰撞 —— 两个文件名的hash值相同;
- 固定大小;
- 文件名的线性列表,包含了指向数据块的指针:
- 路径的遍历:
路径是有目录和最后目标文件构成,这个路径的遍历开销较大,通过缓存机制提高效率;- 名字解析:
逻辑名字转换成物理资源(如文件)的过程;- 在文件系统中,是到实际文件的文件名(路径);
- 遍历文件目录直到找到目标文件;
- 举例:
解析 “/bin/ls”;- 读取root的文件头(在磁盘固定位置);
- 读取root的数据块:搜索“bin”项;
- 读取bin的文件头;
- 读取bin的数据块:搜索“ls”项;
- 读取ls的文件头;
- 当前工作目录:
- 每个进程都会指向一个文件目录用于解析文件名;
- 允许用户指定相对路径代替绝对路径;
- 名字解析:
- 文件系统的挂载:
挂载文件系统的挂载点,用户看到的是一个目录,是一个特殊的文件;
mount
是挂载的命令,unmount
是卸载的命令;操作较简单;
文件别名
- 文件别名,两种实现方式:
- 硬链接:
多个文件项指向同一个文件; - 软链接:
这个文件的内容是另一个文件的路径;
- 硬链接:
- 如果将有效的文件删除:
- 硬链接情况:
只是引用计数减一,只有当引用技术变为0,这个文件才彻底删除; - 软链接情况:
这个别名将成为一个“悬空指针”;
- 硬链接情况:
- 路径循环
文件系统的种类
- 磁盘文件系统:
- 文件存储在数据存储设备上,如磁盘;
- 例如:FAT、NTFS、ext2/3、IS09660等;
- 数据库文件系统:
- 文件根据其特征是可被寻址(辨识)的;
- 例如:winFS;
- 日志文件系统:
- 记录文件系统的修改、事件;
- 例如:Journaling file system;
- 网络、分布式文件系统:
- 例如:NFS、SMB、AFS、GFS;
- 特殊、虚拟文件系统;
ext2/3/4
是主要的文件系统,存储在磁盘或者光盘上;
日志文件系统的读操作、写操作要么不完成,要么就是完成,在中间进行的基础中是不会被打断的;
网络文件系统只要在局域网内,就可以很容易地访问另外一个机器上面的数据;
虚拟文件系统,LINUX下的proc可以看见中断的次数等等内核信息;
网络、分布式文件系统
-
文件可以通过网络被共享:
- 文件位于远程服务器;
- 客户端远程挂载服务器文件系统;
- 标准系统文件访问被转换成远程访问;
- 标准文件共享协议:NFS for Unix,GIFS for Windows;
-
分布式文件系统的问题
- 客户端和客户端上的用户辨别起来很复杂;
- 例如:NFS是不安全的;
- 一致性问题;
- 错误处理模式;
虚拟文件系统
- 为什么使用虚拟文件系统?
如果让应用程序针对不同的文件系统写出应用程序,就会很复杂;通过操作系统实现了,利用其提供的接口,通过一层虚拟文件系统层,屏蔽了底层具体文件系统的差异性,从而可以使得其可以访问不同的文件系统,使用面更好;
- 虚拟文件系统的目标
屏蔽具体文件系统的差异性,给上层提供统一的接口,可以完成基本的文件操作,如读写打开关闭等,也就是对所有不同文件系统的抽象;
- 虚拟文件系统的功能:
- 提供相同的文件和文件系统的接口;
- 管理所有文件和文件系统关联的数据结构;
- 高效查询例程,遍历文件系统;
- 与特点文件系统模块的交互;
- 注意:
虚拟文件系统不在具体的磁盘上,而是在内存中,由操作系统所创建;
- 控制块介绍
- 卷控制块/超级块(Unix:superblock):
每个文件系统都有一个总控制块;- 每个文件系统一个;
- 文件系统详细信息;
- 块、块大小、空余块、计数、指针等;
- 文件控制块(Unix:vnode or inode):
每一个具体的文件其实也需要一定的元数据和特征,所有有一个文件控制块;- 每个文件一个;
- 文件详细信息;
- 许可、拥有者、大小、数据库位置等;
- 目录节点(Linux:dentry):
目录里面的内容是里面的文件,文件的内容是内容,所以目录节点会有所不同,目录节点;- 每个目录一个(目录和文件);
- 将目录项数据结构及树型布局编码成树型数据结构;
- 指向文件控制块,父节点,项目列表等;
- 卷控制块/超级块(Unix:superblock):
这些概念可以构成一个抽象的文件系统图:
首先有一个总控制节点,这之下管理一堆目录,目录可以管理子目录或文件,文件里面是具体的数据(数据块),这些数据都是放在磁盘里面的;
- 文件系统的数据结构:
这些都会映射到磁盘里面的一个或多个扇区,文件里面的数据也会放在扇区里面;- 卷控制块(每个文件系统一个);
- 文件控制块(每个文件一个);
- 目录节点(每个目录项一个);
-
问题:
这些内容什么时候会加载到内存?- 卷控制块:
当文件系统挂载时进入内存; - 文件控制块:
当文件被访问时进入内存; - 目录节点:
在遍历一个文件路径时进入内存;
通过vol总控制块可以找到目录,而通过目录可以找到子目录或文件,而通过文件控制块可以最终找到想要寻找的数据;
- 卷控制块:
数据缓存
由于访问磁盘速度较慢,在内存中会有一块缓存;
-
数据缓存需要考虑的内容:
- 数据块按需读入内存:
- 提供read()操作;
- 预读:预选读取后面的数据块;
- 数据块使用后被缓存:
- 假设数据将会再次被使用;
- 写操作可能会缓存和延迟写入;
- 两种数据块缓存方式:
- 普通缓冲区缓存;
- 页级存:统一缓存数据块和内存页;
- 数据块按需读入内存:
-
希望基于分页的一个缓存机制,使得数据更好给上层 程序更好的访问;
- 总的来说:
缓存是为了进程执行的更加高效,为了减少硬盘的访问次数,减少运算时间;
打开文件的数据结构
-
打开文件描述:
- 每个被打开的文件有一个;
- 文件状态信息;
- 目录项、当前文件指针、文件操作设置等;
-
打开文件表;
- 一个进程一个;
- 一个系统级的;
- 每个卷控制块也会保存一个列表;
- 所以如果有文件被打开将不能被卸载;
- 一些操作系统和文件系统提供该功能;
- 调节对文件的访问;
- 强制:
根据锁保持情况和需求拒绝访问; - 劝告:
进程可以查找锁的状态来决定怎么做;
文件分配
- 大多数文件都很小
- 需要对小文件提供强力的支持;
- 块空间不能太大;
- 一些文件很大
- 必须支持大文件(64-bit文件偏移);
- 大文件访问需要相当高效;
如何为一个文件分配数据块
- 分配方式:
- 连续分配;
- 链式分配;
- 索引分配;
- 指标:
- 高效:如存储利用(外部碎片);
- 表现:如访问速度;
- 连续分配
- 文件头指定起始块和长度;
- 位置、分配策略:
最先匹配、最佳匹配等等; - 优势:
- 文件读取表现好;
- 高效的顺序和随机访问;
- 劣势:
- 碎片;
- 文件增长问题:
- 预分配?
- 按需分配?
- 链式分配
- 文件以数据块链表方式存储;
- 文件头包含了第一块到最后一块的指针;
- 优点:
- 创建、增大、缩小很容易;
- 没有碎片;
- 缺点:
- 不可能进行真正的随机访问;
- 可靠性:
破坏一个链就会失去轨迹;
- 索引分配
- 为每个文件创建一个名为索引数据块的非数据数据块:
到文件数据块的指针列表; - 文件头包含了索引数据块;
- 优点:
- 创建、增大、缩小很容易;
- 没有碎片;
- 支持直接访问;
- 缺点:
- 当文件很小时,存储索引的开销相对较大;
- 如何处理大文件,索引太多;
- 为每个文件创建一个名为索引数据块的非数据数据块:
- 处理大文件的分配方式:
- 早期Unix的分配方式:
- 文件头包含13个指针:
- 10个指针指向数据块;
- 第11个指针指向间接数据块;
- 第12个指针指向二重间接数据块;
- 第13个指针指向三重间接数据块;
- 影响:
- 提高了文件大小限制阈值;
- 动态分配数据块,文件扩展很容易;
- 小文件开销小;
- 只为大文件分配间接数据块,大文件在访问间接数据块是需要大量的查询;
空闲空间列表
跟踪在存储中的所有未分配的数据块;
空闲空间列表存储在哪里;
空闲空间列表的最佳数据结构是什么;
- 用位图代表空闲数据块列表:
111111110011110011111111
;- 如果 i = 0表明数据块 i 是空闲的,反之则已分配;
- 使用简单但可能会是一个 big vector:
- 160 G B d i s k → 40 M b l o c k s → 5 M B w o r t h o f b i t s 160GB~disk\rarr 40M~blocks\rarr 5MB~~worth~~of~~bits 160GB disk→40M blocks→5MB worth of bits;
- 然而,如果空闲空间在磁盘中均匀分布,那么在找到“0”之间需要
n
/
r
n/r
n/r:
- n = 磁盘上数据块的总数;
- r = 空闲块的数目;
- 需要保护:
- 指向空闲列表的指针;
- 位图:
- 必须保存在磁盘上;
- 在内存和磁盘拷贝可能会有所不同;
- 不允许 b l o c k [ i ] block[i] block[i]在内存中的状态为 b i t [ i ] = 1 bit[i] = 1 bit[i]=1而在磁盘中 b i t [ i ] = 0 bit[i] = 0 bit[i]=0;
- 解决:
- 在磁盘上设置 b i t [ i ] = 1 bit[i] = 1 bit[i]=1;
- 分配 b l o c k [ i ] block[i] block[i];
- 在内存中设置
b
i
t
[
i
]
=
1
bit[i] = 1
bit[i]=1;
多磁盘管理 —— RAID
- 通常磁盘通过分区来最大限度减少寻道时间:
- 一个分区是一个柱面的集合;
- 每个分区都是逻辑上独立的磁盘;
- 分区:
硬件磁盘的一种适合操作系统指定格式的划分; - 卷:
一个拥有一个文件系统实例的可访问的存储空间;- 通常常驻在磁盘的单个分区上;
- 通常常驻在磁盘的单个分区上;
- 使用多个并行磁盘来增加:
- 吞吐量(通过并行);
- 可靠性和可用性(通过冗余);
- RAID —— 冗余磁盘阵列
- 各种磁盘管理技术;
- RAID levels:不同RAID分类(如RAID-0,RAID-1,RAID-5);
- 实现:
- 在操作系统内核:存储、卷管理;
- RAID硬件控制器(IO);
- RAID-0:
数据并行访问,提高吞吐率;- 数据块分层多个子块,存储在独立的磁盘中;
- 和内存交叉相似;
- 通过更大的有效块大小来提供更大的磁盘带宽;
- 数据块分层多个子块,存储在独立的磁盘中;
- RAID-1:
向两个硬盘写入同样的数据,镜像数据提高可靠性;- 可靠性成倍提高;
- 读取性能线性增加;
- 向两个磁盘写入,从任何一个读取
- RAID-3:
奇偶校验以bit来作校验单位,其它版本0、4、5都是以块来作为并行校验;
- RAID-4:
4个盘分区并行访问,1个盘来进行奇偶校验从而恢复达到容错;- 数据块级磁带配有专门奇偶校验磁盘:
- 允许从任意一个故障磁盘中恢复;
- 例如,存储8,9,10,11,12,13,14,15,0,1,2,3;
- 数据块级磁带配有专门奇偶校验磁盘:
- RAID-5:
校验是均匀的,访问是并行的,但是只能纠错一个;
- 条带化和奇偶校验按
byte-by-byte
或bit-by-bit
:- RAID-0/4/5: block-wise;
- RAID-3: bit-wise;
- RAID-5:每个条带块都有一个奇偶校验块
- 允许一个磁盘错误;
- RAID-6:有两个冗余块;
- 有一种特殊的编码方式;
- 允许两个磁盘错误;
磁盘调度
- 磁盘的最简单结构
IO请求调度算法
- 请求先来先执行
- 按顺序处理请求;
- 公平对待所有进程;
- 在有很多进程的情况下,接近随机调度的性能;
- 寻道移动最少
- 选择从磁臂当前位置需要移动最少的IO请求;
- 总是选择最短寻道时间;
- Scan扫描方法
先上到头,然后再下来,双方向;- 磁臂在一个方向上移动,满足所有为完成的情况,直到磁臂到达该方向上最后的磁道;
- 调换方向;
- 有时被称为
elevator algorithm
;
- 单向扫描:
只在一个方向上扫描,然后瞬间跳回最高点;
- C-SCAN
到请求的最后一点就返回;