Linux设备与存储精读 · L02-02 | inode 与目录项:名字、元数据、数据分别在哪 模块L02 文件、路径与元数据篇号L02-02 / 38预计阅读40 分钟主线Linux 设备与存储文章目录本篇目标30 秒速览正文1. 为什么不能把「文件」想成一团东西2. inode元数据住在这里3. 目录项名字住在这里4. 目录本身也是特殊文件5. 数据块内容住在这里6. 和块设备、镜像、挂载怎么接起来7. 用 inode 号做两个实验直觉7.1 同 FS两个名字一个 inode7.2 不同 FSinode 号可以「撞号」8. 路径查找在干什么串起来9. 超级块整盘说明书够用即可Android 对照检查清单练习判断题对 / 错读输出题操作题本篇边界下一篇预告本篇目标把「一个文件」拆成三块名字目录项、元数据inode、数据数据块。弄清目录本身也是带 inode 的特殊文件其内容是「文件名 → inode 号」。并能把这套结构和块设备上的文件系统镜像、挂载后的路径访问对上号为硬链接L02-03与权限L03打地基。30 秒速览路径上的名字 ≠ inode ≠ 文件内容三者分开存放。目录项名字 → inode 号inode类型、权限、大小、数据在哪数据块普通文件的字节内容。目录也是文件自己有 inode目录的「内容」就是一条条目录项。同一 inode 可以有多个名字硬链接雏形删一个名字不等于立刻删光数据。FS 镜像刷到分区块设备后上述结构已以二进制形式躺在设备上挂载后由文件系统驱动解析路径才能用。正文1. 为什么不能把「文件」想成一团东西口语里说「有个文件/data/local/tmp/a.txt」心里容易当成一整块。在文件系统里至少要拆开看部分回答什么问题存在哪里概念名字叫什么、挂在哪个目录下目录项dentry元数据谁的、什么权限、多大、类型inode数据文件里真正的字节数据块data blocks目录项 a.txt ──→ inode #1442 │ ├─ 类型普通文件 ├─ 权限、属主、大小、时间戳 … └─ 指向哪些数据块 │ ▼ 数据块Hello\n …后面凡是「改名」「硬链接」「权限」「删除后空间是否释放」都建立在这张分离图上。2. inode元数据住在这里inodeindex node是文件系统里描述一个对象的核心结构。用户通常不直接「打开 inode 号」而是通过路径找到它但可用探针看见编号# Android / 服务器均可试ls-li/data/local/tmp2/dev/null|head# 服务器ls-li/tmp|headstat-c%i %n/tmp2/dev/nullls -li最左侧一列一般是inode 号同一文件系统内标识一个对象。inode 里典型包含不同 FS 细节不同心智模型够用即可类别例子类型普通文件 / 目录 / 符号链接 / 设备节点 …权限与属主mode、uid、gidL03大小与时间size、atime/mtime/ctime链接计数有多少个名字指向本 inodeL02-03数据位置指向哪些数据块或符号链接目标等inode 一般不存文件名。文件名在目录项里所以同一个 inode 可以对应多个名字。3. 目录项名字住在这里目录项把「人类可读的名字」接到「inode 号」目录 /data/local/tmp 的内容概念上≈ . → 该目录自己的 inode .. → 父目录的 inode a.txt → 1442 b.bin → 1443因此改名同文件系统内多半是改目录项里的名字inode 与数据可以不动。移动到另一目录同 FS从旧目录删一项、在新目录加一项仍可指向同一 inode。跨文件系统「移动」往往变成复制 删除因为 inode 号空间不跨 FS 共用。4. 目录本身也是特殊文件L02-01 里目录行首是d。再精确一步目录自己有 inode类型为目录。目录的「文件内容」在概念上就是目录项列表名字 → inode。现代 FSext4、f2fs 等磁盘上可能用树/哈希等结构存这些项但对外仍是「查名字得到 inode」。inode #100类型目录名字通过父目录项关联为 tmp └─ 数据目录内容 a.txt → #1442 b.bin → #1443所以「打开一个目录 / 列出目录」本质上是找到该目录 inode → 读它的目录项 → 再按需读每个子对象的 inode。5. 数据块内容住在这里对普通文件inode 记录「内容在哪些数据块」读文件就是按这些指针去块设备上取字节。对目录数据区或等价结构里是目录项不是「文本小说」。对符号链接目标路径可能存在 inode 内或数据块中短链接常优化进 inodeL02-03 再看操作。对块/字符设备节点inode 描述「这是设备节点 major/minor」没有「文件正文数据块」这种普通文件含义——真正的数据在块设备介质上由驱动按块访问L05。6. 和块设备、镜像、挂载怎么接起来把 L01 / L02-01 与本篇拼成一条制作阶段目录树 权限等 ↓ e2fsdroid / mkfs填充 / 构建系统等 FS 镜像文件普通文件 - 内含超级块、inode 表、目录项、数据块……二进制 ↓ 刷写到 eMMC 某分区 分区块设备b上已是同一套二进制布局 ↓ mount文件系统驱动认超级块并接管 挂载点目录d下出现可路径访问的文件树要点很多系统/用户分区镜像在刷入前就已经带好文件系统结构刷写 ≈ 把这段二进制放到对应地址范围。刷完后内核先暴露块设备未挂载时上面已是 FS 二进制但还只是原始数据。挂载时对应文件系统驱动解析超级块 / inode / 目录项经 VFS 提供路径访问。元数据占用空间所以常见blockdev分区大小 df显示的文件系统空间L11 再量化。不是所有分区镜像都是「可挂载的 FS 镜像」如部分 boot/raw本篇默认讨论 ext4/f2fs/erofs 这类。7. 用 inode 号做两个实验直觉7.1 同 FS两个名字一个 inode服务器示例勿在系统盘上乱做家目录或/tmpcd/tmpechohelloinode-demo.txtlninode-demo.txt inode-demo-hard.txt# 硬链接机制详见 L02-03ls-liinode-demo.txt inode-demo-hard.txt示意两行inode 号相同链接计数为 2。说明两个目录项指向同一 inode共享元数据与数据块。7.2 不同 FSinode 号可以「撞号」/data上的 inode100与/system上的 inode100不是同一个对象。inode 号只在同一个文件系统同一次挂载的那棵 FS内有唯一含义。adb shellls-li/data/local/tmp2/dev/null|headadb shellls-li/system/bin2/dev/null|head# 两边都可能出现相同数字并不表示同一文件8. 路径查找在干什么串起来访问/data/local/tmp/a.txt时概念步骤是从挂载点 /data 对应的 FS 根 inode 出发 → 在「根目录」目录项中查 local → 得到目录 inode → 在该目录项中查 tmp → 得到目录 inode → 在该目录项中查 a.txt → 得到文件 inode → 按 inode 读数据块任一层目录缺少「遍历权限」x查找会在中途失败L03。中间若碰到符号链接还要先解析目标路径L02-03。9. 超级块整盘说明书够用即可**超级块superblock**记录文件系统级信息类型、块大小、容量、inode 总量与空闲等。挂载时驱动先认超级块含魔数才能知道如何解读后面的 inode 与数据区。本篇只需记住超级块是「这盘 FS 的总头」不是「每个文件名对应一个固定字节偏移」的对照表。Android 对照现象用本篇语言解释ls -li看到编号该 FS 内的 inode 号by-name 是符号链接另有 inode目标字符串指向块设备路径刷入的 userdata/system 类镜像块设备上已含超级块/inode/目录项/数据mount之后/data下能lsFS 驱动已把二进制解析成路径可访问的树自定义分区挂上后权限「不对」看的是该 FS 根 inode / 目录 inode 的元数据L03、L07检查清单能分开说名字、inode、数据块各存什么能说明目录也有 inode目录内容是名字→inode知道 inode 号只在同一文件系统内比较才有意义能把「FS 镜像 → 块设备二进制 → 挂载 → 路径」说成一条链明白改名/硬链接为何可以不动文件内容练习判断题对 / 错文件名保存在 inode 里所以改名一定要改 inode。目录没有 inode只有目录项。同一块磁盘上两个不同挂载的文件系统可以各自存在 inode 号为 2 的对象。分区块设备在未挂载时若已刷入 FS 镜像盘上可以已经有 inode/目录项的二进制布局。参考答案错。名字在目录项同 FS 改名通常改目录项。错。目录自己也有 inode。对。编号空间按文件系统挂载实例区分。对。挂载是解析与接入目录树不是「这时才凭空生成全部元数据」首次 mkfs 的情况除外。读输出题$ ls -li 1442 -rw-r--r-- 2 user user 6 ... inode-demo.txt 1442 -rw-r--r-- 2 user user 6 ... inode-demo-hard.txt这两个名字对应几个 inode第三列的2通常表示什么若删除inode-demo.txt数据是否一定立刻消失参考答案一个都是 1442。硬链接计数为 2仍有两个名字指向该 inode。不一定。通常链接计数减为 1另一个名字仍在数据仍在计数到 0 且无进程占用时才回收细节 L02-03。操作题远程服务器cd/tmprm-finode-demo.txt inode-demo-hard.txtechohelloinode-demo.txtlninode-demo.txt inode-demo-hard.txtls-liinode-demo.txt inode-demo-hard.txtrminode-demo.txtls-liinode-demo-hard.txtcatinode-demo-hard.txtrminode-demo-hard.txt观察删一个名字后另一个名字的 inode 号是否不变、内容是否仍在。Android只读观察即可adb shellls-li/data/local/tmp2/dev/null|headadb shellls-lid/data /data/local确认目录行也能看到 inode 号。本篇边界不讲硬链接 / 符号链接命令全选项L02-03不讲ls/stat常用选项必会总表L02-04不讲权限位语义与 umaskL03不讲 ext4/f2fs 磁盘布局的实现级细节L06 够用深度不讲 fstab/fs_mgr 谁发起挂载后续专栏下一篇预告L02-03《硬链接与符号链接ln、readlink、realpath》— 在 inode 图上区分两种「多名字」并收口常用选项。