BTRFS Defragmentation

備註:本文翻譯自 IBM Research Report BTRFS - Linux Btree Filesystem

在寫的時候,碎片整理以兩種不同方式解決。爲了碎片整理一個文件,它被讀取,COWed,並在下一個檢查點寫入磁盤。這可能會使他更加順序,因爲分配器嘗試在儘可能少的extents裏寫出來。缺點是與舊快照的共享丟失了。在許多情況下,這個簡單的算法是有效的。在一些情況下,一個更加複雜的算法維持共享是需要的。

當縮減文件系統的時候,或者從磁盤刪除數據,重新分配會被使用。這是一種算法掃描一個chunk和移動實時數據,同時保持共享。重新分配是複雜的程序,無論怎麼樣,在我們試圖減少空間消耗的時候,無視共享可能會導致空間使用量的增加。

遷移通過chunks basis 工作在一個chunk上。一般的方案是:

1.遷走所有實時的extents(在chunk中)

2.找到所有引用發到chunks中。

3.在保持共享時修復引用

寫時複製方法被貫穿使用;引用永遠不會更新到位。表1 展示了一個簡單的例子。一個數據extent,藍色,需要被移動。

表1:在extent tree下進行範圍內的查找,在chunk中找到所有的extents,拷貝所有的實時extents到新的位置。

爲了加速一些引用跟蹤,我們跟隨back-references去找到所有頂層樹塊直接或者間接地引用chunk。結果存儲在一個叫做backref_cache的DIAG類的數據結構。

表2:上層節點存儲在一個backref_cache.

子卷樹列表從backref_cache中引用的chunk被計算;這些樹被順序的克隆,看錶3。這個操作有兩種影響:(1)及時凍結子卷的狀態。(2)它允許在爲用戶提供持續操作的同時對子捲進行即時修改。

表3:遷移樹。這個例子中,子卷被克隆。可以對克隆盡心更改。

接下來,所有chunks的引用都被遵循, 使用back-references。COW在reloc tree中被用於更新。看錶4。

表4:使用COW去修復在reloc樹中的引用

最後一步是合併reloc trees和原始的。我們遍歷樹。我們找到在reloc樹中被修改但是對應的部分在fs tree中沒有被修改的子樹。這些在reloc tree中的子樹與fs樹中的老同行交換。最終結果是新的fs-trees。最後,我們丟棄reloc trees,他們不再需要了。表5是一個例子。

合併reloc樹和對應的fs樹,然後drop掉reloc樹。

新的文件系統DIAG在內存中,有正確的共享結構。它和原始的使用一樣的數量,這就意味着文件系統空間使用時一樣的。將DIAG寫出到磁盤可以在連續的範圍內完成,從而提高序列性。一旦完成,老的chunk可以被丟棄。

 

本文翻譯自:IBM Research Report - BTRFS

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章