【操作系统】Operation System-第13章-文件系统

操作系统—文件系统

image-20220604223550602

基本概念

文件系统和文件

  • 文件系统:一种用于持久性存储的系统抽象

    是操作系统中管理持久性数据的子系统,提供数据存储的访问功能

    ➢ 在存储器上:组织,控制,导航,访问和检索数据

    ➢ 大多数计算机系统包含文件系统

    ➢ 个人电脑,服务器,笔记本电脑

    ➢ ipad,Tivo / 机顶盒,手机 / 掌上电脑

    ➢ Google可能也是由一个文件系统构成的

  • 文件:文件系统中的一个单元的相关数据在操作系统中的抽象

    是具有符号名,由字节序列构成的数据项集合

    ➢ 文件系统的基本数据单位

    ➢ 文件名是文件的标志符号

文件系统的功能

  • 分配文件磁盘空间

    ➢ 管理文件块(哪一块属于哪一个文件)

    ➢ 管理空闲空间(哪一块是空闲的)

    ➢ 分配算法(策略)

  • 管理文件集合

    ➢ 定位文件及其内容

    ➢ 命名:通过名字找到文件的接口

    ➢ 最常见:分层文件系统

    ➢ 文件系统类型(组织文件的不同方式)

  • 提供的便利及特征

    ➢ 保护:分层来保护数据安全

    ➢ 可靠性 / 持久性:保持文件的持久即使发生崩溃,媒体错误,攻击等

文件和块

  • 文件属性

    ➢ 名称,类型,位置,大小,保护,创建者,创建时间,最久修改时间,…

  • 文件头

    ➢ 在存储元数据中保存了每个文件的信息

    ➢ 保存文件的属性

    ➢ 跟踪哪一块存储块属于逻辑上文件结构的哪个偏移

文件描述符

  • 文件使用模式

    ➢ 使用程序必须在使用前先“打开”文件

    f = open(name, flag);
    ...
    ... = read(f, ...);
    ...
    close(f);
    
  • 内核跟踪每个进程打开的文件

    ➢ 操作系统为每个进程维护一个打开文件表

    ➢ 一个打开文件描述符是这个表中的索引

image-20220604232019678

  • 需要元数据来管理打开文件:

    ➢ 文件指针:指向最近的一次读写位置,每个进程分别维护自己的打开文件指针

    ➢ 文件打开计数:记录文件打开的次数 - 当最后一个进程关闭了文件时,允许将其从打开文件表中移除

    ➢ 文件磁盘位置:缓存数据访问信息

    ➢ 访问权限:每个程序访问模式信息

文件的用户视图和系统视图

  • 用户视图

    ➢ 持久的数据结构

  • 系统访问接口

    字节序列的集合(UNIX)

    ➢ 系统不会关心你想存储在磁盘上的任何的数据结构

  • 操作系统内部视角

    ➢ 块的集合(块是逻辑存储单元,而扇区是物理存储单元)

    ➢ 块大小<> 扇区大小:在UNIX中,块的大小是4KB

用户视图到系统视图的转换

  • 当用户说:给我2-12字节空间时会发生什么?(进程读文件)

    ➢ 获取字节所在的块

    ➢ 返回快内对应部分

  • 如果要写2-12字节?(进程写文件)

    ➢ 获取块

    ➢ 修改块内对应部分

    ➢ 写回块

  • 在文件系统中的所有操作都是在整个块空间上进行的(基本操作单位是数据块)

    ➢ 举个例子,getc() putc(): 即使每次只访问1字节的数据,也会缓存目标数据4096字节(一个磁盘块)

访问模式

  • 用户怎么访问文件

    ➢ 在系统层面需要知道用户的访问模式

  • 顺序访问:按字节依次读取

    ➢ 几乎所有的访问都是这种方式

  • 随机访问:从中间读写

    ➢ 不常用,但是仍然重要。例如:虚拟内存支持文件,内存页存储在文件中

    ➢ 更加快速 - 不希望获取文件中间的内容的时候也必须先获取块内所有字节

  • 基于内容(索引)访问:通过数据特征索引

    ➢ 通常操作系统不完整提供索引访问

    ➢ 数据库是建立在索引内容的磁盘访问上(需要高效的随机访问)

