df -h 显示的是文件系统已用block空间占比,非预分配空间;预分配(如fallocate)不消耗真实block,故df不统计,但写入时可能因无可用block报“no space left on device”。

df -h 显示的是预分配空间利用率吗
不是。df -h 显示的是文件系统级的**已用 block 空间占比**,它反映的是实际写入数据占用的磁盘块(block)比例,和“预分配”无关。Linux 文件系统(如 ext4、xfs)默认不主动预分配空间;只有当应用显式调用 fallocate()、posix_fallocate() 或使用 dd if=/dev/zero ... conv=notrunc 等方式时,才可能创建稀疏文件或预留空间——但这种“预分配”不会被 df 当作“已用”,因为它不消耗真实 block。
为什么 df 显示 10% 却报 “No space left on device”
常见于两种预分配相关误判场景:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 应用(如数据库、日志轮转工具)调用
fallocate(2)预留大文件,但该操作在 ext4 上默认是“lazy”模式:仅更新 inode 中的 size 字段,不立即分配 block —— 所以df不计为已用;但当后续真正写入时,若此时磁盘 block 已满,就会失败 - 文件系统启用了
big_writes或使用了 FUSE 挂载(如某些容器卷),其预分配行为绕过内核标准 block 分配路径,df无法感知 - 更隐蔽的情况:XFS 的
allocsize挂载选项影响延迟分配粒度,配合大量小写入时,df显示余量充足,但实际因 extent 碎片无法满足单次 allocation 请求而失败
怎么查出谁在预分配却没真写
没有通用命令能直接列出“已预分配但未落盘”的文件,但可通过组合排查定位可疑对象:
- 找大尺寸但实际 block 占用极小的文件:
find /path -type f -size +1G -exec du -sh {} \; | awk '$1 —— 这类很可能是 <code>fallocate创建的稀疏文件 - 检查进程是否正在调用预分配系统调用:
sudo strace -p <pid> -e trace=fallocate,fcntl -s</pid>(需提前怀疑目标进程) - 对 XFS 文件系统,用
xfs_info /mountpoint看allocsize值,并结合xfs_db -r -c "freesp -h" /dev/sdX1查看空闲 extent 碎片情况 - 观察
/proc/mounts中对应挂载项是否有noatime,nobarrier,allocsize=等非常规选项
预分配空间问题最容易被忽略的点
真正的瓶颈往往不在总量,而在分配连续性与时机。比如一个 2GB 的 fallocate 文件,在磁盘剩余 3GB 但碎片化严重时仍可能失败;又比如容器中 overlay2 下层镜像层被只读挂载,上层写时触发 copy-on-write,预分配请求落在受限的 upperdir,而 df 查的是 host 根分区 —— 两者根本不在同一视图里。










