uni-atlas (zh)

inode 到底是什么

理解 Unix 文件系统的关键,是把「文件」拆成三段独立的东西:文件名inode数据块 (data blocks)。三者之间是三段映射,而不是一个整体。

三段映射

  1. 目录条目 (directory entry) — 把人可读的文件名映射到一个 inode 编号。目录本身就是一种特殊文件,里头是 (name, inode_number) 这种条目的列表。
  2. inode — 一段记录文件「元信息」的结构:所有者、权限、修改时间、大小、数据块在磁盘上的位置 — 唯独不包含文件名
  3. 数据块 — 文件的实际字节内容,可能散落在磁盘的多个位置;inode 里有指针(或多级索引)指向这些块。

把这三段看清,很多看起来「奇怪」的 Unix 行为就解释通了。

为什么硬链接能成立

ln a b 创建一个 硬链接:把目录条目 b 也指向 a 当前指向的同一个 inode。inode 不变,文件名增加一个ab 在文件系统里是完全平等的两个名字,对应同一份内容。ls -i 能验证它们 inode 编号一致。

rm a 只是删除了一个目录条目;只要还有别的名字指向这个 inode(b 还在),数据就还存活。inode 内部有 引用计数 (link count),只有当 link count 归零、且没有进程仍在用这个文件,内核才会真正回收 inode 与数据块。

这也解释了一个经典陷阱:程序还在打开某个日志文件、你 rm 了那个名字,磁盘空间不会立刻释放 — 因为进程的 fd 仍然在「使用」这个 inode。

与其他概念的边界

  • inode 不存文件名,所以 inode 自己不知道自己叫什么名字。
  • inode 不在用户态可见,你看不到 inode 是什么数据结构;但 stat 系统调用能查到 inode 编号、链接数、大小、时间戳等暴露给用户的字段。
  • 软链接 (ln -s) 跟 inode 无关:软链接是一个特殊文件,内容是一段路径字符串。它指向「名字」,不是「inode」。所以原文件被 rm 之后,软链接会变成悬空指针。

M3 阶段的笔记是骨架(本节就是 #46 的 scaffold note);M5 阶段会扩展代码示例(stat 输出解读、ln / ln -s 实验、引用计数演示)与底层结构图。

用 stat 看 inode

下面这段命令用来查看一个文件的 inode 编号与基本元信息:

ls -i myfile
stat myfile

引用计数公式简记为 n=link_countn = \text{link\_count}。当数据块真正被回收的判定条件:

n=0andopen_count=0n = 0 \quad \text{and} \quad \text{open\_count} = 0

关键区别:软链接和硬链接的关键区别,在于 inode 是否被两个名字共享。硬链接共享 inode、软链接不共享。

输出字段简述

stat 输出里最常被引用的 4 个字段是 InodeLinksSizeModify。理解这 4 个之后,大多数文件系统行为都能解释清楚。