索引访问文件示例

image-20220605121317358

文件内部结构

  • 无结构

    ➢ 单词、比特的队列

  • 简单记录结构

    ➢ 列

    ➢ 固定长度

    ➢ 可变长度

  • 复杂结构

    ➢ 格式化的文档(如,MS word, PDF)

    ➢ 可执行文件

    ➢ …

文件共享和访问控制

  • 多用户系统中的文件共享是很必要的

  • 访问控制

    ➢ 谁能够获得哪些文件的哪些访问权限

    ➢ 访问模式:读,写,执行,删除,列举等

  • 文件访问控制列表(ACL)

    ➢ <文件实体, 权限>

  • Unix模式

    ➢ <用户|组|所有人,读|写|可执行>

    用户ID识别用户,表明每个用户所允许的权限及保护模式

    组ID允许用户组成组,并指定了组访问权限

语义一致性

  • 指定多用户 / 客户如何同时访问共享文件:

    ➢ 和过程同步算法相似

    ➢ 因磁盘IO和网络延迟而设计简单

  • UNIX文件系统(UFS)语义

    ➢ 对打开文件的写入内容立即对其他打开同一文件的其他用户可见

    ➢ 共享文件指针允许多用户同时读取和写入文件

  • 会话语义

    ➢ 写入内容只有当文件关闭时可见

  • ➢ 一些操作系统和文件系统提供该功能

目录

分层文件系统

  • 文件以目录的方式组织起来

  • 目录是一类特殊的文件

    ➢ 每个目录都包含了一张表 <name,pointer to file header>

  • 目录和文件的树型结构

    ➢ 早期的文件系统是扁平的(只有一层目录)

  • 层次名称空间

    image-20220605123022872

目录操作

  • 典型操作

    ➢ 搜索文件

    ➢ 创建文件

    ➢ 删除文件

    ➢ 枚举目录

    ➢ 重命名文件

    ➢ 在文件系统中遍历一个路径

  • 操作系统应该只允许内核模式修改目录

    ➢ 确保映射的完整性

    ➢ 应用程序能够读目录(如 ls)

目录实现

  • 文件名的线性列表,包含了指向数据块的指针

    ➢ 编程简单

    ➢ 执行耗时

  • Hash表 - hash数据结构的线性表

    ➢ 减少目录搜索时间

    ➢ 碰撞 - 两个文件名的hash值相同

    ➢ 固定大小

名字解析(路径遍历)

  • 名字解析:逻辑名字转换成物理资源(如文件)的过程

    ➢ 在文件系统中:到实际文件的文件名(路径)

    ➢ 遍历文件目录直到找到目标文件

  • 举例:解析 “/bin/ls”

    ➢ 读取root的文件头(在磁盘固定位置)

    ➢ 读取root的数据块:搜索 “bin” 项

    ➢ 读取bin的文件头

    ➢ 读取bin的数据块:搜索 “ls” 项

    ➢ 读取ls的文件头

  • 当前工作目录(PWD)

    ➢ 每个进程都会指向一个文件目录用于解析文件名

    ➢ 允许用户指定相对路径来代替绝对路径,如,用 PWD=“/bin” 能够解析 “ls”

文件系统挂载

  • 一个文件系统需要先挂载才能被访问
  • 一个未挂载的文件系统被挂载在挂载点

image-20220605131138491

文件别名

  • 两个或多个文件名关联同一个文件

    image-20220605130157203

  • 硬链接:多个文件项指向一个文件

  • 软链接:以“快捷方式”指向其他文件

    ➢ 通过存储真实文件的逻辑名称来实现

  • 如果删除一个有别名的文件会如何呢?

    ➢ 这个别名将成为一个 “悬空指针”

  • Backpointers方案:

    ➢ 每个文件有一个包含多个backpointers的列表,所以删除所有的backpointers

    ➢ Backpointers使用菊花链管理

  • 添加一个间接层:目录项数据结构

    ➢ 链接 - 已存在文件的另外一个名字(指针)

    ➢ 链接处理 - 跟随指针来定位文件

文件目录中的循环

image-20220605130500357

  • 如何保证没有循环?

    ➢ 只允许到文件的链接,不允许在子目录的链接

    ➢ 增加链接时,用循环检测算法确定是否合理

  • 更多实践

    ➢ 限制路径可遍历文件目录的数量

