1.6 我是一块硬盘

把文件名、元数据、数据块、空闲空间和持久化顺序放进同一个文件系统读写合同。

学习目标

  • 能沿文件名、元数据、数据块和设备传输追踪一次文件读写
  • 能解释文件系统如何分配空闲块、处理边界并保持数据与元数据的持久化顺序
  • 能用正常、边界和单一故障样本定位断电、空间不足、路径错误和旧内容问题

1.6 我是一块硬盘

本页依据刘欣《码农翻身》(2018 年第 1 版)及出版社公开书目信息,独立重构 1.6 我是一块硬盘。正文、代码、图示、实验和练习都是本课程重新设计的教学材料,不复制原书正文、插图、练习答案或代码。

硬盘不是“文件躺在连续位置上”的透明盒子。文件系统把名称解析为元数据和数据块,用空闲空间结构分配块,再把读写请求交给块设备;设备只负责持久化块,不能替文件系统决定名称、权限、目录一致性或断电恢复。

三个会让文件系统模型失真的陷阱

五个词组成文件读写合同

<Term def="把路径中的目录项、名称和权限逐级解析为一个文件对象身份的过程。">名称解析</Term>决定请求指向哪个对象。路径解析失败时不能继续读取旧缓存冒充成功。

<Term def="描述文件类型、大小、权限、所有者、时间、块映射和一致性状态的记录。">元数据</Term>不是文件内容的附属装饰,它决定如何解释和保护数据块。

<Term def="保存文件内容的固定大小设备区域,逻辑块到物理块的映射由文件系统维护。">数据块</Term>可能不连续,也可能需要间接映射。设备只看到块请求,不知道文件名。

<Term def="记录哪些块可分配、已分配给谁以及释放是否完成的结构和不变量。">空闲块账本</Term>保证分配不重叠、释放可重用、崩溃后能恢复。容量数字不能替代账本。

<Term def="数据、元数据、目录项和空闲结构按约定被设备稳定保存,并能在断电后恢复到可解释状态。">持久化顺序</Term>决定恢复看到的是旧版本、新版本还是拒绝状态。

五个词组成磁盘链:名称解析找到对象,元数据找到逻辑范围,数据块承载内容,空闲块账本管理空间,持久化顺序让这些记录在断电后仍然一致。

文件读写链:名称不是位置,保存不止一次写入文件系统负责对象和一致性,块设备负责稳定保存块1解析名称与目录已定位2元数据大小与权限已定位3数据块逻辑与物理已定位4空闲分配与释放已定位5持久顺序与恢复当前恢复点目录项存在不能单独证明数据和空闲账本已经稳定
专属图示:文件系统把名称、块所有权和断电恢复连接成一条证据链。

目录节点到机制证据

内部结构

内部结构包括目录项、元数据、数据块映射、空闲块结构和恢复日志。读写一个文件时,必须说明这些结构如何交接,而不是把文件系统当作一个无状态函数。

文件

文件是名称、元数据和内容块的组合对象。大小变化、权限变化和删除都会改变不同结构;“内容读到了”不能证明文件对象的所有状态都一致。

文件的存放

文件的存放可能跨越多个逻辑块和物理块。复核要区分逻辑偏移、块大小、寻址映射和设备队列,尤其要检查扩展与碎片边界。

管理空闲块

管理空闲块需要维护分配、释放、崩溃恢复和所有权不变量。空间不足不是只有“没有容量”一种失败,也可能是账本损坏、碎片或元数据无法安全更新。

文件系统

文件系统把名称、权限、元数据、数据块和空闲结构组织成可访问对象,并向块设备发出读写请求。它还要决定缓存、日志、同步和恢复策略。

文件读写合同

type FileWrite = {
  path: string;
  metadataBefore: string;
  dataBlocks: string[];
  freeBlockJournal: string[];
  persistenceOrder: string[];
  firstDeviation: string;
  recovery: string;
  decision: "commit" | "replay" | "reject";
};
 
function canCommit(write: FileWrite) {
  return (
    write.path.length > 0 &&
    write.metadataBefore.length > 0 &&
    write.dataBlocks.length > 0 &&
    write.freeBlockJournal.length > 0 &&
    write.persistenceOrder.length >= 2 &&
    write.firstDeviation.length > 0
  );
}

