【操作系统】文件管理

244 阅读17分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

注意:下面标星*的表示会在以后补充

文件

  • 定义:记录在辅助存储器上的相关信息的命名集合。
  • 电源故障和系统重新启动后仍然持续运行。
  • 操作系统通过文件提供信息存储的统一逻辑视图。
  • 操作系统将文件映射到物理设备。
    • 文件如何存储在物理设备上的逻辑表示。

文件系统: 一种存储和组织文件及其包含的数据的方法,以便于查找和访问。

文件的基本功能

  • 显示文件和目录的逻辑(抽象)视图。
    • 隐藏硬件设备的复杂性。
  • 促进存储设备的高效使用。
    • 优化访问,例如磁盘访问
  • 支持共享。
    • 提供保护。

*文件命名

文件存储在磁盘上的抽象信息。

*文件结构

字节序列、记录序列、树

文件类型

  • 常规文件
  • 目录
  • 字符特殊文件(Unix)
    • 用于模拟串行输入/输出设备,如终端、打印机等。
  • 块特殊文件(Unix)
    • 用于为磁盘建模。

Regular Files 常规文件

常规文件是包含用户信息的文件。

ASCII文件:

  • 一种文本文件,其中每个字节根据ASCII码表示一个字符。
  • 由文本行组成。
  • 行的长度不一定都相同。
  • 优势
    • 可以使用任何文本编辑器显示、打印和编辑。
    • 促进信息交流。

二进制文件:二进制文件内容必须由程序或硬件处理器解释,而这些程序或处理器必须事先准确了解其格式,具有内部结构

*文件存取 File Access

顺序存取和随机存取

*文件属性

*文件操作

问:一些操作系统提供系统调用rename来为文件命名。使用此调用重命名文件与仅将文件复制到具有新名称的新文件,然后删除旧文件之间有什么区别吗?

答:重命名调用不会更改创建时间或上次修改的时间,但创建新文件会使其获取当前时间作为创建时间和上次修改的时间。此外,如果磁盘已满,复制可能会失败

目录 Directory

  • 目录是一个包含文件名和文件位置之间对应关系的文件。
  • 目录条目(Directory entries)包含有关文件的信息(如属性)
  • 目录条目是在创建它们所描述的文件时创建的,而在删除文件时删除。

Directory Structures

Single-level Directory System 单级目录系统

一个目录包含所有文件,所有用户使用同一个目录

  • 优点:
    • 易于支持和理解。
  • 问题:
    • 命名问题(名称冲突Collision问题): 所有文件必须具有唯一的名称。
    • 分组问题:在大型文件系统中难以记住文件名

Two-level Directory System 二级目录系统

每个用户的单独目录

  • 文件名只需要在给定用户的目录中是唯一的。
  • 系统文件通常需要一个单独的目录。
  • 用户名和文件名定义路径名。

优缺点:

  • 优点
    • 解决名称冲突问题
      • 对于不同的用户可以有相同的文件名。
    • 高效的搜索。
    • 文件共享和保护。
  • 缺点
    • 分组问题未解决。

Hierarchical Directory System

文件在叶子节点上,内部节点是目录

优点:

  • 解决名称冲突问题
  • 对于不同的用户可以有相同的文件名。
  • 高效的搜索。
  • 文件共享和保护。
  • 解决分组问题

*Path Names

*Directory Operations

链接 创建从现有文件到路径名的链接。(即,建立“硬链接”。) 取消链接 删除“硬链接”。

File System Implementation 文件系统实现

File System Layout 文件系统布局

  • 0号扇区:“主引导记录 Master Boot Record”(MBR)
    • 包含分区映射。
  • 磁盘的其余部分划分为“分区Partition”。
    • 分区(Partition):连续的扇区
    • 每个分区都可以保存自己的文件系统。
  • 每个分区都以“引导块boot block”开头。
    • 包含一个“引导程序”从该分区中的文件系统读入操作系统。
    • 操作系统启动 BIOS读取MBR,然后读取并执行引导块。
  • partition在引导块后面还有超级块(Superblock)
    • 包含文件系统的所有关键参数

image.png

文件的实现(分配方式)

评价分配方式的关键指标(Key Metrics):

  • 碎片(内部和外部)?
  • 是否在初始创建后随时间增长文件?
  • 快速查找顺序和随机访问的数据?
  • 易于实现?
  • 存储开销?

Contiguous Allocation 连续分配

每个文件占用磁盘上一组连续的块。

  • 优势
    • 易于实现(只需要开始扇区和文件长度)。
    • 在系统崩溃时易于恢复。
    • 性能良好(适合顺序存取和直接存取)。
  • 缺点
    • 外部碎片(因为文件删除产生)
      • 需要定期压实(耗时)。
      • 需要管理空闲列表,在创建时必须知道文件的最大可能大小
    • 文件无法增长。
  • 适用于CD-ROM、DVD和其他一次性写入的光学介质。
    • 所有文件大小预先知道。
    • 永远不会删除文件。