文件系统种类

  • 磁盘文件系统

    ➢ 文件存储在数据存储设备上,如磁盘

    ➢ 例如:FAT,NTFS,ext2/3,ISO9660 等

  • 数据库文件系统

    ➢ 文件特征是可被寻址(辨识)的

    ➢ 例如:WinFS

  • 日志文件系统

    ➢ 记录文件系统的修改/事件

    ➢ 例如:journaling file system

  • 网络 / 分布式文件系统

    ➢ 例如:NF,SMB,AFS,GFS

  • 特殊 / 虚拟文件系统

网络 / 分布式文件系统

  • 文件可以通过网络被共享

    ➢ 文件位于远程服务器

    ➢ 客户端远程挂载服务器文件系统

    ➢ 标准系统文件访问被转换成远程访问

    ➢ 标准文件共享协议:NFS for Unix,CIFS for Windows

  • 分布式文件系统的挑战

    ➢ 客户端和客户端上的用户辨别起来很复杂

    ​ √ 例如,NFS是不安全的

    一致性问题

    ➢ 错误处理模式

虚拟文件系统

  • 分层结构

    ➢ 顶层:文件 / 文件系统API

    ➢ 上层:虚拟(逻辑)文件系统 (将所有设备IO,网络IO全抽象成为文件,使得接口一致)

    ➢ 底层:特定文件系统模块

image-20220605143652387

  • 目的

    ➢ 对所有不同文件系统的抽象

  • 功能

    ➢ 提供相同的文件和文件系统接口

    ➢ 管理所有文件和文件系统关联的数据结构

    ➢ 高效查询例程,遍历文件系统

    ➢ 与特定文件系统模块的交互

基本数据结构

  • 卷控制块(UNIX:“superblock”)

    ➢ 每个文件系统一个

    ➢ 文件系统详细信息

    ➢ 块、块大小、空余块、计数 / 指针等

  • 文件控制块(UNIX:“vnode” or “inode”)

    ➢ 每个文件一个

    ➢ 文件详细信息

    ➢ 许可、拥有者、大小、数据库位置等

  • 目录节点(Linux:“dentry”)

    ➢ 每个目录项一个(目录和文件)

    ➢ 将目录项数据结构及树形布局编码成树形数据结构

    ➢ 指向文件控制块、父节点、项目列表等

image-20220605171108828

  • 文件系统数据结构

    ➢ 卷控制块(每个文件系统一个)

    ➢ 文件控制块(每个文件一个)

    ➢ 目录节点(每个目录项一个)

  • 持续存储在二级存储中

    ➢ 在分配在存储设备中的数据块中

  • 当需要时加载进内存

    ➢ 卷控制块:当文件系统挂载时进入内存

    ➢ 文件控制块:当文件被访问时进入内存

    ➢ 目录节点:在遍历一个文件路径时进入内存

数据块缓存

image-20220605150421097

  • 数据块按需读入内存

    ➢ 提供read()操作

    ➢ 预读:预先读取后面的数据块

  • 数据块使用后被缓存

    ➢ 假设数据将会再次被使用

    ➢ 写操作可能被缓存和延迟写入

  • 两种数据块缓存方式

    ➢ 普通缓冲区缓存

    ➢ 页缓存:同一缓存数据块和内存页

  • 分页要求

    ➢ 当需要一个页时才将其载入内存

  • 支持存储

    ➢ 一个页(在虚拟地址空间中)可以被映射到一个本地文件中(在二级存储中)

image-20220605154730566

  • 文件数据块的页缓存

    ➢ 在虚拟内存中文件数据块被映射成页

    ➢ 文件的读/写操作被转换成对内存的访问

    ➢ 可能导致缺页和/或设置为脏页

    ➢ 问题:页置换 - 从进程或文件页缓存中?页置换算法需要协调虚拟存储和页缓存间的页面数。

image-20220605154918399

打开文件的数据结构

  • 打开文件描述符

    ➢ 每个被打开的文件一个都有一个文件描述符

    ➢ 文件状态信息

    ➢ 目录项,当前文件指针,文件操作设置等

  • 打开文件表

    ➢ 一个进程一个

    ➢ 一个系统级的

    ➢ 每个卷控制块也会保存一个列表

    ➢ 所以如果有文件被打开将不能被卸载

