应使用 stat -c "%b" 获取单个文件的 st_blksize(如 4096),或 stat -f -c "%s" 获取挂载点的 f_bsize,二者为内核推荐的最优 i/o 对齐大小;%o 仅返回权限八进制值,与 i/o 性能无关。

stat -c "%B" 查单个文件的推荐 I/O 块大小
文件的 st_blksize 是内核为该文件提供的最优读写对齐建议,不是设备扇区大小,也不是硬编码的 4096。它由 VFS 层根据挂载选项、文件系统类型(如 XFS 的 sunit/swidth)和实际分配策略动态决定。
用法很简单:stat -c "%B" /path/to/file。输出是字节数,常见值有 4096、8192、65536。
- 必须传入普通文件路径,不能是目录或设备节点
- 若文件刚创建且未写入,
%B可能回退为文件系统默认值(如 ext4 通常 4096) - 对稀疏文件或 mmap 场景尤其关键:按此值分配缓冲区 + 对齐偏移,才能避免内核内部额外拷贝
stat -f -c "%S" 查挂载点的文件系统级推荐块大小
这是应用程序初始化缓冲区时更通用的依据,对应 statvfs() 返回的 f_bsize,即「文件系统推荐 I/O 缓冲区大小」。它比单个文件的 st_blksize 更稳定,适合批量处理同挂载点下大量文件的场景。
命令:stat -f -c "%S" /mount/point。注意路径必须是已挂载目录(如 /home),不能是 /dev/sdb1 或普通文件。
-
%S和%s(f_frsize)在本地文件系统中通常相等,优先用%S - XFS 挂载时带
sunit=64k选项,%S很可能返回 65536;NVMe DAX 模式下可能更大 - 误用
stat -c "%o"会得到权限八进制值(如 644),和 I/O 性能完全无关
xfs_info 显示 XFS 文件系统的实时块配置
仅限 XFS 已挂载文件系统。它不显示权限或单文件属性,而是揭示底层结构参数,比如数据块大小、日志块大小、是否启用 realtime 区域等。
先确认类型:df -T /mnt/data → 看到 xfs 后再执行:xfs_info /mnt/data。
- 重点看
data = bsize=4096这一行的bsize,这才是 XFS 数据 I/O 的基本单位 -
logging.bsize通常与 data.bsize 一致,但日志总容量由logging.blocks × bsize决定 - 若
realtime.blocks > 0,说明启用了 realtime 子卷,大文件连续写入会受益于realtime.extsz对齐
别踩这些坑:块大小 ≠ 扇区大小,≠ 内存页大小,≠ 权限值
很多人混淆几个概念,导致优化失效甚至性能倒退:
-
stat -c "%o"返回的是权限(如 755),和 I/O 完全无关 -
/sys/block/*/queue/logical_block_size是块设备层参数,绕过 VFS,对普通read()/write()调用无效 -
getpagesize()返回内存页大小(通常 4096),但它不反映存储对齐要求;用它做 I/O 缓冲区可能引发非对齐访问开销 - 硬编码 4096 在 XFS su=64k、NFSv4.2、DAX 等场景下会明显低效——必须运行时获取
st_blksize或f_bsize
真正起作用的,是调用 stat() 或 statvfs() 获取值后,用 posix_memalign() 分配对齐内存,再配合无缓冲的 read()/write() 使用。stdio 的缓冲层会掩盖对齐收益。











