如何在 btrfs 上为单个文件打开压缩?

end*_*ith 4 compression btrfs

我正在使用 GNU 生成 3 TB 驱动器映像ddrescue,并意识到它对于目标驱动器来说太大了(因为空白空间填充了 0xAA 而不是 0x00,所以我没有使用稀疏输出文件,而是需要实际压缩)。

输出文件在 btrfs 文件系统上,它支持按文件压缩,但通过哪种方法?

  1. https://wiki.archlinux.org/index.php/Btrfs#Compression说:

要将压缩应用于现有文件,请使用命令,其中 是,或。例如,要使用 zstd 重新压缩整个文件系统,请运行以下命令:btrfs filesystem defragment -calgalgzliblzozstd

  # btrfs filesystem defragment -r -v -czstd /
Run Code Online (Sandbox Code Playgroud)

这会重新压缩现有文件,但似乎是针对文件文件夹,而不是单个文件?

  1. 它还说:

提示:也可以在不使用compress挂载选项的情况下为每个文件启用压缩;这样做适用 chattr +c于文件。当应用于目录时,它将导致新文件在出现时自动压缩。

不过,目前尚不清楚这是否会重新压缩现有文件。

  1. https://btrfs.wiki.kernel.org/index.php/Compression#Can_I_force_compression_on_a_file_without_using_the_compress_mount_option.3F

在文件上设置压缩属性 usingbtrfs property set <file> compression <zlib|lzo|zstd>强制使用指定算法在该文件上使用压缩。

这似乎是为了强制压缩通常不会被压缩的文件,因为它们包含不是很可压缩的数据?

我想将整个现有文件转换为(默认 LZO)压缩,并继续压缩将来写入其中的任何数据,而不更改卷上其他文件的压缩?

小智 5

# btrfs filesystem defragment -r -v -czstd /
Run Code Online (Sandbox Code Playgroud)

这会重新压缩现有文件,但似乎是针对文件文件夹,而不是单个文件?

它也适用于单个文件。

(对于需要-r标志的目录,否则它将对该目录所属的子卷的元数据进行碎片整理)。

chattr +c

不过,目前尚不清楚这是否会重新压缩现有文件。

它不会。

btrfs property set <file> compression <zlib|lzo|zstd>

这似乎是为了强制压缩通常不会被压缩的文件,因为它们包含不是很可压缩的数据?

它禁用检测文件是否可压缩的机制并无论如何压缩它。
我相信它只会存储压缩文件,如果它至少有点可压缩,更具体地说,如果压缩数据不大于原始 IIRC。

另请注意,该检测机制不是很复杂,有时也会对非常可压缩的文件禁用压缩。

我想将整个现有文件转换为(默认 LZO)压缩,并继续压缩将来写入其中的任何数据,而不更改卷上其他文件的压缩?

btrfs filesystem defragment -clzo /path/to/file
Run Code Online (Sandbox Code Playgroud)

(注意:这将强制压缩文件)

  • 如果我使用“文件系统碎片整理”并继续写入文件,那么在那之后写入的部分将不会被压缩,对吧?`filesystem defragment` 压缩现有部分,但不压缩未来部分,而 `chattr +c` 压缩未来部分,但不压缩现有部分? (2认同)