image-20220605160905754

打开文件锁

  • 一些操作系统和文件系统提供该功能

  • 调节对文件的访问

  • 强制和劝告:

    ➢ 强制 - 根据锁保持情况和需求拒绝访问

    ➢ 劝告 - 进程可以查找锁的状态来决定怎么做

文件分配

文件大小

  • 大多数文件都很小

    ➢ 需要对小文件提供强力的支持

    ➢ 块空间不能太小

  • 一些文件非常大

    ➢ 必须支持大文件(64-bit 文件偏移)

    ➢ 大文件访问需要相当高效

文件分配

  • 如何为一个文件分配数据块

  • 分配方式

    连续分配

    链式分配

    索引分配

  • 指标

    ➢ 高效:如存储利用(外部碎片)

    ➢ 表现:如访问速度

连续分配

image-20220605162138965

  • 文件头指定起始块和长度

  • 位置 / 分配策略

    ➢ 最先匹配,最佳匹配,…

  • 优势

    ➢ 文件读取表现好

    ➢ 高效的顺序和随机访问

  • 劣势

    ➢ 碎片!

    ➢ 文件增长问题

    ​ √ 预分配?

    ​ √ 按需分配?

链式分配

image-20220605164705993

  • 文件以数据块链表方式存储

  • 文件头包含了到第一块和最后一块的指针

  • 优点

    ➢ 创建,增大,缩小很容易

    ➢ 没有碎片

  • 缺点

    ➢ 不可能进行真正的随机访问

    ➢ 可靠性

    ​ √ 破坏一个链然后…

索引分配

image-20220605164911568

  • 为每个文件创建一个名为索引数据块的非数据数据块

    ➢ 到文件数据块的指针列表

  • 文件头包含了索引数据块

  • 优点

    ➢ 创建,增大,缩小很容易

    ➢ 没有碎片

    ➢ 支持直接访问

  • 缺点

    ➢ 当文件很小时,存储索引的开销

    ➢ 如何处理大文件?链式、分层

image-20220605165206121

在早期的Unix系统中就采用了多级索引块方式,UFS多级索引分配:

image-20220605170843578

大文件的问题

  • 文件头包含13个指针

    ➢ 10个指针指向数据块

    ➢ 第11个指针指向索引块

    ➢ 第12个指针指向二级索引块

    ➢ 第13个指针指向三级索引块

  • 效果

    ➢ 提高了文件大小限制阈值

    ➢ 动态分配数据块,文件扩展很容易

    ➢ 小文件开销小

    ➢ 只为大文件分配间接数据块,大文件在访问数据块时需要大量查询

这几种办法都有各自的优点和缺点,在实际使用时会把这几种方法组合到一起来用。

空闲空间列表

  • 跟踪在存储中的所有未分配的数据块
  • 空闲空间列表存储在哪里?
  • 空闲空间列表的最佳数据结构是什么样的?

位图

  • 用位图代表空闲数据块列表:

    1111111111110011101001010111... 1111111111110011101001010111 ... 1111111111110011101001010111...

    ➢ 如果 i = 0 i = 0 i=0 表明数据块 i i i 是空闲的,反之则已分配

  • 使用简单但是可能会是一个 b i g   v e c t o r big\ vector 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 → 40M\ blocks → 5MB\ worth\ of\ bits 160GB disk40M blocks5MB worth of bits

    ➢ 然而,如果空闲空间在磁盘中均匀分布,那么在找到 “ 0 0 0” 之前需要扫描 n / r n / r n/r

    ​ √ n = 磁 盘 上 数 据 块 总 数 n=磁盘上数据块总数 n=

    ​ √ r = 空 闲 块 的 数 目 r=空闲块的数目 r=

保证一致性

  • 需要保护:

    ➢ 指向空闲列表的指针

    ➢ 位图

    ​ √ 必须保存在磁盘上

    ​ √ 在内存和磁盘拷贝可能有所不同

    ​ √ 不允许block[i]在内存中的状态为bit[i] = 1而在磁盘中bit[i] = 0

  • 解决:

    ➢ 在磁盘上设置bit[i] = 1

    ➢ 分配block[i]

    ➢ 在内存中设置bit[i] = 1

