XFS

XFS，一種高性能的日誌文件系統，最早於1993年，由Silicon Graphics為他們的IRIX作業系統而開發，是IRIX 5.3版的預設檔案系統。2000年5月，Silicon Graphics以GNU通用公共許可證釋出這套系統的原始碼，之後被移植到Linux內核上。XFS特別擅長處理大文件，同時提供平滑的數據傳輸。

## 歷史

XFS的開發始於1993年，在1994年被首次部署在IRIX 5.3上。2000年5月，XFS在GNU通用公共許可證下發布，並被移植到Linux上。2001年XFS首次被Linux發行版所支持，現在所有的Linux發行版上都可以使用XFS。

XFS最初被合併到Linux 2.4主線中，這使得XFS幾乎可以被用在任何一個Linux系統上。Arch, Debian, Fedora, openSUSE, Gentoo, Kate OS, Mandriva, Slackware, Ubuntu, VectorLinux和Zenwalk的安裝程序中都可選擇XFS作為文件系統，但由於預設的啟動管理器GRUB中存在bug，以上發行版中只有少數幾個允許用戶在 /boot 掛載點（引導目錄）上使用XFS文件系統。

FreeBSD在2005年12月獲得了對XFS的只讀支持，並在次年6月引入了試驗性的寫入支持。不過這些只是為了方便使用者從Linux上遷移到FreeBSD上，並不是為了把XFS作為主打文件系統使用。Red Hat Enterprise Linux 5.4 64位版的內核完整支持XFS，但未包含創建和使用XFS的命令行工具（CentOS正在進行這方面的嘗試），原因是這些軟體包還不夠穩定。Red Hat Enterprise Linux 7/CentOS預設使用XFS檔案系統。

## 規範

### 容量

XFS是一個64位文件系統，最大支持8exbibytes減1位元組的單個文件系統，實際部署時取決於宿主作業系統的最大塊限制。對於一個32位Linux系統，文件和文件系統的大小會被限制在16tebibytes。

### 文件系統日誌

日誌文件系統是一種即使在斷電或者是作業系統崩潰的情況下保證文件系統一致性的途徑。XFS對文件系統元數據提供了日誌支持。當文件系統更新時，元數據會在實際的磁碟塊被更新之前順序寫入日誌。XFS的日誌被保存在磁碟塊的循環緩衝區上，不會被正常的文件系統操作影響。XFS日誌大小的上限是64k個塊和128MB中的較大值，下限取決於已存在的文件系統和目錄的塊的大小。在外置設備上部署日誌會浪費超過最大日誌大小的空間。XFS日誌也可以被存在文件系統的數據區（稱為內置日誌），或者一個額外的設備上（以減少磁碟操作）。

XFS的日誌所保存的是「邏輯」條目，以人類更加容易理解的方式來描述當前正在進行的操作（「物理」日誌與其相反，保存的是每次操作中被修改的塊）。日誌的更新以異步的方式進行，避免影響整體性能。

如果發生系統崩潰，可以根據日誌中的記錄來重做並完成崩潰的前一時刻發生的系統操作。崩潰之後首次掛載文件系統時，會自動進行恢復。恢復的速度不受文件系統大小的影響，取決於需要重做的系統操作的數量。

對於最近被修改但未完全寫入磁碟的數據，XFS保證在重啟時清零所有未被寫入的數據塊，以防止任何有可能的、由剩餘數據導致的安全隱患（因為雖然從文件系統接口無法訪問這些數據，但不排除裸設備或裸硬體被直接讀取的可能性）。

### 分配組

XFS文件系統內部被分為多個「分配組」，它們是文件系統中的等長線性存儲區。每個分配組各自管理自己的inode和剩餘空間。文件和文件夾可以跨越分配組。這一機制為XFS提供了可伸縮性和並行特性——多個線程和進程可以同時在同一個文件系統上執行I/O操作。這種由分配組帶來的內部分區機制在一個文件系統跨越多個物理設備時特別有用，使得優化對底層存儲部件的吞吐量利用率成為可能。

### 條帶化分配

在條帶化RAID陣列上創建XFS文件系統時，可以指定一個「條帶化數據單元」。這可以保證數據分配、inode分配、以及內部日誌被對齊到該條帶單元上，以此最大化吞吐量。

### 基於Extent的分配方式

XFS文件系統中的文件用到的塊由變長Extent管理，每一個Extent描述了一個或多個連續的塊。與那些把文件所有塊都單獨列出來的文件系統相比，extent大幅縮短了列表。

有些文件系統用一個或多個面向塊的位圖管理空間分配——在XFS中這種結構被由一對B+樹組成的、面向Extent的結構替代了；每個文件系統分配組（AG）包含這樣的一個結構。其中，一個B+樹用於索引未被使用的Extent的長度，另一個索引這些Extent的起始塊。這種雙索引策略使得文件系統在定位剩餘空間中的Extent時十分高效。

### 可變塊尺寸