Linked List Allocation 链表分配

每个文件都有一个链表,每个块的第一个块作为指向下一个块的指针

优势:

  • 无外部碎片
  • 目录条目很简单(只需要开始和结束块编号)。
  • 只要块可用,文件就可以继续增长。
  • 适合顺序访问

缺点:

  • 随机访问文件的速度很慢
  • 块中的数据存储量不再是2的幂(指针占用了一些字节),读取时需要从两个磁盘块中拼接成一个块,降低运行效率
  • 易碎:指针可能丢失或损坏。

Linked List Allocation Using FAT 在内存中采用表的链表分配

文件分配表(FAT):

  • 内存中保留表格:磁盘上每个块一个表项。
  • 每个表项都包含“next”块的地址。(把前面每个块中的指针取出来放在表中)

image.png

优势

  • 整个块可用于数据(没有指针)。
  • 利于随机访问:
    • 搜索链接列表(全部在内存中不需要磁盘引用)
  • 表项只需要一个数字:起始块编号 就能找到文件的所有块

缺点:整个表必须同时在内存中,占用内存空间

例子:磁盘大小200 GB,块大小1 KB,FAT表项(entry)大小4字节
用于存储FAT的内存4B×200GB/1KB=800MB4B×200GB/1KB=800 MB

indexed Allocation 索引i节点分配

解决基于文件分配表的链表分配,表必须同时在内存当中的问题

将所有指针合并到一个位置(索引块或i节点)

  • 每个文件都有自己的索引块。
  • 打开文件时将索引块加载到内存中,使其始终可用于随机访问。

优势:

  • 易于实现。
  • 无外部碎片
  • 文件可以在索引块大小的限制下增长。
  • 快速查找和随机访问。 缺点:
  • 文件块可能分散在整个磁盘
    • 顺序存取不良。
    • 需要碎片整理程序。
  • 索引块的空间开销
  • 需要随着文件大小的增加重新分配索引块

Multi-level Indexed Allocation 多级索引分配

Q:如果每个i节点都有空间容纳固定数量的磁盘地址,那么当文件增长超过此限制时会发生什么情况?
A:某些索引项指向索引块,建立多级索引,高级索引块包含指向低级索引块的指针

优势

  • 无外部碎片。
  • 与一级索引相比,文件可以很容易地以更大的限制增长
  • 快速随机访问。 缺点:
  • 实现可能很复杂。
  • 较大的空间开销(索引块空间开销未解决)。
  • 顺序访问可能很慢(未解决前面的文件块分散问题)
    • 必须为快速访问分配连续块。

*目录的实现

在Unix/Linux中,目录条目包含文件名、属性和文件的i节点号。目录项包含:文件名、i节点编号  i节点包含文件属性。

处理长文件名

Shared Files 共享文件

一个文件出现在多个目录中。

链接Link:目录和共享文件之间的连接称为链接。

Link建立

在Unix中:

  • 硬链接:

    • 两个目录都指向相同的i节点。 image.png
  • 符号链接Symbolic Links(软链接):

    • 建立类型为LINK的新文件,文件放在要连接的目录下,这个文件只包含文件原来的目录的“路径”
    • 原来的目录指向文件的i节点。

image.png

Link删除

硬链接

  • 在每个i节点中放置一个“引用计数”字段。
  • 统计指向文件的目录数。
  • 从目录中删除文件时,计数器-1
  • 计数为0时,回收文件中的所有块。 实例: (a)链接前的情况(b)创建链接后的情况(c)原始所有者删除文件后的情况 image.png

符号链接:删除真实文件(正常文件删除),符号链接变为“断开”(因为符号链接本身也只连接目录)。

缺陷

查找一个指定目录及其子目录下的某个文件,可能会被多次定位到一个被Link的文件

硬链接:

  • 无法跨文件系统建立链接。
  • 如果将其中一个文件移动到其他文件系统,则会将其复制,并相应调整两个文件的链接计数。
  • 只有超级用户才能创建指向目录的硬链接。

Symbolic Link:

  • 额外空间开销:磁盘上的额外空间(LINK文件)和用于存储LINK文件的额外inode。
  • 访问原始文件所需的额外时间:必须先读取链接文件,然后读取目标文件的路径。
  • 如果原始文件移动到其他位置,则无法再通过符号链接(悬挂链接)访问它。

磁盘空间管理

块大小