合同要求写入者能解释路径、元数据、数据块、空闲账本和持久化顺序。不能证明某一步稳定保存时选择 replay 或 reject,而不是用目录项存在掩盖内容和空间状态的不一致。

四步复核一次文件写入

分步1 / 4

1. 解析名称并读取元数据

冻结路径、权限、文件版本和目录状态,记录每一级名称解析、元数据和逻辑范围。路径不存在、权限不足或对象类型不符时应在这里停止。

文件读写链:名称不是位置,保存不止一次写入文件系统负责对象和一致性,块设备负责稳定保存块1解析名称与目录已定位2元数据大小与权限已定位3数据块逻辑与物理已定位4空闲分配与释放已定位5持久顺序与恢复当前恢复点目录项存在不能单独证明数据和空闲账本已经稳定
专属图示:文件系统把名称、块所有权和断电恢复连接成一条证据链。

Interactive lab

选择持久化样本,定位首个不一致

先回放

输入

断电发生在数据块与目录项更新之间,恢复状态依赖日志。

首个变化

持久化顺序先变得不确定,不能只看目录项。

裁决动作

冻结写入,按日志回放并验证旧版本。

先保存结构和顺序,再决定提交、回放或拒绝;目录和容量数字都不是完整证据。

正常、边界与单一故障证据

持久化证据矩阵:看第一处不一致正常样本看映射,边界样本看停止,故障样本看恢复观察项正常边界故障路径可解析权限拒绝悬空项数据块完整碎片扩大旧内容空间账本一致恰好耗尽重复归属恢复版本稳定先回放顺序缺失恢复必须同时检查内容、元数据和空闲块所有权
专属图示:三类样本共同检查名称、数据、空间与恢复证据。
样本只改变的变量预期判定必存证据
正常路径、元数据、数据块、空闲账本和同步完整读取与恢复结果可解释映射、顺序、内容、账本
边界空间、文件大小、权限或断电时点越过阈值停止或恢复到已知版本,不假装成功阈值、旧状态、恢复决策
单一故障一个目录项、数据块、空闲记录或设备传输失效首个不一致暴露并修复或拒绝首差、所有者、回放日志

最小磁盘证据包与反例

证据包包含路径和目录快照、文件元数据、逻辑到物理块映射、空闲块账本、设备请求、缓存和同步点、断电时点、恢复结果、版本和独立复核记录。最终读到内容或目录项存在,只能辅助定位,不能单独证明持久化一致。

反例可以是文件名存在但数据块未写完,也可以是两个文件在恢复后共享了不应共享的块。发现反例后,保留断电前后结构,修复日志或更新顺序,重建空闲账本并重放;不要删除旧块记录来制造干净结果。

术语表

名词解释

本章出现的专业名词,用大白话再讲一遍。

名称解析

把路径中的目录项、名称和权限逐级解析为文件对象身份的过程。

元数据

描述文件类型、大小、权限、所有者、时间、块映射和一致性状态的记录。

数据块

保存文件内容的固定大小设备区域,逻辑块到物理块的映射由文件系统维护。

空闲块账本

记录哪些块可分配、已分配给谁以及释放是否完成的结构和不变量。

持久化顺序

数据、元数据、目录项和空闲结构按约定被设备稳定保存的顺序。

练习

练习

问题 1: 断电后目录里有新文件名,但读取内容得到旧数据。你先比较哪些证据?

问题 2: 磁盘容量还有余量,但创建大文件失败。如何区分容量、碎片和空闲账本问题?

问题 3: 两个文件恢复后内容互相污染,你会如何回退?

资料与写作方式声明

本章以码农翻身权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

本页小结

1.6 我是一块硬盘的关键不是把硬盘想成连续字节,而是能沿名称解析、元数据、数据块、空闲块和持久化顺序追踪一次读写。面对断电、空间边界和块冲突,保留首个不一致、恢复路径和所有权证据,才能判断是重放、修复还是拒绝。

讨论

评论区加载中…