如何在 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不同,儘管大多數物理範圍仍然是共享的。

相關內容