大块尺寸 内部碎片 最后一个块(平均)浪费了1/2的空间 很多非常小的文件;浪费更大。 小块尺寸 更多寻道时间;文件访问速度将变慢。

大,空间浪费,小,时间慢,进行时空权衡

典型块大小: MS-DOS FAT-12: 512B, 1KB, 2KB, 4KB
 FAT-16: 2KB, 4KB, 8KB, 16KB, 32KB
 FAT-32: 4KB, 8KB, 16KB, 32KB

Keeping Track of Free Blocks 记录空闲块

Bit Map

具有n个块的磁盘需要具有n个位的位图。 可用块用1表示。已分配块用0表示

优势

  • 简单易懂。
  • 很容易找到第一个空闲块。
  • 支持连续分配,很容易找到n个连续的空闲块。 缺点
  • 位图效率很低,除非整个位图都保存在主存中(并且偶尔会写入磁盘以满足恢复需要)。
  • 对于较小的磁盘,如果可以就将其保存在主存中,但对于较大的磁盘,不一定要将其保存在主内存中

Linked List

每个块可容纳尽可能多的可用磁盘块号

示例:计算保存完整空闲列表所需的最大块数。
16GB磁盘有2242^{24}个1KB的块,需要2242^{24}个/255个=65793个块。(假设32位块号,即每个块号4字节,除去每个块开头4个字节存放指向下个块的指针)

与位图比较(缺点):

  • 遍历列表和/或查找给定大小的连续块并不容易。
  • 链表需要较多的空间
    • 只有当磁盘几乎已满(即几乎没有可用块)时,链表方案才需要比位图更少的块
  • 主存中只需要保留一个指针块。在某些情况下,这种方法会导致不必要的磁盘I/O。
    • 当指针块几乎为空时,一系列短暂的临时文件可能会导致大量磁盘I/O。
    • 解决方案:将磁盘上的大多数指针块保持为满(以尽量减少磁盘使用),但将内存中的指针块保持为半满。

*Counting

  • 除了保留n个可用磁盘地址的列表外,我们还可以保留第一个可用块的地址以及第一个块之后的n个可用连续块的数量。
  • 然后,可用空间列表中的每个条目都包含一个磁盘地址和一个计数。
  • 虽然每个条目都需要比简单磁盘地址更多的空间,但只要计数通常大于1,整个列表就会更短。

*Disk Quotas

文件系统可靠性 File System Reliability

File System Back Up

Physical Dump

从磁盘上的块0开始, 按顺序复制每个块

Logical Dump

从一个或多个指定的目录开始,递归转储在其中找到的自给定基准日期以来已更改的所有文件和目录

文件和目录的增量转储: 将仅复制自上次增量备份以来已修改的文件包含任何修改文件的目录

  • 阶段1:从起始目录开始,检查其中的所有目录项。位图(i节点编号对应位编号)中标记每个修改的文件和每个目录(无论是否修改)。
  • 阶段2:递归遍历目录树,取消标记目录下没有修改过的文件或目录的目录
  • 阶段3:转储所有标记的目录
  • 阶段4:转储所有标记的文件

File System Consistency

多步骤更新会导致一致性问题

checking blocks 检查块

前提:每个磁盘块必须在一个文件(或目录)中,或在可用列表中。

  • 构建2个表,每个表包含每个块的一个计数器。
    • 一个表表示是否在使用,一个表表示是否空闲,两个表对应0 1不同才是一致的
  • 读取所有i节点并标记使用的块。
  • 检查空闲列表并标记空闲块。

块的不一致状态举例:

  • 同时为0:某些块不在文件或空闲列表中(“块丢失”)

    • 解决:添加到空闲列表 image.png
  • 空闲表有大于1:某些块多次出现在可用列表中

    • 使用位图时不会发生,只有空闲表是真正意义上的表时才发生。
    • 解决:修复空闲列表(或者重新建立空闲表),使块只显示一次。

image.png

  • 使用表有大于1:某些块位于多个文件中
    • 解决:分配另一个空闲块,复制块内容到该空闲块,把该块放到一个文件当中,通知用户该文件可能包含来自另一个文件的数据

image.png

  • 同时为1:某个块既在空闲表又在使用表

    • 解决:空闲表中对应值清0(将其移除空闲表) image.png
  • 某个块号两个表都大于1(假设都是2)的情况

    • 解决:这意味着某些块出现在两个文件中,在空闲列表中也出现两次。
      • 第一步是从空闲表中删除两个副本(空闲表-2)。
      • 接下来,必须获取另外一个空闲块,并将病态块的内容复制到那里。
      • 最后,应该更改其中一个文件中出现的块,以引用新获取的块副本

检查目录 checking directories

