ls -U 和 stat 是互补的底层探针:前者按磁盘原始顺序列出目录项,后者揭示 inode 与块级元数据;结合二者可分析 Ext4 的目录哈希布局、块分配对齐及局部性优化。

要理解目录文件的物理存储结构与 block 分配原理,不能只靠表面列表——ls -U 和 stat 是互补的底层探针:前者跳过排序、保留原始磁盘读取顺序,后者直接暴露 inode 与块级元数据。两者结合,才能看到文件系统“怎么存”而非“怎么显示”。
ls -U:观察原始目录项排列顺序
普通 ls 默认按字母或时间排序,掩盖了目录项在磁盘上的真实写入次序。-U(即 unsorted)强制按目录数据块中实际存储的顺序输出,这对分析 Ext4 的目录哈希布局、碎片分布、甚至恢复误删文件时的线索定位很关键。
- 目录本质是特殊文件,其数据块里存的是
struct dirent列表:每个条目含文件名 + 对应 inode 号 -
ls -U输出顺序 ≈ 内核readdir()从目录数据块中逐项读出的顺序,不经过用户态排序 - 配合
hexdump -C $(pwd)/. | head -20可粗略验证:前几项的 inode 号常与ls -Ui显示一致
stat:提取 inode 与 block 分配核心字段
stat 不查目录项,而是直接读取目标文件/目录的 inode 结构,其中关键字段揭示物理存储逻辑:
- st_blocks:已分配的 512 字节块数(注意不是文件大小除以 512,因有对齐和稀疏空洞)
- st_blksize:文件系统 I/O 块大小(如 Ext4 常为 4096),决定最小读写粒度
- st_ino:该文件在 inode 表中的编号,唯一标识其元数据位置
- st_size 与 st_blocks × 512 的差值,可判断是否存在未写满块或稀疏区域
Block 分配原理的实操验证
用 stat 和 ls -U 联动,能直观看到 Ext4 的块分配行为:
- 新建小文件:
echo "a" > f1; stat -c "%n: size=%s, blocks=%b, blksize=%B" f1→ 通常blocks=8(即 4096 字节),哪怕内容仅 2 字节 —— 这是 4K 块对齐的体现 - 追加写入:
dd if=/dev/zero of=f1 bs=1 count=4097 seek=1 2>/dev/null,再stat→blocks变为 16,说明跨块了 - 对比
ls -Ui和ls -U:同一目录下多个文件若 inode 号连续,往往说明它们被分配在相近的块组中,反映 Ext4 的局部性优化
延伸:结合 debugfs 看真实磁盘布局
stat 和 ls -U 提供的是逻辑视图。若需穿透到物理层,可用 debugfs 查看实际块号:
-
sudo debugfs /dev/sda1进入交互模式 -
stat <inode_num></inode_num>→ 显示该 inode 所用的数据块列表(如Blocks: (0):12345 (1):12346) -
icheck 12345→ 反查哪个 inode 占用了该块 - 这些块号对应磁盘上真实的 LBA 地址,经 CHS 或 LBA 映射后,最终落于某柱面/磁头/扇区


















