文件系统

中优先级
本节的重点在于外存空间管理的方法,其他几个知识点也偶有考察,稍微了解下概念就行。

功能

文件系统(File System)作为操作系统与存储设备之间的桥梁,负责数据的存储、访问、管理和保护。简单来说,文件系统主要包含以下功能:

文件系统的核心功能File System文件系统① 数据组织/dira.txtb.log② 空间管理分配 / 回收空闲占用→ 减少碎片③ 数据访问AppFileopen / readwrite / close④ 数据保护rwxuser / group / other校验 / 备份 / 一致性
  1. 数据存储与组织
    • 文件系统以 文件目录 的形式组织数据,将存储设备的物理空间划分为 逻辑单元(如文件、文件夹),便于用户和应用程序访问与管理数据。
  2. 空间管理
    • 通过 空闲块管理(分配、回收、组织),文件系统高效利用存储空间,减少碎片,支持文件的创建、扩展和删除。常见方法包括 连续分配链接分配索引分配
  3. 数据访问与操作
    • 提供标准接口(如 打开关闭)支持对文件的访问和操作,确保数据的高效检索和修改,同时支持 随机访问顺序访问
  4. 数据保护和安全
    • 权限管理
    • 数据完整性校验
注意

文件系统和磁盘的功能区别

文件系统和磁盘在存储管理中扮演不同角色。磁盘负责物理存储,提供固定大小的 扇区(通常为 512字节4KB),作为数据读写的 最小物理单位。文件系统则在磁盘之上构建 逻辑结构,负责数据的组织和管理,以 盘块(或簇) 为单位进行空间分配和操作。

盘块/簇是文件系统定义的 逻辑单位,其大小在格式化时确定(常见如 4KB8KB 等),用于管理文件的存储和访问。盘块通常是 扇区 的整数倍,便于将逻辑操作映射到物理存储。扇区 则是磁盘的物理单位,硬件层面的最小读写单位,固定且不可更改。

全局结构

MBR
Parition 1
Partition 2
Partition Table
boot sector
super block
free space management
inodes
file and directory data
File System Metadata
Data Area
Disk

如上图所示,磁盘从逻辑上分为如下部分:

  1. 引导区(Master Boot Sector,MBR):引导区位于磁盘的起始位置,通常是磁盘的第一个 扇区。它包含 引导加载程序(boot loader),用于引导操作系统。引导加载程序负责启动计算机并加载操作系统内核。
  2. 分区表(Partition Table):分区表通常存储在磁盘的第一个扇区之后,用于记录磁盘上的 分区信息。分区表指示了磁盘上每个分区的起始位置、大小和文件系统类型。不同操作系统使用不同的分区表格式,如 MBR(Master Boot Record)和 GPT(GUID Partition Table)。
  3. 分区(Partition):分区中存储有 文件系统,文件系统中包含 元数据数据区 这两个部分。
    • 元数据
      • 超级块(Superblock):包含文件系统的关键信息,在计算机启动时,超级块会被载入内存。超级块中包含的典型信息包括分区的块的数量、块的大小、空闲空间的管理方式等。
      • 空闲块信息:管理磁盘中空闲块的存储数据,具体方法见下文空闲空间管理方法
      • inodes:管理文件的元数据
    • 数据区:文件系统的 数据区 存储了实际的文件数据。这是存储文件内容的地方。文件系统会将文件数据分为一个或多个 ,并将这些块分布在磁盘上的不同位置。文件系统的 数据区 通常占据了磁盘上的大部分空间。

下图是一个 文件系统分区(Partition)上的存储示例,文件系统的 元数据superblockinode 位图区(inode bmap)、数据块位图区(data bmap)、inode 存储区(inode region)这四个部分构成。

D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
D
Data Region
Data Region
Inode Region
0
7
8
15
16
23
24
31
32
39
40
47
48
55
56
63
I
I
I
I
I
d
i
S
Abbreviation
Meaning
S
Superblock
i
inode bmap
d
data bmap
I
inode region
D
data region
Super
i-bmap
d-bmap
0
4
8
12
1
5
9
13
2
6
10
14
3
7
11
15
16
20
24
28
17
21
25
29
18
22
26
30
19
23
27
31
32
36
40
44
33
37
41
45
34
38
42
46
35
39
43
47
48
52
56
60
49
53
57
61
50
54
58
62
51
55
59
63
64
68
72
76
65
69
73
77
66
70
74
78
67
71
75
79
0KB
4KB
8KB
12KB
16KB
20KB
24KB
28KB
32KB
iblock 0
iblock 1
iblock 2
iblock 3
iblock 4
The Inode Table
文件系统元%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3Bdashed%3D1%3BdashPattern%3D12%2012%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22-245%22%20y%3D%22170%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%221397.2727272727273%22%20y%3D%22160%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3Bdashed%3D1%3BdashPattern%3D12%2012%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22-245%22%20y%3D%22170%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%221397.2727272727273%22%20y%3D%22160%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E数据
文件系统
图中的缩写