递归根目录下的树,计算每个文件的链接数。每个文件一个计数器(主要检查的内容)

  • 将这些数字与存储在i节点中的链路计数进行比较。
  • 每个i节点中的引用计数(计数在i节点中!)必须等于指向文件的硬链接数

两种不一致状态:

  • 引用计数太大
    • “rm”命令将删除硬链接。
    • 当计数变为0时,将释放块。
    • 永久分配:块永远不能重复使用。
  • 引用计数太小
    • 删除链接后,计数将很快变为零
    • 这些块将被添加到空闲列表中,即使文件仍在某个目录中

解决方案:将i节点中的链接计数强制调整为实际目录条目数

*File System Performance 文件系统性能

文件系统实例

MS-DOS 文件系统

目录

特点:

  • 使用8+3个文件名。
  • DOS 1.0仅限于一个目录。
  • 更高版本允许分层文件系统。
  • 目录可以嵌套到任意深度。
  • 目录大小可变
  • 目录项 directory entries 的大小固定为32字节。

目录项结构(图中单位为byte):

  • 属性:指示文件为只读、存档、隐藏或系统文件。
  • 时间:小时(5位)、分钟(6位)、秒(5位)
  • 日期:年(7位所以最多表示128年,而从1980年开始计数,因此使用该文件系统的2107年就寄了)、月(4位)、日(5位)
  • 大小:理论上可以是4GB(4字节32bit),但实际上是2GB或更少

image.png

使用文件分配表跟踪文件地址: 每个目录项只给出第一个块编号,用于索引到FAT表

FAT文件系统有三个MS-DOS版本:

  • FAT-12、FAT-16、FAT-32每个磁盘地址包含的位数不同
    • FAT-32随Windows 95第二版一起推出。
    • 磁盘块是512字节的倍数:每个分区可以不同。
  • 允许的块大小因变量而异。

下面只要记住最大块大小即可:

FAT-12:

  • 12位磁盘地址(一个地址表示一个块
  • 块大小最大4KB212KB2^{12}KB
  • 分区大小:理论上最大16MB(212×2122^{12}×2^{12}字节)。 FAT-16:
  • 16位磁盘地址(一个地址表示一个块)
  • 块大小最大32KB215KB2^{15}KB
  • 分区大小:理论上最大2GB(216×2152^{16}×2^{15}字节)。 FAT-32:
  • 28位磁盘地址(一个地址表示一个块)
  • 块大小最大32KB215KB2^{15}KB
  • 分区大小:理论上最大8TB(228×2152^{28}×2^{15}字节),但通常限制为2TB。

image.png

FAT-32相对于FAT-16的优势:

  • 支持更大的磁盘。
  • 使用FAT-32的8 GB磁盘可以是单个分区。
  • 使用FAT-16必须有四个分区。
  • 对于给定大小的磁盘分区,可以使用较小的块大小。

练习题:

  • Q:MS-DOS FAT-16表包含64K个条目,假设其中一个位用于其他目的,而该表正好包含32768(2152^{15})个条目。如果没有其他更改,在这种情况下,最大的MS-DOS文件多大?
  • A:FAT-16最大块为32KB。有了2152^{15}个这样的块,最大的文件大小1 GB。

The UNIX V7 File System

目录

以从根开始的树的形式组织的,文件名最多14个字符,可以包含除/和NUL之外的任何ASCII字符。

目录项:

  • 文件名,以及该文件的i节点的#(2字节)
  • 文件系统中的文件数限制为64K image.png

image.png

image.png

  • Q1:Unix文件系统有1KB的块和4字节的磁盘地址。如果i节点可以是直接条目,一个、两个和三个间接条目,并且直接i节点包含10个间接目录项,则最大文件大小是多少?
  • A:i节点包含10个指针。单个间接块包含256个指针。双间接块适用于2562256^2个指针。三重间接块适用于2563256^3个指针。将这些数据相加,我们得到的最大文件大小为16843018个块,约为16.06 GB。

查找/usr/ast/mbox:

  • 文件系统定位根目录。它可以位于磁盘上的任何位置,但其i节点位于固定位置。
  • 文件系统查找路径的第一个组件(usr)并找到其i节点号。从这个i节点,系统定位/usr的目录,并在其中查找下一个组件(ast)。
  • 当在目录/usr中找到ast的条目时,可以获得目录/usr/ast的i-node。从这个i节点可以找到目录本身并查找mbox。
  • 然后将该文件的i节点读入内存,并保存在那里,直到文件关闭。

image.png

问题2:需要多少磁盘操作才能获取文件/usr/ast/course/os/handout.t的i节点假设根目录的i节点在内存中,但路径上的其他内容都不在内存中。还假设所有目录都适合一个磁盘块。

image.png

*The Linux Ext2 File System