原文筆記
Chap. 12 Note
12.1 Overview:文件与文件管理系统
文件系统的核心作用
- 文件系统是操作系统中用户最直接接触的部分之一。
- 文件用于长期保存输入、输出和程序运行结果。
- 文件具有独立于进程的生命周期:进程结束后文件仍可存在。
文件的三个重要性质
- 长期存在:文件存储在磁盘等二级存储器上,不随用户注销或进程结束而消失。
- 可共享:文件有名字和访问权限,可被多个进程或用户受控共享。
- 有结构:文件内部可以有记录、字段等结构;文件之间也可通过目录形成层次结构。
文件系统常见操作
- Create:创建文件,并放入文件结构中。
- Delete:删除文件。
- Open:进程打开文件,之后才能读写。
- Close:关闭文件,进程不再访问它。
- Read:读取文件的全部或部分内容。
- Write:写入或修改文件内容,可扩展文件大小。
文件属性
文件系统通常维护以下属性:
- 文件所有者
- 创建时间
- 最近修改时间
- 最近访问时间
- 文件大小
- 文件类型
- 访问权限
- 存储位置
数据层次结构
- Field 字段:最基本的数据元素,只包含一个值,如姓名、日期、传感器读数。
- Record 记录:一组相关字段,可被应用程序作为一个单位处理。
- File 文件:一组相似记录的集合,用户和程序按名字引用。
- Database 数据库:相关数据的集合,强调数据之间关系明确,并可被多个应用共享。
文件与数据库的区别
- 文件通常是一组相似记录的集合。
- 数据库不仅包含数据,还显式维护数据之间的关系。
- 数据库通常由独立的 DBMS 管理,但底层仍依赖操作系统文件管理功能。
文件可支持的典型记录级操作
- 顺序检索所有记录。
- 检索单条记录。
- 检索下一条记录。
- 检索上一条记录。
- 插入新记录。
- 删除记录。
- 更新记录。
- 按条件检索多条记录。
UNIX 类系统的特殊点
- UNIX 内核把普通文件看作字节流。
- 字段、记录等逻辑结构由应用程序自己解释,不由操作系统强制规定。
文件管理系统 File Management System
文件管理系统是一组系统软件,为用户和应用程序提供文件服务。
主要目标:
- 满足用户的数据管理需求。
- 尽可能保证文件数据有效。
- 优化系统吞吐量和用户响应时间。
- 支持多种存储设备。
- 减少或避免数据丢失。
- 为用户进程提供标准 I/O 接口。
- 在多用户系统中支持多用户文件访问。
文件管理系统的基本用户需求
- 用户能创建、删除、读、写、修改文件。
- 用户可受控访问其他用户文件。
- 用户可控制别人对自己文件的访问类型。
- 用户可在文件之间移动数据。
- 用户可备份和恢复文件。
- 用户可通过文件名而非数字编号访问文件。
文件系统软件层次结构
从低到高:
- Device Drivers 设备驱动:
- 直接与设备、控制器或通道通信。
- 启动 I/O 操作并处理中断或完成事件。
- Basic File System / Physical I/O 基本文件系统:
- 处理磁盘或磁带上的数据块。
- 关心块的位置和内存缓冲,不理解文件内容。
- Basic I/O Supervisor 基本 I/O 管理器:
- 负责文件 I/O 的启动和结束。
- 维护设备 I/O、调度、文件状态、缓冲区和空间分配。
- Logical I/O 逻辑 I/O:
- 面向记录而不是物理块。
- 维护文件的基本数据。
- Access Method 访问方法:
- 最接近用户和应用。
- 为不同文件结构提供统一接口,如顺序访问、索引访问、散列访问。
文件管理主要功能
- 目录管理:通过目录定位文件并维护属性。
- 访问控制:限制哪些用户可以怎样访问文件。
- 记录处理:把用户看到的记录映射到文件操作。
- 块管理:把逻辑记录组织为物理块。
- 二级存储管理:分配和回收磁盘块。
- I/O 调度:提升磁盘访问性能。
- 空闲空间管理:记录哪些磁盘块尚未使用。
12.2 File Organization and Access:文件组织与访问
文件组织的含义
- 文件组织指记录的逻辑结构,取决于记录的访问方式。
- 物理组织还受到记录阻塞和文件分配策略影响。
选择文件组织的重要标准
- 访问时间短。
- 易于更新。
- 节省存储空间。
- 维护简单。
- 可靠性高。
这些标准可能冲突:
- 索引能加快访问,但会增加冗余和空间开销。
- 顺序结构简单省空间,但随机访问慢。
五种基本文件组织
- Pile 堆文件。
- Sequential File 顺序文件。
- Indexed Sequential File 索引顺序文件。
- Indexed File 索引文件。
- Direct / Hashed File 直接文件或散列文件。
Pile 堆文件
特点:
- 最简单的文件组织。
- 数据按到达顺序收集。
- 每条记录可以字段不同、顺序不同。
- 字段通常需要自描述,包括字段名和值。
- 字段长度可通过分隔符、长度子字段或默认规则表示。
访问方式:
- 没有结构,只能穷尽搜索。
- 查找某字段或某值时,可能必须扫描整个文件。
优点:
- 易于插入和更新。
- 适合收集原始数据。
- 适合数据大小和结构变化很大的场景。
- 空间利用较好。
缺点:
- 查找效率差。
- 不适合大多数需要快速检索的应用。
Sequential File 顺序文件
特点:
- 最常见的文件结构。
- 记录格式固定。
- 所有记录长度相同。
- 字段数量、字段顺序和字段长度固定。
- 只需存储字段值,字段名和字段长度作为文件结构属性保存。
- 通常有一个 key field 关键字段。
- 关键字段唯一标识记录。
- 记录按关键字段顺序存储。
适用场景:
- 批处理应用。
- 每次处理全部或大部分记录,如工资、账单。
- 唯一容易同时存储在磁带和磁盘上的组织方式。
优点:
- 结构简单。
- 顺序处理效率高。
- 适合全文件扫描。
缺点:
- 单条记录查询慢,需要顺序搜索。
- 插入新记录困难。
- 常用 log file / transaction file 暂存新记录,再周期性批量合并。
链表式顺序文件:
- 每个物理块保存一个或多个记录。
- 块中包含指向下一块的指针。
- 插入时只需修改指针。
- 代价是额外指针开销和处理开销。
Indexed Sequential File 索引顺序文件
核心思想:
- 保留顺序文件按关键字排序的特点。
- 增加索引以支持随机访问。
- 增加溢出文件 overflow file 处理插入。
结构:
- 主文件按关键字段顺序排列。
- 索引文件包含关键字段和指向主文件的指针。
- 溢出文件保存新插入但尚未合并进主文件的记录。
查找过程:
- 先查索引,找到小于等于目标键的最大索引项。
- 根据指针进入主文件附近位置。
- 再顺序搜索少量记录。
优点:
- 比普通顺序文件大幅减少平均查找时间。
- 仍保留顺序处理能力。
- 可用多级索引进一步提升效率。
插入处理:
- 新记录先放入溢出文件。
- 前驱记录维护指向溢出记录的指针。
- 定期把主文件和溢出文件批量合并。
缺点:
- 溢出文件过大时性能下降。
- 需要定期重组。
- 主要仍围绕一个关键字段组织。
Indexed File 索引文件
核心思想:
- 放弃单一关键字段和顺序性。
- 记录通过多个索引访问。
- 每个可能被搜索的字段都可有索引。
索引类型:
- Exhaustive Index 穷尽索引:
- 每条记录都有一个索引项。
- Partial Index 部分索引:
- 只为包含某字段的记录建立索引。
优点:
- 可按多个属性高效查询。
- 记录位置不受限制。
- 支持变长记录。
- 适合查询频繁、实时性强的应用。
缺点:
- 新增记录时必须更新相关索引。
- 索引维护成本高。
- 全文件顺序处理不如顺序文件自然。
典型应用:
- 航空订票系统。
- 库存控制系统。
Direct / Hashed File 直接文件或散列文件
特点:
- 利用磁盘可直接访问已知地址块的能力。
- 每条记录仍需要关键字段。
- 不强调记录顺序。
- 对关键值应用散列函数,得到记录存储位置。
优点:
- 单条记录访问非常快。
- 适合固定长度记录。
- 适合每次只访问一条记录的场景。
缺点:
- 不适合顺序处理。
- 需要处理散列冲突,通常配合溢出区。
典型应用:
- 目录。
- 价格表。
- 日程表。
- 名单。
12.3 B-Trees:B 树
为什么需要 B 树
- 大文件或数据库中,单级顺序索引仍然太慢。
- 多级索引可提高访问效率。
- 普通树若不平衡,会出现长短不一的搜索路径。
- B 树是一种平衡的多路搜索树,适合作为大型索引结构。
B 树特点
- 是树结构,没有闭环。
- 由节点和叶子组成。
- 每个节点包含若干关键字和指向子节点的指针。
- 节点内关键字按非降序排列。
- 每个节点最多有相同数量的关键字。
- 所有叶子在同一层。
- 树保持平衡,搜索路径长度稳定。
- 分支因子大,因此树通常很矮。
B 树的度 d
若 B 树最小度为 d:
- 每个节点最多有 2d - 1 个关键字。
- 每个节点最多有 2d 个子指针。
- 除根节点外,每个内部节点至少有 d - 1 个关键字。
- 除根节点外,每个内部节点至少有 d 个子指针。
- 根节点至少有 1 个关键字和 2 个子节点。
- 有 k 个指针的非叶节点包含 k - 1 个关键字。
B 树查找
- 从根节点开始。
- 若关键字在当前节点中,查找成功。
- 若目标小于当前节点最小关键字,走最左指针。
- 若目标大于当前节点最大关键字,走最右指针。
- 若目标位于两个相邻关键字之间,走中间指针。
- 重复直到找到或到达叶子。
B 树插入
- 先按查找过程找到应插入的最低层节点。
- 若该节点未满,直接按顺序插入。
- 若节点已满:
- 围绕中位关键字分裂节点。
- 中位关键字提升到父节点。
- 左右两边形成两个节点。
- 若父节点也满,继续向上分裂。
- 若根节点分裂,则产生新根,树高加 1。
B 树优点
- 查找、插入、删除效率高。
- 树高低,磁盘访问次数少。
- 所有叶子同层,性能稳定。
- 广泛用于数据库和操作系统文件系统索引。
12.4 File Directories:文件目录
目录的作用
- 目录保存文件信息,包括属性、位置、所有者等。
- 用户通过文件名引用文件,目录负责把文件名映射到实际文件。
- 目录本身也是一种文件,但通常只能通过系统例程间接访问。
文件目录中的信息
Basic Information 基本信息:
- 文件名。
- 文件类型。
- 文件组织方式。
Address Information 地址信息:
- 所在卷 volume。
- 起始地址。
- 已用大小。
- 已分配大小。
Access Control Information 访问控制信息:
- 文件所有者。
- 授权用户信息。
- 允许的操作,如读、写、执行、网络传输。
Usage Information 使用信息:
- 创建日期。
- 创建者身份。
- 最近读取日期。
- 最近读取者。
- 最近修改日期。
- 最近修改者。
- 最近备份日期。
- 当前使用状态,如是否打开、是否锁定、是否已在内存修改但尚未写回磁盘。
目录操作
- Search:搜索目录以定位文件。
- Create file:创建文件时添加目录项。
- Delete file:删除文件时移除目录项。
- List directory:列出目录内容和属性。
- Update directory:文件属性变化时更新目录项。
目录结构
简单列表目录
- 每个文件一个目录项。
- 文件名作为关键字。
- 实现简单。
- 缺点是搜索慢、命名冲突严重、不适合多用户和大量文件。
二级目录
- 有一个主目录。
- 每个用户有自己的用户目录。
- 文件名只需在单个用户目录内唯一。
- 更容易做访问控制。
- 缺点是仍不能很好支持用户按项目、类型等组织文件。
树形目录
- 几乎所有现代系统采用。
- 主目录下有用户目录。
- 用户目录下可有子目录和文件。
- 任意目录都可包含文件或子目录。
- 支持层次化组织、权限隔离和更自然的命名。
目录内部组织
- 小目录可用顺序文件。
- 大目录若条目很多,用散列结构可减少搜索时间。
Pathname 路径名
- 从根目录到目标文件的一系列目录名加文件名组成 pathname。
- 同名文件可以存在于不同目录中,只要路径名唯一。
- 路径名解决全系统唯一命名问题。
Working Directory 工作目录
- 进程或交互用户当前所在目录。
- 文件可相对于工作目录引用。
- 登录或进程创建时,默认工作目录通常是用户主目录。
- 用户可通过切换目录改变工作目录。
12.5 File Sharing:文件共享
文件共享中的两个核心问题
- Access Rights 访问权限。
- Simultaneous Access 同时访问控制。
访问权限层次
常见权限从弱到强:
- None:
- 用户甚至不知道文件存在。
- Knowledge:
- 用户知道文件存在和所有者。
- Execution:
- 用户可加载并执行程序,但不能复制。
- Reading:
- 用户可读取文件,包括复制和执行。
- Appending:
- 用户可在文件末尾追加数据,但不能修改或删除已有内容。
- Updating:
- 用户可修改、删除、添加文件内容。
- Changing Protection:
- 用户可改变其他用户的访问权限。
- Deletion:
- 用户可删除文件。
权限通常构成层次:
- 较强权限隐含较弱权限。
- 例如 Updating 通常隐含 Knowledge、Execution、Reading、Appending。
用户分类
- Specific user:指定用户。
- User groups:用户组。
- All:所有用户,即公共文件。
同时访问
- 多个用户拥有 append 或 update 权限时,系统必须控制并发。
- 简单方法:更新时锁定整个文件。
- 更细粒度方法:只锁定被更新的记录。
- 本质上类似 readers/writers problem。
- 必须处理互斥和死锁问题。
12.6 Record Blocking:记录阻塞
记录与块
- 记录是结构化文件的逻辑访问单位。
- 块是二级存储器 I/O 的基本单位。
- 文件 I/O 必须把记录组织成块。
块大小的权衡
较大块的优点:
- 一次 I/O 可传输更多记录。
- 顺序处理时减少 I/O 次数。
- 可能提升整体传输效率。
较大块的缺点:
- 随机访问时可能读入大量无用记录。
- 需要更大的 I/O 缓冲区。
- 缓冲管理更复杂。
三种记录阻塞方式
Fixed Blocking 固定阻塞
- 使用定长记录。
- 一个块中存放整数个记录。
- 块末尾可能有未用空间。
- 未用空间称为内部碎片。
- 常用于定长记录的顺序文件。
Variable-Length Spanned Blocking 变长跨块阻塞
- 使用变长记录。
- 记录紧密打包进块中,几乎不浪费空间。
- 一个记录可以跨越两个块。
- 需要指针指向后续块。
优点:
- 存储利用率高。
- 不限制记录大小。
缺点:
- 实现复杂。
- 跨块记录读取可能需要两次 I/O。
- 更新困难。
Variable-Length Unspanned Blocking 变长非跨块阻塞
- 使用变长记录。
- 记录不能跨块。
- 若剩余空间不足以放下下一条记录,则浪费该空间。
优点:
- 比跨块方式简单。
- 单条记录不会分散到多个块。
缺点:
- 会产生空间浪费。
- 记录大小不能超过块大小。
与虚拟内存的关系
- 虚拟内存系统中,页通常是基本传输单位。
- 页较小,不适合直接作为大文件 I/O 的块。
- 一些系统会把多个页组合为一个较大的文件 I/O 块。
12.7 Secondary Storage Management:二级存储管理
两个基本任务
- 为文件分配磁盘空间。
- 跟踪哪些磁盘空间仍可分配。
文件分配需要考虑的问题
- 创建文件时是否一次分配最大空间?
- 分配单位是一个块、多个连续块,还是整个文件?
- 用什么数据结构跟踪文件已分配的部分?
Preallocation 预分配
- 创建文件时声明最大大小。
- 一次分配所需空间。
- 适合能预估文件大小的场景,如编译输出、文件传输。
优点:
- 运行时分配开销小。
- 可提高连续性。
缺点:
- 很多应用无法准确预测最大文件大小。
- 用户容易高估大小,造成空间浪费。
Dynamic Allocation 动态分配
- 文件增长时按需分配空间。
- 更灵活,减少预留浪费。
- 但可能导致文件分散,影响性能。
Portion 分配片段
- portion 是连续的一组已分配块。
- 可以小到一个块,大到整个文件。
分配片段大小的权衡
大连续片段:
- 顺序访问性能好。
- 分配表小。
- 空间重用困难。
- 可能产生外部碎片。
小固定块:
- 灵活。
- 易于重用。
- 分配表可能很大。
- 连续性差,可能影响顺序访问。
空闲空间分配策略
- First Fit:
- 选择第一个足够大的空闲连续块组。
- Best Fit:
- 选择满足要求的最小空闲块组。
- Nearest Fit:
- 选择离该文件上次分配位置最近的空闲块组,提高局部性。
三种文件分配方法
Contiguous Allocation 连续分配
特点:
- 文件创建时分配一整段连续块。
- 属于预分配。
- 文件分配表只需记录起始块和长度。
优点:
- 顺序访问性能最好。
- 随机访问也简单。
- 第 i 个块的位置为 b + i - 1。
缺点:
- 必须预先知道文件大小。
- 会产生外部碎片。
- 可能需要磁盘紧缩 compaction。
Chained Allocation 链式分配
特点:
- 通常按单个块分配。
- 每个块包含指向下一块的指针。
- 文件分配表只需记录起始块和长度。
- 可预分配,但更常见的是按需分配。
优点:
- 不需要连续空间。
- 没有外部碎片。
- 增长方便。
缺点:
- 随机访问差,必须沿链查找。
- 指针占用空间。
- 局部性差,顺序读取可能频繁移动磁头。
- 可通过周期性文件整理改善局部性。
Indexed Allocation 索引分配
特点:
- 每个文件有一个索引。
- 索引中每项指向文件的一个块或一个片段。
- 文件分配表指向该文件的索引块。
优点:
- 支持顺序访问和直接访问。
- 避免连续分配的外部碎片问题。
- 比链式分配随机访问更好。
- 是最流行的分配方式之一。
缺点:
- 需要索引块。
- 小文件也有索引开销。
- 索引过大时需要多级索引。
Free Space Management 空闲空间管理
为了分配文件块,系统必须知道哪些块空闲,因此需要 Disk Allocation Table。
Bit Table 位表
- 每个磁盘块对应 1 位。
- 0 表示空闲,1 表示已使用。
- 空间开销最小。
- 易于查找连续空闲块。
- 若磁盘很大,位表也可能很大。
- 通常希望位表驻留内存,否则搜索成本高。
- 可用辅助摘要表记录每个范围的空闲块数量和最大连续空闲块长度。
位表大小公式:
- 所需字节数 = disk size in bytes / (8 × file system block size)
Chained Free Portions 空闲片段链
- 每个空闲片段保存指针和长度。
- 只需保存链表头指针和首片段长度。
- 空间开销小。
优点:
- 适合多种分配方法。
- 不需要完整磁盘分配表。
缺点:
- 磁盘用久后会碎片化。
- 分配一个块前可能要先读该空闲块以得到下一个指针。
- 大量分配和删除碎片文件时很慢。
Indexing 索引法
- 把空闲空间当成一个文件。
- 用索引表记录每个空闲片段。
- 通常按变长片段记录更高效。
- 能有效支持各种文件分配方法。
Free Block List 空闲块列表
- 每个块编号。
- 在磁盘保留区域维护所有空闲块编号列表。
- 比位表大很多,通常存磁盘上。
- 可把列表的一小部分放入内存:
- 栈方式:分配 pop,释放 push。
- FIFO 队列方式:从队首分配,释放到队尾。
- 后台线程可对内存中的空闲块号排序,以便连续分配。
Volume 卷
- 卷是操作系统或应用可用于数据存储的一组可寻址扇区。
- 最简单情况:一个磁盘就是一个卷。
- 一个磁盘可分多个分区,每个分区是一个卷。
- 多个磁盘或多个分区也可组合成一个卷。
Reliability 可靠性
潜在问题:
- 系统为了效率把磁盘分配表和文件分配表缓存在内存中。
- 若内存表已更新但磁盘表未更新时系统崩溃,可能导致空间重复分配或文件损坏。
安全分配步骤:
- 锁定磁盘上的磁盘分配表。
- 搜索空闲空间。
- 分配空间并更新磁盘分配表到磁盘。
- 更新文件分配表到磁盘。
- 解锁磁盘分配表。
性能问题:
- 每次小分配都同步写磁盘会很慢。
- 可用批量分配减少开销。
- 崩溃后需清理已标记使用但未真正归属文件的空间。
12.8 UNIX File Management:UNIX 文件管理
UNIX 文件类型
- Regular / Ordinary 普通文件:
- 包含任意数据。
- 文件系统不规定内部结构,只看作字节流。
- Directory 目录文件:
- 包含文件名和 inode 指针。
- 目录按层次结构组织。
- 目录本质是特殊保护的普通文件。
- Special 特殊文件:
- 用文件名映射物理设备。
- Named Pipes 命名管道:
- 用于进程间通信。
- 先进先出传输数据。
- Links 硬链接:
- 已有文件的另一个名字。
- Symbolic Links 符号链接:
- 一个数据文件,内容是被链接文件的名字。
Inode
- inode 是 UNIX 管理文件的核心控制结构。
- 每个文件由一个 inode 控制。
- 多个文件名可以关联到同一个 inode。
- 文件名不在 inode 中,目录项负责把文件名映射到 inode。
inode 中通常包含:
- 文件类型和访问模式。
- 所有者和用户组。
- 创建、读取、写入、inode 更新时间。
- 文件大小。
- 数据块指针。
- 文件使用的物理块数量。
- 指向该文件的目录项数量。
- 文件标志。
- generation number,用于检测对已删除文件的旧引用。
- 块大小。
- 扩展属性。
UNIX 文件分配
- 按块动态分配。
- 不要求文件块连续。
- 使用索引分配。
- inode 中保存部分索引。
- inode 包含直接指针和间接指针。
典型结构:
- 直接指针:
- 直接指向文件数据块。
- 小文件访问快。
- 单级间接指针:
- 指向一个保存数据块地址的块。
- 二级间接指针:
- 指向保存单级间接块地址的块。
- 三级间接指针:
- 指向保存二级间接块地址的块。
优点:
- inode 固定且较小,可长期留在内存。
- 小文件访问几乎不需要间接寻址。
- 最大文件大小可非常大。
UNIX 目录
- 目录是包含文件名和 inode 编号的文件。
- 目录项 dentry 包含文件名和 i-number。
- i-number 用作 inode 表索引。
UNIX 卷结构
一个 UNIX 文件系统通常包含:
- Boot block:
- 启动操作系统所需代码。
- Superblock:
- 文件系统属性,如分区大小、inode 表大小。
- Inode table:
- 所有文件 inode 的集合。
- Data blocks:
- 存放文件数据和子目录。
12.9 Linux Virtual File System:Linux 虚拟文件系统
VFS 的目的
- Linux 支持多种真实文件系统。
- VFS 为用户进程提供统一文件系统接口。
- 各真实文件系统通过映射模块接入 VFS。
- 用户调用如 read、write、open 时,先进入 VFS,再被转换为具体文件系统操作。
VFS 工作过程
- 用户进程发出文件系统调用。
- VFS 处理文件系统无关部分。
- VFS 调用具体文件系统的映射函数。
- 具体文件系统把请求转换为设备操作。
- 设备驱动执行底层 I/O。
- 结果沿相反路径返回用户。
VFS 的四类核心对象
- Superblock object:
- 表示一个已挂载文件系统。
- Inode object:
- 表示一个具体文件。
- Dentry object:
- 表示路径中的一个目录项。
- File object:
- 表示一个进程打开的文件。
Superblock Object
保存一个文件系统的信息:
- 挂载设备。
- 文件系统基本块大小。
- dirty 标志。
- 文件系统类型。
- 只读等标志。
- 根目录指针。
- 打开文件列表。
- 访问控制信号量。
- superblock 操作函数列表。
常见操作:
- 分配 inode。
- 写 inode 到磁盘。
- 卸载时释放 superblock。
- 获取文件系统统计信息。
- 重新挂载时更新挂载选项。
Inode Object
- 每个文件对应一个 inode object。
- 保存文件名和实际数据内容之外的文件信息。
- 包含所有者、组、权限、访问时间、大小、链接数等。
- 包含 inode operations,如创建文件、查找文件名、创建目录。
Dentry Object
- 表示路径中的一个组成部分。
- 可以是目录名或文件名。
- 加速路径查找。
- 用于 dentry cache。
- 包含指向 inode、superblock、父 dentry、子 dentry 的指针。
File Object
- 表示进程已经打开的文件。
- open 系统调用时创建。
- close 系统调用时销毁。
- 包含:
- 对应 dentry。
- 所属文件系统。
- 使用计数。
- 用户 ID。
- 用户组 ID。
- 当前文件指针。
- read、write、open、release、lock 等操作函数。
VFS 缓存
- Inode cache:
- 缓存最近访问过的 inode。
- Directory cache:
- 缓存目录名到 inode 编号的映射。
- Buffer cache:
- 缓存物理块数据,减少重复磁盘读取。
12.10 Windows File System:Windows NTFS
NTFS 目标
- 面向高端工作站和服务器。
- 支持大型文件、可靠恢复、安全访问和网络应用。
NTFS 关键特性
- Recoverability 可恢复性:
- 崩溃或磁盘故障后恢复卷到一致状态。
- 文件系统修改被视为事务。
- 事务要么完成,要么回滚。
- Security 安全性:
- 使用 Windows 对象模型。
- 文件对象带有安全描述符。
- Large disks and large files:
- 高效支持大磁盘和大文件。
- Multiple data streams:
- 一个文件可有多个数据流。
- Journaling 日志:
- 记录卷上文件变化。
- Compression and encryption:
- 支持透明压缩和加密。
- Hard links and symbolic links:
- 支持硬链接、符号链接和挂载点。
NTFS 存储概念
- Sector 扇区:
- 磁盘最小物理存储单位,通常 512 字节。
- Cluster 簇:
- 一个或多个连续扇区。
- NTFS 的基本分配单位。
- Volume 卷:
- 一个逻辑分区,由一个或多个簇组成。
- 可位于单磁盘或跨多个磁盘。
Cluster 的意义
- NTFS 不直接按扇区分配,而按簇分配。
- 簇大小越大,管理项越少,适合大磁盘。
- 文件的簇不必连续,因此可产生碎片。
NTFS 卷布局
NTFS 卷主要包括:
- Partition boot sector:
- 卷布局、文件系统结构、启动信息和代码。
- Master File Table,MFT:
- 保存该卷所有文件和文件夹的信息。
- System files:
- 包括 MFT 镜像、日志文件、簇位图、属性定义表等。
- File area:
- 存放普通文件数据。
MFT 主文件表
- NTFS 的核心。
- MFT 是由 1024 字节记录组成的表。
- 每行描述一个文件或文件夹。
- MFT 自身也被当作文件。
- 小文件可完全存放在 MFT 记录中。
- 大文件内容溢出到其他簇,MFT 记录保存指针。
NTFS 文件属性
文件和目录由属性集合定义,包括:
- Standard information:
- 访问属性、时间戳、链接计数等。
- Attribute list:
- 属性列表,适用于属性无法放入单个 MFT 记录的情况。
- File name:
- 文件或目录名。
- Security descriptor:
- 所有者和访问控制信息。
- Data:
- 文件内容,可有默认未命名数据流和命名数据流。
- Index root / Index allocation:
- 用于实现文件夹。
- Volume information:
- 卷版本、卷名等。
- Bitmap:
- 表示 MFT 或文件夹中记录使用情况。
NTFS 可恢复性
关键组件:
- I/O Manager:
- 包含 NTFS 驱动,处理 open、close、read、write。
- Log File Service:
- 记录文件系统元数据修改日志。
- Cache Manager:
- 缓存文件读写,提高性能。
- Virtual Memory Manager:
- 将缓存文件映射到虚拟内存。
重要考点:
- NTFS 恢复的是文件系统元数据,不保证用户文件内容完全恢复。
- NTFS 使用日志。
- 修改文件系统的重要子操作要先写日志,再写磁盘结构。
- 崩溃后可根据日志 redo 或 undo 未完成事务。
12.11 Android File Management:Android 文件管理
Android 文件系统
- Android 使用 Linux 的文件管理能力。
- 目录结构类似 Linux,但有 Android 特有目录。
system 目录
- 包含操作系统核心部分。
- 包括系统二进制文件、系统库、配置文件和基础应用。
- 系统镜像通常只读。
data 目录
- 应用保存私有数据的主要位置。
- 包含用户数据,如联系人、短信、设置、安装的应用。
- 恢复出厂设置会清除此分区。
- 安装应用时:
- .apk 放入 /data/app。
- 应用私有库放入
/data/data/<application name>。 - 建立应用相关文件和数据库。
/data/data/<application name>是应用沙箱,其他应用不可访问。
cache 目录
- 用于操作系统临时存储。
- 保存频繁访问的数据和应用组件。
- 清除 cache 不影响用户个人数据。
- 缓存会随着使用自动重建。
mnt/sdcard 目录
- 表示 SD 卡或用户可读写存储空间。
- 用于音频、视频和用户数据。
- 在有内置和外置 SD 卡的设备上,/sdcard 通常指内置 SD 卡。
SQLite
- Android 广泛使用 SQLite。
- SQLite 是基于 SQL 的轻量级关系数据库引擎。
- 适合嵌入式和内存受限系统。
- SQLite 不是独立数据库服务器进程。
- SQLite 库直接链接进应用程序,成为应用的一部分。
12.12 Summary:本章总结
总体脉络
- 文件管理系统为用户和应用提供文件访问、目录维护和访问控制。
- 文件由记录组成,记录访问方式决定文件逻辑组织。
- 文件目录提供文件命名、定位、层次组织和访问控制基础。
- 记录与磁盘块大小通常不一致,因此需要记录阻塞策略。
- 磁盘空间管理包括文件分配和空闲空间管理。
- 现代文件系统还必须考虑并发访问、可靠性、安全性和缓存性能。
易考判断点
- 文件是相似记录的集合,不是字段的集合。
- 字段是最基本数据元素,记录是相关字段集合。
- 数据库强调数据关系显式,并服务于多个应用。
- 堆文件按到达顺序存储,不是排序存储。
- 顺序文件的关键字段必须唯一。
- 顺序文件最适合全文件批处理。
- 索引顺序文件增加索引和溢出文件。
- 一般索引文件可有多个索引,并支持变长记录。
- 直接文件使用对关键值的散列。
- 目录的访问控制信息包含所有者、访问用户和允许动作。
- working directory 是当前目录。
- 文件共享需要处理互斥和死锁。
- 固定阻塞可能产生内部碎片。
- 连续分配必须预分配,易产生外部碎片。
- 链式分配无外部碎片,但随机访问差。
- 索引分配支持顺序和直接访问。
- 空闲空间管理需要磁盘分配表。
- bit table 中每个块对应一位。
- UNIX 普通文件是字节流。
- UNIX 使用 inode 保存文件控制信息。
- Linux VFS 提供统一文件接口。
- NTFS 的最小物理单位是 sector,但基本分配单位是 cluster。
- NTFS 核心结构是 MFT。
- NTFS 日志主要恢复元数据,不保证用户数据内容。