在 BTRFS 磁盘上,使用 'du' 和 'dd' 的奇怪行为显示文件大小为 0。有人对此有什么线索或想法吗?

在 BTRFS 磁盘上,使用 'du' 和 'dd' 的奇怪行为显示文件大小为 0。有人对此有什么线索或想法吗?

一直在研究 btrfs,考虑从 ext4 转移到那个。

然而,当想要比较读写速度时,我似乎遇到了一个(至少对我来说)btrfs 磁盘上的异常行为du,它显然没有以与我的 ext4 上的文件相同的方式报告文件大小。

(抱歉,此处使用的是挪威语。不过大多数人可能对英语输出足够熟悉,知道发生了什么)


制作测试文件

  1. 我在dd挂载的文件系统磁盘 :

    $ sudo dd if=/dev/urandom of=5G_dd_test_file.tmp bs=1 count=0 seek=5G
    0+0 oppføringer inn
    0+0 oppføringer ut
    0 byte kopiert, 0,00393248 s, 0,0 kB/s
    
  2. 以类似的方式,我在相同位置创建一个测试文件fallocate

    $ sudo fallocate -l 5G 5G_fallocate_test_file.tmp
    
  3. ls确认他们都在那里:

    $ ls
    5G_dd_test_file.tmp  5G_fallocate_test_file.tmp
    

du行為怪异..(?)

输出的尺寸du <file>

$ sudo du 5G_dd_test_file.tmp 
0   5G_dd_test_file.tmp

$ sudo du 5G_fallocate_test_file.tmp 
5242880 5G_fallocate_test_file.tmp

注意 dd 生成的文件的大小为 0

相比之下,lsstat同一个文件上:

$ ls -l *.tmp
-rw-r--r-- 1 root root 5368709120 mars  24 18:07 5G_dd_test_file.tmp
-rw-r--r-- 1 root root 5368709120 mars  24 18:12 5G_fallocate_test_file.tmp
$ stat *.tmp
  Fil: 5G_dd_test_file.tmp
  Størrelse: 5368709120[tab]Blokker: 0          IO Blokk: 4096   vanlig fil
Device: 0,40    Inode: 258         Links: 1
Tilgang: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Tilgang: 2022-03-24 18:07:34.646755042 +0100
Omgjøring: 2022-03-24 18:07:34.646755042 +0100
Endring: 2022-03-24 18:07:34.646755042 +0100
 Fødsel: 2022-03-24 18:07:34.646755042 +0100
  Fil: 5G_fallocate_test_file.tmp
  Størrelse: 5368709120[tab]Blokker: 10485760   IO Blokk: 4096   vanlig fil
Device: 0,40    Inode: 259         Links: 1
Tilgang: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Tilgang: 2022-03-24 18:12:11.768422242 +0100
Omgjøring: 2022-03-24 18:12:11.768422242 +0100
Endring: 2022-03-24 18:12:11.768422242 +0100
 Fødsel: 2022-03-24 18:12:11.768422242 +0100

但是如果我将-b参数添加到du (通常不需要)当执行相同的操作时,dd生成的文件显示0尺寸。然后du看起来一切如常。

$ sudo du -b 5G_dd_test_file.tmp
5368709120  5G_dd_test_file.tmp

另一件奇怪的事情来自du(?)

因此,出于好奇,我决定简单地gzip从以下位置获取文件dd

$ sudo gzip 5G_dd_test_file.tmp

$ sudo du 5G_dd_test_file.tmp.gz
5092    5G_dd_test_file.tmp.gz

现在它显示的尺寸非零。

$ sudo ls -l 5G_dd_test_file.tmp.gz
-rw-r--r-- 1 root root 5210230 mars  24 18:07 5G_dd_test_file.tmp.gz
sudo stat 5G_dd_test_file.tmp.gz
  Fil: 5G_dd_test_file.tmp.gz
  Størrelse: 5210230   [tab]Blokker: 10184      IO Blokk: 4096   vanlig fil
Device: 0,40    Inode: 260         Links: 1
Tilgang: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Tilgang: 2022-03-24 18:07:34.646755042 +0100
Omgjøring: 2022-03-24 18:07:34.646755042 +0100
Endring: 2022-03-24 18:43:41.061926016 +0100
 Fødsel: 2022-03-24 18:42:27.554141544 +0100

问题是

  • 这是正常行为吗?而且确实是可以预料到的吗?
  • 如果不是,这是否可能破坏依赖于du回报的脚本或程序?

答案1

这是正常行为吗?而且确实是可以预料到的吗?

基本上是的。

创建文件时使用dd seek=…是一种创建文件. 使用dd seek=…和写入任何内容(count=0)是创建完全稀疏文件的一种方法。

[…] 稀疏文件是一种计算机文件,当文件本身部分为空时,它会尝试更有效地利用文件系统空间。这是通过将代表空块的简要信息(元数据)写入数据存储介质而不是构成块的实际“空”空间来实现的,从而消耗更少的存储空间。仅当块包含“真实”(非空)数据时,才会将完整块大小作为实际大小写入介质。

我更喜欢的方式是truncate。另一方面, 的主要目的fallocate是实际上分配块。fallocate为您创建了一个非稀疏文件。

du报告磁盘使用情况。完全稀疏文件使用零块来存储数据。它只是一个分配了零块的目录条目。

gzip创建了一个非稀疏文件。没有完全稀疏的文件可以成为有效的 gzip 存档,因为完全稀疏的文件在读取时会返回空字节,但 gzip 标头本身包含非空字节。此外,我不希望任何 gzip 存档是(能够)部分稀疏的,因为零块(即假设的稀疏部分)几乎不费吹灰之力就可以高度压缩,而它们的存在意味着gzip它的工作失败了。


这是否可能会破坏依赖于du回报的脚本或程序?

不,除非脚本du在应该使用du -b或时使用了wc -c;但那是一个错误在脚本中

du按照设计用途使用。以下是一些见解:为什么有这么多不同的方法来测量磁盘使用情况?


Ext4 也支持稀疏文件。使用你的dd命令,我在 ext4 文件系统和 btrfs 文件系统中分别创建了一个完全稀疏的文件。整个“问题”绝对是不是关于 ext4 与 btrfs。

相关内容