外存空间管理

文件存储设备(如硬盘、SSD)将存储空间划分为多个大小相同的 物理块(通常为 512字节4KB 或更大),以块为单位进行数据的读写和交换。因此,文件系统的外存管理实质上是对这些 物理块(特别是 空闲块)的组织、分配与回收的管理。以下详细说明空闲块管理的关键问题和方法:

文件系统外存空间管理的思想和 文件的物理结构 十分类似,不过两者应用的对象不一样:

  • 外存空间管理的对象是 空闲磁盘块
  • 文件的物理结构管理的对象是 被文件使用的数据块

空闲表法

再该方法中,系统需要维护一张 空闲块表,用以记录磁盘上尚未分配的连续空闲块的所在位置和大小。表格的每一行描述一个空闲区段。

序号
第一个空闲盘块号
空闲盘块数
1
2
4
2
9
3
3
15
5
4
-
-

空闲块表应包含以下两个字段:

  • 起始空闲盘块号:该空闲区段的第一个盘块编号
  • 空闲盘块数:该区段中连续空闲盘块的数量

这样,空闲块表就能够清晰、完整地反映磁盘空间的空闲情况,为后续的块分配和回收提供可靠依据。

空闲表法:磁盘空闲块分布示意空闲块已占用块012345678910111213141516171819盘块号序号1:起始 2,数量 4序号2:起始 9,数量 3序号3:起始 15,数量 5上图与 file_free_list 空闲表一一对应:每个绿色连续段即表中一行记录,红色为已被文件占用、不出现在空闲表中的块。

空闲链表法

空闲链表法(Free List)使用 链表 来组织和管理磁盘上的所有空闲盘块。系统将 每一个空闲盘块本身作为链表的一个结点,并在空闲盘块中保存 下一个空闲盘块的盘块号(next 指针),从而把所有空闲盘块串联成一条链表。系统只需维护一个 链表头指针,即可访问整个空闲块链表。

0
1
2
3
4
5
6
7
8
9
10
3
12
13
14
15
16:1
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
free-space
linked list head

这样,所有空闲盘块就构成了一条链表:

  • 分配时:系统从链表头取出第一个空闲盘块作为新分配的磁盘块,然后将头指针移动到链表中的下一个空闲盘块即可,分配时间复杂度为 O(1)
  • 回收时:释放的盘块重新变为空闲盘块,并在其中写入原链表头的盘块号,再将链表头更新为该盘块,即可完成回收,时间复杂度同样为 O(1)
  • 遍历时:若需要统计空闲空间或查找所有空闲盘块,只需从链表头开始依次访问即可。

由于空闲链表法仅需要维护一个链表头指针,因此实现简单,分配和回收效率较高,但若需要遍历全部空闲盘块,则必须顺序访问整个链表,效率较低。

补充

空闲链表法与前面介绍的 文件物理结构中的链式分配 十分相似,它们都是将 next 指针直接存放在磁盘块内部,通过链表将多个磁盘块连接起来。二者的区别在于:

文件链式分配空闲链表法
链接的是 同一个文件的数据块链接的是 所有空闲盘块
每个数据块保存 文件数据 + 下一块盘块号每个空闲盘块保存 下一空闲盘块号(其余空间无需使用)

位图法

位图(Bitmap)是一种用二进制位数组来管理磁盘空闲块的方法。位图中的每一位(bit)对应磁盘上的一个数据块(通常为 4 KB、8 KB 等),通过该位的取值即可表示该数据块的使用状态:

  • 0:对应的数据块为空闲,可以分配给文件使用。
  • 1:对应的数据块已被占用,不能再次分配。
row/col
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
0
1
1
0
0
0
1
1
0
1
1
1
0
0
1
1
1
2
0
0
0
0
0
1
1
1
0
0
1
0
1
0
1
1
3
1
1
0
1
0
0
0
0
1
1
1
1
1
1
0
0
4
...

位图法的工作过程如下:

  1. 分配空闲块:当文件需要申请新的磁盘块时,文件系统在位图中查找值为 0 的位,找到后将其修改为 1,并把对应的数据块分配给该文件。
  2. 回收空闲块:当文件被删除或释放某些数据块时,文件系统将这些数据块对应的位重新置为 0,表示这些数据块重新变为空闲,可供后续分配。
