如何在 Btrfs 文件系统中查找给定文件的数据副本?

如何在 Btrfs 文件系统中查找给定文件的数据副本?

我已经使用 bedup 对 Btrfs 文件系统进行了重复数据删除,因此现在所有重复文件(超过一定大小)都是“reflink”副本。

有什么方法可以看到,给定文件名,哪些其他文件是相同的引用链接?

答案1

像 btrfs 这样的写时复制 (CoW) 文件系统的全部意义在于可以有效地共享文件的多个版本的内容。因此,您可能会将文件视为包含内容的范围的集合,其中内容可能会或可能不会被其他文件共享。或者通过该文件的其他版本。实现更像是一个扩展树,其中扩展可以共享。

在将更改写入文件(并因此生成该文件的新版本)期间工作的相同机制用于执行重复数据删除。该实现描述于https://github.com/g2p/bedup

重复数据删除是使用 Btrfs 功能实现的,该功能允许将数据从一个文件克隆到另一个文件。克隆的范围在磁盘上共享,从而节省空间。

内核中的实现(例如)位于http://lxr.free-electrons.com/source/fs/btrfs/ioctl.c#L2843;该评论清楚地表明,这不是关于“重新链接”文件,而是关于范围:

2843 /**
2844  * btrfs_clone() - clone a range from inode file to another
2845  *
2846  * @src: Inode to clone from
2847  * @inode: Inode to clone to
2848  * @off: Offset within source to start clone from
2849  * @olen: Original length, passed by user, of range to clone
2850  * @olen_aligned: Block-aligned value of olen, extent_same uses
2851  *               identical values here
2852  * @destoff: Offset within @inode to start clone
2853  */

所以它不是被重新链接的文件,而是被共享的范围。还可以通过与多个文件共享范围来构建新文件。或者跨卷共享。或者(不确定当前是否支持)甚至在同一个文件中多次具有相同的范围;)

因此,不存在高级工具来查找共享整个文件的文件,因为这是一个派生概念。当然,可以为它编写支持,但据我所知,情况并非如此......

答案2

我刚刚发布了一个名为fienode(← 链接)计算文件物理范围的 SHA1 哈希值。相同的 CoW 副本具有相同的哈希值。

原则上,您可以在文件系统上的所有文件上运行此命令,然后查找相同的哈希值。

这里还有一个更详细的答案,解释了为什么这是必要的。

但请注意,BTRFS 可以自由更改物理范围。我观察到一个大型的引用链接文件在没有任何刺激的情况下改变了它的物理范围,使得输出fienode不同,尽管大多数物理范围仍然是共享的。

相关内容