塊是文件系統中的最小可分配單元。XFS允許在創建文件系統時指定塊的大小，從512位元組到64KB，以適應專門的用途。比如，對於有很多小文件的應用，較小的塊尺寸可以最大化磁碟利用率；但對於一個主要處理大文件的系統，較大的塊尺寸能提供更好的性能。...

### 延遲分配

XFS在文件分配上使用了惰性計算技術。當一個文件被寫入緩存時，XFS僅在記憶體中對該文件保留適當數量的塊，並不立即給數據分配Extent。實際的塊分配僅在這段數據被沖刷到磁碟時才發生。這一機制提高了將該文件寫入一組連續塊中的機會，減少碎片的同時提升了性能。

### 稀疏文件

XFS對每個文件提供了一個64位的稀疏地址空間，使得大文件中的「洞」（空白數據區）不被實際分配到磁碟上。因為文件系統對每個文件使用一個Extent表，文件分配表就可以保持一個較小的體積。對於太大以至於無法存儲在inode中的分配表，這張表會被移動到B+樹中，繼續保持對該目標文件在64位地址空間中任意位置的數據的高效訪問。

### 擴展屬性

XFS通過實現擴展文件屬性給文件提供了多個數據流，使文件可以被附加多個名/值對。文件名是一個最大長度為256位元組的、以NULL字符結尾的可列印字串，其它的關聯值則可包含多達64KB的二進位數據。這些數據被進一步分入兩個名字空間中，`root`和`user`。保存在root名字空間中的擴展屬性只能被超級用戶修改，user名字空間中的可以被任何對該文件擁有寫權限的使用者修改。擴展屬性可以被添加到任意一種 XFS inode上，包括符號連結、設備節點、目錄，等等。可以使用`attr`這個命令行程序操作這些擴展屬性。`xfsdump`和`xfsrestore`工具在進行備份和恢復時會一同操作擴展屬性，而其它的大多數備份系統則會忽略擴展屬性。

### Direct I/O

對於需要高吞吐量的應用，XFS實現了直接的I/O，允許未緩存的I/O操作直接應用到使用者空間。數據在應用程式的緩衝區和磁碟間利用DMA進行傳輸，以此提供底層磁碟設備全部的I/O帶寬。

### 確定速率I/O

XFS確定速率I/O系統給應用程式提供了預留文件系統帶寬的API。XFS會動態計算底層存儲設備能提供的性能，並在給定的時間內預留足夠的帶寬以滿足所要求的性能。此項特性是XFS所獨有的。確定方式可以是硬性的或軟性的，前者提供了更高性能，而後者相對更加可靠。不過只要底層存儲設備支持硬性速率確定，XFS就只允許硬性模式。這一機制最常被用在實時應用中，比如影片流。

### DMAPI

XFS實現了數據管理應用程式接口（DMAPI）以支持高階存儲管理（HSM）。到2010年10月為止，Linux上的XFS實現已經支持DMAPI所要求的的磁碟元數據規範，但有報告稱內核支持仍處於不穩定狀態。此前SGI曾提供了一個包含DMAPI鉤子的內核源碼樹，但這個支持未被合併進主代碼樹。不過現在內核開發者們已經注意到了它並對其做了更新。

### 快照

XFS並不直接提供對文件系統快照的支持，因為XFS認為快照可在卷管理器中實現。對一個XFS文件系統做快照需要調用`xfs_freeze`工具凍結文件系統的I/O，然後等待卷管理器完成實際的快照創建，再解凍I/O，繼續正常的操作。之後這個快照可以被當作備份，以只讀方式掛載。在IRIX上發布的XFS包含了一個整合的卷管理器，叫XLV。這個卷管理器無法被移植到Linux上，不過XFS可以和Linux上標準的LVM正常工作。在最近發布的Linux內核中，`xfs_freeze`的功能被實現在了VFS層，當卷管理器的快照功能被喚醒時將自動啟動`xfs_freeze`。相對於無法掛起，卷管理器也無法對其創建「熱」快照的ext3文件系統，XFS的快照功能具有很大優勢。幸運的是，現在這種情況已經改觀。從Linux 2.6.29內核開始，ext3, ext4, gfs2和jfs文件系統也獲得了凍結文件系統的特性。

### 在線碎片整理

雖然XFS基於Extent的特徵和延遲分配策略顯著提高了文件系統對碎片問題的抵抗力，XFS還是提供了一個文件系統碎片整理工具，`xfs_fsr`（XFS filesystem reorganizer的簡稱）。這個工具可以對一個已被掛載、正在使用中的XFS文件系統進行碎片整理。

### 在線尺寸調整

XFS提供了`xfs_growfs`工具，可以在線調整XFS文件系統的大小。XFS文件系統可以向保存當前文件系統的設備上的未分配空間延伸。這個特性常與卷管理功能結合使用，因為後者可以把多個設備合併進一個邏輯卷組，而使用硬碟分區保存XFS文件系統時，每個分區需要分別擴容。到2010年8月為止，XFS分區不可以原位收縮，不過有一些方法可以變相處理這個問題。