位图法:空闲磁盘块的分配与回收0 空闲1 已占用本次操作初始位图状态:1101001010块0块1块2块3块4块5块6块7块8块9① 分配:扫描位图,找到第一个为 0 的位(块2),将其置 1分配后:块2 被分配(0 → 1)1111001010块0块1块2块3块4块5块6块7块8块9② 回收:文件释放块8,将对应位由 1 置 0回收后:块8 被释放(1 → 0)1111001000块0块1块2块3块4块5块6块7块8块9操作要点分配空闲块:• 从位图起始位置顺序扫描• 找到首个为 0 的位• 将该位改写为 1• 将对应数据块交给文件使用回收空闲块:• 由块号计算所在位的下标行号 = ⌊块号 / 每行位数⌋列号 = 块号 mod 每行位数• 将该位由 1 置 0• 数据块重新变为可分配状态优点:位图紧凑,一位即代表一块;扫描/位运算高效,便于连续分配。

成组链接法

成组链接法 是一种管理磁盘空闲盘块的方法。它的核心思想是:

不把所有空闲盘块一个一个串成链表,而是把若干个空闲盘块号分成一组,用一个磁盘块集中保存这一组空闲盘块号;多个组之间再用链接方式连接起来。

这样既避免了普通链表法中“每找到一个空闲块都要访问一次磁盘”的低效率,也比单纯位示图更适合某些文件系统的空闲空间管理。

size: 4
8
(single indirect)
4
5
6
· · · · · 
size: 10
23
53
16
77
· · · · · 
56
null
free block
free block
free block
free block
free block
free block
free block
free block

成组链接法可以理解为“组内用数组保存多个空闲盘块号,组间用链表连接”。

其大致过程如下:

  1. 把空闲盘块分组

    文件系统会把空闲盘块按一定数量分成若干组。 每一组中,用一个专门的磁盘块保存这一组空闲盘块的盘块号。

    例如,一个磁盘块中可以记录 100 个空闲盘块号,那么这一块就相当于一个“空闲盘块号表”。

  2. 组内保存多个空闲盘块号

    每个空闲块组中,保存的是若干个可分配的空闲盘块号。 当系统需要分配空闲盘块时,可以直接从当前组中取出一个盘块号,然后把对应的磁盘块分配出去。

    由于一次读入一个空闲块组后,就能得到多个空闲盘块号,所以分配效率比普通链表法更高。

  3. 组与组之间通过链接关系连接

    当当前组中的空闲盘块号快要用完时,需要知道下一组空闲盘块号在哪里。 因此,当前组中通常会保留一个位置,用来记录下一组空闲块组所在的盘块号。

    这样,系统就可以从当前组跳转到下一组,继续取得更多空闲盘块号。

  4. 分配空闲盘块

    分配时,系统优先从当前空闲块组中取出一个盘块号。 如果当前组中的盘块号还没有取完,就继续从本组分配。 如果当前组已经取完,就根据组间的链接关系找到下一组,并把下一组作为新的当前组。

  5. 回收空闲盘块

    回收时,系统把被释放的盘块号重新加入当前空闲块组中。 如果当前组已经装满,就可以重新开辟一个新的空闲块组,并把它链接到原来的空闲块组链中。

成组链接法(空闲盘块管理)展示成组链接法:多个空闲盘块号存放在一个磁盘块中形成空闲块组,组间用链表连接;分配时从当前组取出盘块号,取完转下一组;回收时把盘块号放回当前组,组满则建新组。核心思想把若干空闲盘块号存于一个磁盘块,称为"空闲块组"组内保存多个盘块号,组间用链表连接成链初始状态:空闲块组链组1(当前组)下一组盘块号:20100101102……199组2下一组盘块号:40200201202……299组3下一组盘块号:60300301302……399分配过程:从当前组取出盘块号组1(当前组)下一组盘块号:20100101102……199组2(当前组)下一组盘块号:40200201202……299回收过程:放回当前组组2(当前组)下一组盘块号:40200201202……299505(回收的盘块号)若当前组已满建立新组(如组4)并链接到原链表末尾再回收盘块号放入新组特点一次读入一个空闲块组,即可获得多个空闲盘块号,减少磁盘I/O次数分组存储+链表连接=成组链接法

因此,成组链接法的本质可以概括为:

用一个磁盘块集中保存一批空闲盘块号,减少磁盘访问次数;再用链接方式把不同批次的空闲盘块号组织起来,使空闲空间可以不断扩展。

提示

考研中一般不要求掌握非常细的实现细节,重点理解以下几点即可:

  • 它是用于 空闲磁盘块管理 的方法;
  • 它结合了 空闲表法空闲链表法 的思想;
  • 组内保存多个空闲盘块号,组间通过链接连接;
  • 分配时从当前组取空闲块,当前组用完后再转到下一组;
  • 回收时把释放的盘块号加入当前组,当前组满了再建立新组。

