一尘不染

stat命令如何计算文件块?

linux

我想知道stat命令如何计算文件的块。我读了
这篇文章,它说:

值st_blocks以512字节块为单位给出文件的大小。(例如,当文件有孔时,它可能小于st_size /
512。)值st_blksize给出了“首选”的块大小,以实现有效的文件系统I / O。(以较小的块写入文件可能会导致读取-修改-重写效率低下。)

但我无法在测试中验证它。

我的文件系统是ext3。

dumpe2fs -h / dev / sda3显示:

...
First block: 0
Block size: 4096
Fragment size: 4096
...

然后我跑

kent@KentT60:~/Desktop$ stat Email
File: `Email'
Size: 965 Blocks: 8 IO Block: 4096 regular file
Device: 80ah/2058d Inode: 746095 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ kent) Gid: ( 1000/ kent)
Access: 2009-08-11 21:36:36.000000000 +0200
Modify: 2009-08-11 21:36:35.000000000 +0200
Change: 2009-08-11 21:36:35.000000000 +0200

如果这里的块表示:多少个512字节块,则该数目应为2而不是8。我认为,来自文件系统的块大小(io块)为4k。如果fs将获取文件Email,它将从磁盘(8 x
512bytes块)中提取最少4k,这意味着965/512 + 6 =8。我不确定猜测是否正确。

另一个测试:

kent@KentT60:~/Desktop$ stat wxPython-demo-2.8.10.1.tar.bz2
File: `wxPython-demo-2.8.10.1.tar.bz2'
Size: 3605257 Blocks: 7056 IO Block: 4096 regular file
Device: 80ah/2058d Inode: 746210 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ kent) Gid: ( 1000/ kent)
Access: 2009-08-12 21:45:45.000000000 +0200
Modify: 2009-08-12 21:43:46.000000000 +0200
Change: 2009-08-12 21:43:46.000000000 +0200


3605257/512=7041.xx = 7042

按照我上面的猜测,这将是7042 + 6 =7048。但是统计结果显示为7056。

另一个来自Internet的示例http://www.computerhope.com/unix/stat.htm。我将示例复制到页面底部:

File: `index.htm'
Size: 17137 Blocks: 40 IO Block: 8192 regular file
Device: 8h/8d Inode: 23161443 Links: 1
Access: (0644/-rw-r--r--) Uid: (17433/comphope) Gid: ( 32/ www)
Access: 2007-04-03 09:20:18.000000000 -0600
Modify: 2007-04-01 23:13:05.000000000 -0600
Change: 2007-04-02 16:36:21.000000000 -0600

在此示例中,FS块大小为8k。我想块数应该是16xN,但是是40。迷路了…

任何人都可以解释,该统计信息如何计算出块数?

谢谢!


阅读 753

收藏
2020-06-07

共1个答案

一尘不染

stat命令行工具使用stat/ fstat等功能,这些功能在返回数据stat的结构。结构的st_blocks成员stat返回:

磁盘上实际分配的大小为512字节的物理块的总数。没有为块特殊文件或字符特殊文件定义此字段。

因此,对于您的“电子邮件”示例,大小为965,块计数为8,这表示磁盘上物理分配了8 * 512 =
4096字节。之所以不是2,是因为磁盘上的文件系统没有以512为单位分配空间,而是显然以4096为单位分配空间。(分配的单位可能会根据文件大小和文件系统的复杂程度而有所不同。例如ZFS支持不同分配单位。)

同样,对于wxPython示例,它指示在磁盘上物理分配了7056 * 512字节或3612672字节。你明白了。

IO块大小是“有关I /
O操作的’最佳’单位大小的提示”-通常是物理磁盘上的分配单位。请勿在IO块和stat用于指示物理大小的块之间混淆;物理大小的块始终为512字节。

根据评论更新:

就像我说的,st_blocks操作系统是如何指示磁盘上的文件使用了多少空间。磁盘上实际分配的单位是文件系统的选择。例如,由于ZFS分配块的方式不同,
即使在同一个文件中
,ZFS也可以具有可变大小的分配块:文件开始时具有较小的块大小,并且块大小不断增加,直到达到特定点为止。如果该文件以后被截断,它可能会保留旧的块大小。因此,根据文件的历史记录,它可以具有多个可能的块大小。因此,给定文件大小后,为什么它具有特定的物理大小并不总是很明显。

具体示例:在具有ZFS文件系统的Solaris框上,我可以创建一个非常短的文件:

$ echo foo > test
$ stat test
  Size: 4               Blocks: 2          IO Block: 512    regular file
(irrelevant details omitted)

好的,小文件,2块,该文件的物理磁盘使用率为1024。

$ dd if=/dev/zero of=test2 bs=8192 count=4
$ stat test2
  Size: 32768           Blocks: 65         IO Block: 32768  regular file

好的,现在我们看到物理磁盘使用率为32.5K,IO块大小为32K。然后,我将其复制到test3test3在编辑器中将该文件截断:

$ cp test2 test3
$ joe -hex test3
$ stat test3
  Size: 4               Blocks: 65         IO Block: 32768  regular file

好了,这是一个其中有4个字节的文件-
就像test-但由于ZFS文件系统分配空间的方式,它实际上在磁盘上使用32.5K。块大小随文件变大而增加,但当文件变小时不减小。(是的,这可能会导致大量的空间浪费,具体取决于您在ZFS上执行的文件类型和文件操作,这就是为什么它允许您基于每个文件系统设置最大块大小并动态更改它的原因。)

希望您现在应该意识到,文件大小和物理磁盘使用率之间不一定存在简单的关系。即使在上面,也不清楚为什么需要32.5K字节来存储大小为32K的文件-
看来ZFS通常需要额外的512字节来自己存储文件。也许它将存储用于校验和,参考计数,事务状态-
文件系统簿记。通过在指示的物理文件大小中包含这些额外内容,似乎ZFS试图不误导用户文件的物理成本。这并不意味着在不了解有关底层文件系统实现的详细信息的情况下对计算进行反向工程很简单。

2020-06-07