### 原生備份/恢復工具

XFS提供了`xfsdump`和`xfsrestore`工具協助備份XFS文件系統中的數據。`xfsdump`按inode順序備份一個XFS文件系統。與傳統的UNIX文件系統不同，XFS不需要在dump前被卸載；對使用中的XFS文件系統做dump就可以保證鏡像的一致性。這與XFS對快照的實現不同，XFS的dump和restore的過程是可以被中斷然後繼續的，無須凍結文件系統。`xfsdump`甚至提供了高性能的多線程備份操作——它把一次dump拆分成多個數據流，每個數據流可以被發往不同的目的地。不過到目前為止，Linux尚未完成對多數據流dump功能的完整移植。

### 原子磁碟配額

XFS的磁碟配額在文件系統被初次掛載時啟用。這解決了一個在其它大多數文件系統中存在的一個競爭問題：要求先掛載文件系統，但直到調用quotaon (8)之前配額不會生效。

## 性能考慮

### 寫入屏障

XFS文件系統默認在掛載時啟用「寫入屏障」的支持。該特性會一個合適的時間沖刷底層存儲設備的回寫緩存，特別是在XFS做日誌寫入操作的時候。這個特性的初衷是保證文件系統的一致性，具體實現卻因設備而異——不是所有的底層硬體都支持緩存沖刷請求。在帶有電池供電緩存的硬體RAID控制器提供的邏輯設備上部署XFS文件系統時，這項特性可能導致明顯的性能退化，因為文件系統的代碼無法得知這種緩存是非易失性的。如果該控制器又實現了沖刷請求，數據將被不必要地頻繁寫入物理磁碟。為了防止這種問題，對於能夠在斷電或發生其它主機故障時保護緩存中數據的設備，應該以`nobarrier`選項掛載XFS文件系統。

### 日誌的放置

XFS文件系統創建時默認使用內置日誌，把日誌和文件系統數據放置在同一個塊設備上。由於在所有的文件系統寫入發生前都要更新日誌中的元數據，內置日誌可能導致磁碟競爭。在大多數負載下，這種等級的競爭非常低以至於對性能沒有影響。但對於沉重的隨機寫入負載，比如在忙碌的數據塊伺服器上，XFS可能因為這種 I/O競爭無法獲得最佳性能。另一個可能提高這個問題的嚴重性的因素是，日誌寫入被要求以同步方式提交——它們必須被完全寫入，之後對應實際數據的寫入操作才能開始。

如果確實需要最佳的文件系統性能，XFS提供了一個選項，允許把日誌放置在一個分離的物理設備上。這只需要很小的物理空間。分離的設備有自己的I/O路徑，如果該設備能對同步寫入提供低延遲的路徑，那麼它將給整個文件系統的操作帶來顯著的性能提升。SSD，或帶有寫回緩存的RAID系統是日誌設備的合適候選，它們能滿足這種性能要求。不過後者在遭遇斷電時可能降低數據的安全性。要啟用外部日誌，只須以`logdev`選項掛載文件系統，並指定一個合適的日誌設備即可。

## 缺點

- XFS文件系統的卷無法被直接收縮，只能通過「備份->重灌->還原」的方式間接進行容量縮減（這也是雲端主機供應商會告知存儲空間只能增加不能縮減的其中一個原因），在準備多一組存儲卷的情況下，有工具可對XFS卷進行上述操作：`xfsdump`和`xfsrestore`。
- 歷史上XFS上的元數據操作曾比其它文件系統都慢，表現為在刪除大量小文件時性能糟糕。該性能問題是被Red Hat的XFS開發者Dave Chinner在代碼中定位到的。使用一個叫「延遲記錄」的掛載選項可以成數量級地提升元數據操作的性能。該選項幾乎把日誌整個存在記憶體中。Linux內核主線版本2.6.35中作為一個試驗性特性引入了這個補丁，在2.6.37中使它成為了一個穩定的特性，並在2.6.39中把它作為預設的日誌記錄方法。早期測試顯示在有少量線程的環境中其性能接近EXT4，在大量線程的環境下超過了EXT4。
- 缺少透明壓縮的支援
- 缺少校驗保護，校驗保護在對付資料損毀#靜態型方面有幫助

## 參考文獻

- XFS for Linux Administration（SGI Document Number: 007-4273-003）

## 基本資料

- 開發者：Silicon Graphics Inc.
- 發布：IRIX v5.3
- 發布：1994年
- 目錄內容：B+樹
- 文件分配：B+樹
- 最長文件名：255 bytes
- 最大卷容量：16 exabytes
- 最大文件尺寸：8 exabytes、（減1位元組）
- 文件名字符集：除NUL（'\0'）和 '/'以外的字節
- 日期記錄：支持
- 日期解析度：納秒
- 屬性：支持
- 文件系統權限：支持
- 透明壓縮：不支持
- single_instance_storage：不支持
- 透明加密：不支持（在塊設備層上實現）
- 作業系統：IRIX, Linux, FreeBSD （試驗性）