如果我的目录中有以下内容:
empty_dir
: 空目录。empty_file
: 空的文件。one_char
:由一个字符组成的文件。several_blocks
:由多个块组成的文件(但不是“太大”或“稀疏”)。
然后,ls
将显示以下†:
$ ls -Gghs
total 152K
8,0K drwxr-xr-x 2 4,0K dec 21 23:34 empty_dir
4,0K -rw-r--r-- 1 0 dec 21 23:21 empty_file
8,0K -rw-r--r-- 1 1 dec 21 23:22 one_char
132K -rw-r--r-- 1 127K dec 22 00:14 several_blocks
其次,stat
显示以下内容:
$ stat empty_dir/
File: empty_dir/
Size: 4096 Blocks: 16 IO Block: 4096 directory
...
$ stat empty_file
File: empty_file
Size: 0 Blocks: 8 IO Block: 4096 regular empty file
...
$ stat one_char
File: one_char
Size: 1 Blocks: 16 IO Block: 4096 regular file
...
$ stat several_blocks
File: several_blocks
Size: 129760 Blocks: 264 IO Block: 4096 regular file
...
第三,du
显示以下内容:
$ du -h empty_dir/
8,0K empty_dir/
$ du -h empty_file
4,0K empty_file
$ du -h one_char
8,0K one_char
$ du -h several_blocks
132K several_blocks
最后:
$ tune2fs /dev/nvme0n1p2 -l
...
Block size: 4096
...
Inode size: 256
...
报告的块大小stat
为 512 B,这意味着stat
、ls
、之间的输出du
是一致的:
empty_dir
:16 * 512 / 1024 = 4096 + 4096 = 8 KiB。empty_file
:8 * 512 / 1024 = 0 + 4096 = 4 KiB。one_char
:16 * 512 / 1024 = 4096 + 4096 = 8 KiB。several_blocks
:264 * 512 / 1024 = 129760 + 5408 = 129760 + 1312 + 4096 = 131072 + 4096 = 32 * 4096 + 4096 = 132 KiB。
问题
- 为什么分配的大小是
empty_dir
两个one_char
块(大小为 4096 B)而不是一个? - 为什么一个块的分配大小
empty_file
不是零? - 为什么分配的大小
several_blocks
(以及一般较大的文件)比实际大小大一个以上块?明显的大小 ((264 * 512) - 129760 = 5408 > 4096)?
我怀疑附加块是包含 的块inode
,就像这样提问者询问(但没有得到答复)。同样,这位提问者也有观察到的双倍大小,但问题中的表述不正确,并收到问题其他部分的答案。然而,这回答对于另一个问题,建议不应有额外的块(这是我的直觉)。
- 我们的系统配置是否不正确?
- 假设包含 的块
inode
被计数:当du
在多个文件上使用时,它是否会补偿对inode
块进行多次计数,多个是否应该inodes
在同一个块中(因为一个块可以包含 16 个inodes
(4096 / 256 = 16))?
附录
@WumpusQ.Wumbley 推测可能是扩展属性事实证明是这样的!
getfattr
返回user.com.dropbox.attributes
。事实证明,测试目录是一个目录深处的子目录,该目录以符号方式链接到我的目录中Dropbox文件夹。请参阅下面已接受的答案。
†它在 GNU/Linux 上使用 GNU Core Utilities 8.30,在 NVME SSD 上的 ext4 上使用内核 4.19.1 (Manjaro)。
答案1
@WumpusQ.Wumbley 在评论中指出了原因:扩展属性。
为了完整起见,答案如下。
扩展属性,在这种情况下应用Dropbox(getfattr
返回user.com.dropbox.attributes
),使用额外的块进行存储。没有这些扩展属性 ls
(和其他命令)返回:
$ ls -Gghs
total 136K
4,0K drwxr-xr-x 2 4,0K dec 22 20:11 empty_dir
0 -rw-r--r-- 1 0 dec 22 20:11 empty_file
4,0K -rw-r--r-- 1 1 dec 22 20:12 one_char
128K -rw-r--r-- 1 127K dec 22 20:13 several_blocks
正如预期的那样。
此外,stat
对于唯一有趣的several_blocks
回报情况:
$ stat several_blocks
File: several_blocks
Size: 129760 Blocks: 256 IO Block: 4096 regular file
...
这也符合预期,因为 256 * 512 - 129760 = 1312 < 4096,即没有使用额外的块。
- 由于扩展属性。
- 由于扩展属性。
- 由于扩展属性。
- 不可以,但要注意扩展属性由应用程序添加。
- 错误的假设。
答案2
“附加块”并不是由于配置中的某些不一致造成的。 (假设,由于其他原因,它总是可能是错误的。就像宇宙射线损坏了你的内核代码:-))。
我这样说是因为没有选项可以手动调整这些命令的磁盘使用情况的计算细节。这些命令仅通过乘法或除法将磁盘使用量转换为不同的单位。通过调用 stat() 系统调用来获取磁盘使用情况。内核返回许多合成“块”,它们始终为 512 字节。也没有任何内核选项影响 stat() 如何计算块数。
我可以告诉你,包含 inode 的块不应该计入你的 ext4 文件系统。一般来说,贾尔斯说它不计入他所知道的任何文件系统中。也许部分是由于您提出的观点:-)。 inode 往往小于 报告的 512 字节块stat
。 ext4 默认为 256 字节 inode; ext3 默认为 128 字节。
如果我们查看相关问题(右侧栏),我们会注意到一种可能存在额外块的情况。范围树(或间接块,如果范围被禁用)是依赖于 ext4。 (为什么文件大小和磁盘上的大小差异大于 4 KiB?)
相关问题的第二个答案提出了另一种情况。 Fallocate() 的某些用途可能允许创建大小与分配给它们的块数之间存在任意大差异的文件。
也就是说,我怀疑以上不足以解释任何你的例子。