如何理解 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 125  2018 README
$ ls -lh README 
-rw-r--r-- 1 liyongjun liyongjun 8.6K 125  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的主要内容,如果未能解决你的问题,请参考以下文章

stat命令的实现-mysate

stat命令如何计算文件的块?

linux stat 简单介绍

Linux命令之显示文件状态信息stat

命令分析_stat

stat