其他空闲空间列表方式

image-20220605172913426

多磁盘管理 - RAID

  • 通常磁盘通过分区来最大限度减小寻道时间

    ➢ 一个分区是一个柱面的集合

    ➢ 每个分区都是逻辑上独立的磁盘

image-20220605175215219

  • 分区:硬件磁盘的一种适合操作系统指定格式的划分

  • 卷:一个拥有完整文件系统实例的可访问的存储空间

    ➢ 通常常驻在磁盘的单个分区上

image-20220605175324841

多磁盘管理

  • 使用多个并行磁盘来增加

    ➢ 吞吐量(通过并行)

    ➢ 可靠性和可用性(通过冗余)

  • 冗余磁盘阵列 - RAID(Redundant Array of Inexpensive Disks)

    ➢ 各种磁盘管理技术

    ➢ RAID levels:不同RAID分类(如,RAID-0,RAID-1,RAID-5)

  • 实现

    ➢ 软件:在操作系统内核:存储 / 卷管理

    ➢ 硬件:RAID硬件控制器(I/O)

RAID-0

磁盘条带化

  • 数据块分成多个子块,存储在独立的磁盘中

    ➢ 和内存交叉相似

  • 通过更大的有效块大小来提供更大的磁盘带宽

image-20220605175821005

存储的时候磁盘分成三个子块,写数据 三个磁盘同时写,读也是同时读三个,速度会提升接近三倍;如果读的数据量比较小 只有第一组,那么速度是没有提升的。

RAID-1

磁盘镜像

  • 可靠性成倍增长

  • 读取性能线性增加

    ➢ 向两个磁盘写入,从任何一个读取

image-20220605181043418

提高可靠性,但也有一定的代价。

RAID-4

带校验的磁盘条带化(结合RAID-0、RAID-1)

  • 数据块级磁带配有专用奇偶校验磁盘

    ➢ 允许从任意一个故障磁盘中恢复

    ➢ 例如:存储8,9,10,11,12,13,14,15,0,1,2,3

image-20220605181917809

既能够提高性能,又能增加可靠性。

如果 D i s k 1 − 4 Disk1-4 Disk14 任何一个盘的数据丢失,可以通过另一个特殊的盘 P a r i r y   D i s k Pariry\ Disk Pariry Disk 把坏的数据恢复,通过纠错码的方式,假设某一个 D i s k i Disk_i Diski 坏了, P a r i r y   D i s k Pariry\ Disk Pariry Disk 中存的数据其实是数字的奇偶校验,可以把坏掉的盘的数据反推出来;

用额外的一个盘来完成容错的功能,出现一个故障可以恢复,但出现多个故障就不行了。

D i s k 1 − 4 Disk1-4 Disk14 任何一个磁盘进行写操作,此时 P a r i r y   D i s k Pariry\ Disk Pariry Disk 也需要进行一次写操作,所以它的读写非常频繁,会出现瓶颈,能否把 P a r i r y   D i s k Pariry\ Disk Pariry Disk 的开销均匀的分布在不同的盘中?↓

RAID-5

带分布式校验的磁盘条带化

  • 每个条带块有一个奇偶校验块

    ➢ 但同样 只允许有一个磁盘错误

image-20220605183231405

基于位和基于块的磁盘条带化

  • 条带化和奇偶校验按byte-by-byte或者bit-by-bit

    ➢ RAID-0/4/5:block-wise(基于数据块)

    ➢ RAID-3:bit-wise(基于位)

  • 例如:在RAID- 3系统中存储bit-string 101(粒度太细,不实用)

    image-20220605183721269

RAID-6

  • 每个条带块有两个冗余块

    ➢ 有一种特殊的编码方式

    ➢ 允许两个磁盘错误

进步一提高可靠性,当然这种可靠性到底提了多少,跟你数据的重要性和对可靠性的要求的不同而不同。

RAID嵌套

image-20220605184131123

磁盘调度

此内容我放在了下一章:【操作系统】Operation System-第14章-I/O子系统

整理自 【清华大学】 操作系统

猜你喜欢

转载自blog.csdn.net/weixin_53407527/article/details/125184605