如何理解 stat 命令显示的 Blocks 和 IO Block
Posted Li-Yongjun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解 stat 命令显示的 Blocks 和 IO Block相关的知识,希望对你有一定的参考价值。
场景描述
待测文件:README
实际大小 8755 字节,约等于 8.6K
$ ls -l README
-rw-r--r-- 1 liyongjun liyongjun 8755 12月 5 2018 README
$ ls -lh README
-rw-r--r-- 1 liyongjun liyongjun 8.6K 12月 5 2018 README
占用空间 12K
$ du -h README
12K README
stat 显示
$ stat README
File: README
Size: 8755 Blocks: 24 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1726296 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/liyongjun) Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:50.000000000
Modify: 2018-12-05 22:44:34.000000000
Change: 2020-12-18 14:08:37.000000000
疑惑
stat 命令显示的 Blocks 和 IO Block 是什么意思?因为很显然:
Size
不等于 Blocks * IO Block
占用空间
也不等于 Blocks * IO Block
明确一:IO Block
$stat LICENSE
File: LICENSE
Size: 18348 Blocks: 40 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1713584 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/liyongjun) Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:50.000000000
Modify: 2018-12-05 22:44:34.000000000
Change: 2020-12-18 14:08:37.000000000
$ stat Makefile
File: Makefile
Size: 43176 Blocks: 88 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1724286 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/liyongjun) Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:51.000000000
Modify: 2020-06-27 03:22:49.000000000
Change: 2020-12-18 14:08:37.000000000
发现对于任意文件,IO Block 恒为 4096,可以推断出这是个固定值,含义为:文件系统的最小寻址单元。
扇区为 512 字节,IO Block 为 4096,说明当前系统将 8 个扇区做为一个块。
对于文件系统而言,它能读写的最小粒度为 1 个 IO Block,此处为 4K。
令人疑惑的 Blocks
唯一的疑惑就是 Blocks 了。
网上搜索到的答案都是:表示块数、占用空间 = Blocks * IO Block。很显然这些都是错误答案,至少不适用于我当前使用的系统(应该只有 IO Block 为 512 字节的系统,才适用于:占用空间 = Blocks * IO Block)。总之,互连网上充斥着很多未经验证的错误答案,甚至曝光量比正确答案都多,这一现象真让人痛心!
既然没人给出正解,那只能靠自己了。万法归一,查看源码。
阅读 stat.c,发现 Blocks 和 IO Block 分别对应于 stat 结构中的 st_blocks 和 st_blksize
// 作了部分删减
struct stat
__dev_t st_dev; /* Device. */
unsigned short int __pad1;
__ino_t __st_ino; /* 32bit file serial number. */
__mode_t st_mode; /* File mode. */
__nlink_t st_nlink; /* Link count. */
__uid_t st_uid; /* User ID of the file's owner. */
__gid_t st_gid; /* Group ID of the file's group.*/
__dev_t st_rdev; /* Device number, if device. */
__off_t st_size; /* Size of file, in bytes. */
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
__ino64_t st_ino; /* File serial number. */
;
st_blocks
Number 512-byte blocks allocated. 分配的块数,以 512 字节为单位st_blksize
Optimal block size for I/O. 最优的 IO 块大小,可以理解为 best I/O block size
所以,重点,Blocks 指的是以 512 字节为单位的块的数量,或者理解为扇区数,因为一个扇区就是 512 字节。
再回首
再回头看 stat 展示的信息
$ stat README
File: README
Size: 8755 Blocks: 24 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1726296 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/liyongjun) Gid: ( 1000/liyongjun)
Access: 2022-04-06 09:33:50.000000000
Modify: 2018-12-05 22:44:34.000000000
Change: 2020-12-18 14:08:37.000000000
Blocks 为 24,那大小就是 512 * 24 = 12K,和 du 展示的占用空间大小一致。即 占用空间 = Blocks * 512。
以上是关于如何理解 stat 命令显示的 Blocks 和 IO Block的主要内容,如果未能解决你的问题,请参考以下文章