入门 05-文件系统与存储 预计 20 分钟 kp-021

文件、目录与 inode:持久化的核心抽象

文件是"未解释的字节序列"这一极简抽象;文件的真实身份是 inode(索引节点),目录只是"名字到 inode 号"的映射表,硬链接与软链接正是这一模型的两个自然推论。

学习状态:

一句话定义

文件是"未解释的字节序列"这一极简抽象;文件的真实身份是 inode(索引节点),目录只是"名字到 inode 号"的映射表,硬链接与软链接正是这一模型的两个自然推论。

为什么重要

"一切皆文件"是 UNIX 设计哲学的基石——设备、管道、套接字都以文件接口呈现(呼应 kp-026 的 VFS)。而 inode 模型则解释了大量日常现象:为什么删除大文件空间没释放(fd 未关)、为什么 inode 会耗尽但磁盘明明有空间、为什么 mv 同分区文件瞬间完成。

前置知识

kp-003(文件操作走系统调用);kp-018(文件页驻留内存的概念)。

核心概念

  • inode:文件的元数据实体:权限、属主、大小、时间戳、链接计数、数据块指针;不含文件名。
  • 目录项(dentry):目录文件中的一条"文件名 → inode 号"记录;目录本身也是文件。
  • 硬链接:同一 inode 的多个名字,ln 创建,删除任一名字只是链接计数减一。
  • 软链接(符号链接):独立的新文件,内容是另一个路径字符串,可跨文件系统、可指向不存在的目标。
  • 文件描述符(fd):进程打开文件后得到的句柄,指向内核打开文件表(含偏移量)。
  • 路径解析:从根 dentry 出发逐级查目录,内核用 dentry cache 加速。

原理与机制

一次 open("/home/a.txt") 的内核路径:

"/"          -> 根目录 inode
"home"       -> 读根目录数据块, 找到 home 的 inode 号
"a.txt"      -> 读 home 目录数据块, 找到 a.txt 的 inode 号
             -> 读 inode, 权限校验, 创建打开文件表项, 返回 fd

inode 的数据块指针策略:小文件直接指针;更大用一级/二级/三级间接块(ext2 模型),现代 ext4 改用 extent(起始块+长度连续区间),长文件开销从 O(指针数) 降为 O(extent 数)。删除文件 = 目录项移除 + 链接计数减一;计数归零且无进程持有 fd 时,inode 与数据块才真正回收——这就是"文件被删,日志进程还在写,空间不释放"的机制解释。

图示

目录文件(名字->inode号)        inode 表                 数据块
[ a.txt -> #1024 ] --------> inode #1024 (nlink=2) --> +--------+
[ b.txt -> #1024 ] --------> (同一inode: b.txt 是硬链接) | 文件内容 |
[ s.txt -> #4096 ] --> inode #4096: 内容是 "/home/a.txt" (软链接)

直观类比

inode 像人的身份证(唯一、记录全部档案),文件名像常用称呼——可以有好几个称呼(硬链接)指向同一张身份证;软链接像一张写着"他住在哪"的便条,人搬走了便条就失效。目录则是一份通讯录:只有"称呼→身份证号"的映射,别无其他。

实例或案例

stat a.txt              # inode 号、链接数、时间戳全景
ls -i                   # 列目录项的 inode 号
ln a.txt hard && rm a.txt && cat hard   # 硬链接: 删原名数据仍在(nlink 未到 0)
ln -s /nonexist broken && ls -l broken   # 悬空软链接
df -i                   # inode 使用率: 小文件海可耗尽 inode 而 df 显示有空间

经典排查:lsof | grep deleted 找出"已删除但仍被进程持有"的大文件,重启或重启该进程后空间回收。

常见误区

  • 认为文件名属于文件:名字只存在于目录数据中,重命名只是改一条目录项。
  • 认为跨文件系统可以硬链接:inode 号只在单个文件系统内唯一,跨系统只能用软链接。
  • 认为 fd 就是从 0 开始的连续小数字所以随便记:0/1/2 是约定(标准输入/输出/错误),其余由内核分配,并发下要小心复用竞态。

与其他知识点的关系

目录查找的缓存(dentry cache)由 kp-015 的 RCU 保护;文件页的驻留与回收连接 kp-027 页缓存;磁盘上 inode 与数据块的具体排布是 kp-023 的主题。

延伸阅读

《UNIX 操作系统设计》第 4 章;《操作系统导论》文件与目录章节。

自测题

  1. 删除文件时内核做了什么、何时真正释放空间?

答:移除目录项并把 inode 链接计数减一;计数归零且无进程打开该文件时,inode 与数据块标记为空闲,空间才释放。

  1. 硬链接与软链接的本质区别?

答:硬链接是同一 inode 的另一个名字,与原文件完全平等;软链接是存着路径字符串的独立文件,解析时重定向,可跨文件系统且可悬空。

  1. 为什么 mv 同一分区是瞬时操作?

答:同分区内 mv 只改目录项(名字→inode 映射),不移动任何数据块;跨分区则退化为复制加删除。

标签:#文件 #inode #硬链接 #目录项 #dentry