虚拟文件系统

虚拟文件系统Virtual File System,简称 VFS)是一种位于操作系统内核中的抽象层,它为各种底层文件系统提供统一的访问入口。通过 VFS,操作系统能够把不同存储介质(本地磁盘、网络共享、光盘等)和各类文件系统的实现细节屏蔽掉,使上层的系统调用和用户程序只需要面对一套一致的接口,而无需关心文件实际存放在哪里、采用何种组织方式。

VFS 的核心目标有三点:

  1. 统一接口:为所有文件系统提供统一的 API(如 openreadwriteclose 等),保证应用程序在对文件进行操作时的代码始终相同。
  2. 提升可扩展性:只要新的文件系统实现了 VFS 定义的接口,就可以通过注册驱动或模块的方式无缝加入系统,而无需修改内核其它部分。
  3. 增强可移植性:同一套系统调用在不同硬件平台或不同底层文件系统上均能工作,从而简化了跨平台软件的开发。
VFS Interface
local file system
type 1
local file system
type 2
remote file system
type 1
disk
disk
network
file-system interface

在 VFS 的架构中,每一种具体的文件系统(例如 ext4、NTFS、NFS、ISO 9660 等)都会实现一套内部的操作函数,并在启动时向 VFS 注册自己的驱动或模块。当应用程序发起文件操作时,流程大致如下:

  1. 系统调用入口:用户态程序调用如 open()read() 等系统调用。
  2. VFS 调度:VFS 接收到请求后,根据文件路径解析出对应的挂载点(mount point),进而确定使用哪一个底层文件系统。
  3. 转发到具体实现:VFS 将请求转交给已注册的文件系统驱动,由它完成实际的磁盘读取、网络通信或光盘访问等操作。
  4. 结果返回:底层文件系统返回操作结果,VFS 再把结果封装回系统调用的返回值,交给用户程序。

通过上述机制,应用程序能够实现 跨文件系统的透明访问,即无论文件位于本地硬盘、远程服务器还是光盘上,使用的代码完全相同。这种抽象不仅简化了软件开发,还为操作系统的模块化设计提供了坚实的基础。

文件系统挂载

文件系统挂载 是指把一个独立的文件系统与操作系统的目录结构(即文件树)关联起来,使得该文件系统中的文件和目录能够被正常访问和管理。简而言之,挂载的过程就是把存储介质(如硬盘分区、U 盘、光盘、网络共享等)上的文件系统“接入”到操作系统的统一命名空间中。

/
sbin
etc
opt
fs
cups
/dev/sda1
/
app1
app2
/dev/sda2
mkdir /opt/mount_fs
mount /dev/sda2 /opt/mount_fs
/
sbin
etc
opt
fs
cups
/dev/sda1
mount_fs
app1
app2

在大多数现代操作系统,文件系统挂载是一个必不可少的步骤,具体表现为:

  1. 识别存储设备
    系统先检测到设备的出现(如插入 U 盘、插入光驱、网络共享被建立),并确定该设备所使用的文件系统类型(ext4、NTFS、FAT32、ISO 9660、NFS、SMB 等)。
  2. 选择挂载点
    挂载点是文件树中的一个目录,系统会在该目录下“挂上”外部文件系统。挂载点本身必须是一个已存在且为空的目录(在 Linux/Unix 中常见的挂载点有 /mnt/media/boot 等),而在 Windows 中则对应于盘符(如 D:E:)。
  3. 执行挂载操作
    操作系统调用相应的挂载函数,将外部文件系统的根目录映射到挂载点。挂载完成后,用户和应用程序通过访问挂载点即可透明地读取、写入该文件系统中的文件,就好像这些文件本来就在本地目录一样。
  4. 管理与维护
    • 挂载选项:可以在挂载时指定只读、只写、用户权限、同步/异步等选项,以满足安全性或性能需求。
    • 自动挂载:在 Linux 中,/etc/fstab 文件或 systemdautomount 单元可以实现系统启动时自动挂载;在 Windows 中,使用 “磁盘管理” 或组策略设置网络驱动器的自动映射。
    • 卸载:使用 umount(Linux/Unix)或 “安全移除硬件”(Windows)将文件系统从挂载点分离,以防止数据丢失。

挂载可以提供以下优势:

  • 统一命名空间:无论底层是本地磁盘、光盘还是远程网络共享,所有资源都在同一棵目录树下呈现,简化了路径管理。
  • 跨文件系统协同:不同类型的文件系统(如 ext4 与 NTFS)可以并存,用户无需关心底层格式,只需通过统一的路径访问即可。
  • 资源隔离与安全:通过挂载选项可以限制对特定文件系统的读写权限,保护敏感数据不被意外修改。