XFS

**XFS** (eXtents File System)は、シリコングラフィックスが同社のIRIXオペレーティングシステムのために開発した高性能ジャーナリングファイルシステムである。

## 歴史
XFSは（JFSと共に）UNIXシステムで最古のジャーナリングファイルシステムの一つであり、
成熟し安定し、コードはよくデバッグされている。
XFSの開発はシリコングラフィックスにより1993年に開始され、IRIX 5.3において初めて搭載された。

XFSは2000年5月にGPLで公開されると共にLinuxへの移植が開始され、
2001 - 2002年ごろにはサポートするディストリビューションが現れた。
Red Hat Enterprise Linux（RHEL）ではバージョン5.4以降「Scalable File Systemアドオン」という名前でXFSの有償サポートを行っていたが、RHEL7では/bootを含めた標準ファイルシステムとしてXFSを採用した。
XFSは2002年に開発版メインラインであるLinux 2.5 カーネルに、次いで2004年に安定版メインラインである2.4 カーネルにマージされた。
ほとんどすべてのLinuxシステムにおいて利用可能で、SUSE、Gentoo、Mandriva、Slackware、、、Ubuntu、Debian、Fedora、Arch Linuxの各ディストリビューションでXFSの利用を選択することができる。

FreeBSDでは、2005年12月から読み込みのみのサポートを開始し、2006年6月には FreeBSD-7.0-CURRENTにおいて実験的書き込みが可能となった。

XFSはファイルシステムの先頭ブロックをスーパーブロックとして使っておりブートローダーを先頭ブロックにインストールすることはできない。これはIRIXとの互換性の為であり変更の予定はないとしている。

## 仕様

### 容量
XFSは64ビットのジャーナリングファイルシステムであり、ファイルシステムの整合性が保証されている。ファイルシステムサイズは最大で8EiBであるが、通常ホストオペレーティングシステムの仕様によりそれよりも少ない容量に制限される。たとえば32ビット Linuxにおいては、最大16TiBである。

### ジャーナリング
XFSはファイルシステムメタデータをジャーナリングする。つまり、ファイルシステムへの変更が発生した際は、直列化されたジャーナルに書き込まれた後に、実ブロック
の更新が行われる。ジャーナルは、通常のディスク操作では読み込まれることのないディスク領域にリングバッファとして確保される。ジャーナルは、ファイルシステムのデータ部に置くこともできれば（内部ジャーナル）、ディスク操作の競合を避けるために別個のデバイス上に置くこともできる（外部ジャーナル）。
XFSのジャーナルは、ファイルシステム操作が高水準に表現された「論理的な」エントリ
から成る。それに対して、他のファイルシステムのジャーナルでは、トランザクション中で変更される
ブロックのコピーをそのまま保持した、「物理的な」エントリから成る。
ジャーナルの更新は、性能の低下を避けるために非同期的に行われる。
システムクラッシュが起きると、ジャーナルを利用することでクラッシュの直前の操作を再実行することが出来、
これによりXFSファイルシステムの整合性は保たれる。
この再実行による復旧は、ファイルシステムのマウント時に自動的に行われ、それに要する時間はファイルシステムのサイズに依存しない。
クラッシュに際し、未書き込みのデータブロックがジャーナル上に残っている場合には、復旧時にゼロで置換されて書き込まれる。
これはセキュリティ上の問題を回避するためである。

### アロケーショングループ
XFSファイルシステムは内部的に複数のに分割することが可能である。アロケーショングループとは、等しいサイズの連続的なディスク領域である。1つのファイルやディレクトリは複数のアロケーショングループに跨って存在することが可能である。
それぞれのアロケーショングループが固有のinode空間と固有の空き領域を持つことで、拡張性と並列処理性が生み出される。（複数の異なるスレッドやプロセスが同一のファイルシステムに同時にアクセス可能である）
この特性により、メタデータの更新も並列に行うことができ、マルチプロセッサシステムやマルチコアシステムにおいて、I/O性能を向上させることができる。
ファイルシステムが複数の物理デバイスに渡るときに、この強みは発揮され、すべての物理ストレージの性能が最大限発揮される。

### ストライプアロケーション
RAIDアレイ上にXFSファイルシステムを作成するときには、**ストライプ単位**をRAIDアレイのストライプ単位と一致させることにより、スループットを最大化することができる。

### エクステントの利用
XFSではファイルデータを格納するブロックは、と呼ばれる構造により管理される。個々のエクステントがポイントするブロック数は可変で、一つあるいは複数の連続したブロックを指し示すことが出来る。あるファイルに使われているブロックを単純に列挙して保持するファイルシステムに比べ、スペースを大きく削減できる。
他の多くのファイルシステムでは、ブロックのアロケーションのために、一つあるいは複数のビットマップを使用しているが、XFSではこれらビットマップは、エクステントを利用した（各アロケーショングループごとに）一対のB+木による管理構造に置き換えられている。
そのB+木の対の内、片方の木は利用できるエクステントの長さを管理し、他方はエクステントの開始ブロックを記録している。このデュアルインデックス構造により、種々のファイルシステム操作の中で効率高く利用可能なエクステントを探索することが可能となっている。

### 可変ブロックサイズ
ファイルシステムのブロックサイズは、アロケーションの最小単位のサイズである。
XFSではブロックサイズは512バイトから64キロバイトまで可変であり、用途に合わせてファイルシステムの作成時に指定できる。
小さなサイズのファイルを多数個使うのならば、ブロックサイズを小さくすれば利用可能な容量が大きくなるし、主に大きなサイズのファイルしか扱わないのであれば、ブロックサイズを大きくすることで読み書き性能が向上する。

### 遅延アロケーション
XFSはファイルアロケーションに遅延書き込みの技術を用いている。
バッファーキャッシュにファイルが書き込まれると、すぐにエクステントをアロケートするのではなく、記録に必要な数のブロックを予約するに止める。実際にエクステント（ブロック）がアロケートされるのはディスクにフラッシュされる時である。これにより、ファイルがなるべく連続したブロックに書き込まれるようにし、フラグメンテーションを減少させ、性能を向上させている。

### スパースファイル
XFSでは、64ビットのスパースなアドレス空間が各ファイルごとに利用可能で、すなわち、極めて大きいサイズのファイルを扱うと同時に、ファイル中に実ディスクスペースの割り当てのない「穴」を持たせることが出来る。
XFSはファイルのデータブロックの管理に可変長のエクステントを用いるため、ファイルアロケーションマップのサイズは小さく保持できる。
アロケーションマップのサイズが一つのinodeに収まり切らなくなった場合でも、そのアロケーションマップはB+木上に移される。
以上により64ビットの広大な空間であっても迅速にアクセスすることが可能となっている。

### 拡張属性
XFSは拡張属性として複数のデータストリームを一つのファイルに格納することが出来る。
これにより複数のname/valueの対を一つのファイルに付け加えることが出来る。
nameは最大で256バイトのヌル終端文字列で、valueは最大で64キロバイトのバイナリデータである。
さらにrootとuserの2つの名前空間に分けて記録できる。root名前空間に記録された属性はスーパーユーザーのみが変更可能であり、user名前空間の属性はそのファイルの書き込みパーミッションを持つユーザーのみが変更できる。
この拡張属性は、シンボリックリンクやデバイスノード、ディレクトリなどあらゆる種類のXFSのinodeに付加することが可能である。
`attr`ツールを使用して、コマンドラインから操作することが出来る。
`xfsdump`/`xfsrestore`ツールは拡張属性をサポートしており、拡張属性も併せてバックアップ/リストアされる。
他の多くのバックアップツールはXFS拡張属性に対応していない物が多い。

### ダイレクトI/O
高いディスクスループットが必要なアプリケーションのために、キャッシュされない入出力をユーザ空間で可能にするダイレクトI/Oが提供される。ファイルデータはDMAによりアプリケーションのバッファからディスクに直接転送されるため、ディスクデバイスのI/O帯域をそのまま利用できる。

### I/O帯域保証
XFSは保証された帯域幅でのファイル入出力を可能にするAPIを提供する。XFSは、接続されているストレージデバイスの利用可能な帯域幅を動的に計算し、要求された性能に見合った帯域幅を確保する。これは現在XFSのみがもつ機能である。
帯域保証にはhardとsoftの2種類があり、帯域保証の確実性とI/O性能のトレードオフにより使い分けることができる。ただし、hardはそのXFSファイルシステムが存在するディスクサブシステムがそれをサポートする時のみ利用可能である。
この帯域保証の機能は、ビデオストリーミングのようなリアルタイムアプリケーションでよく用いられる。

### DMAPI
XFSは階層型ストレージ管理をサポートするための・インタフェースを実装している。
この機能はLinux上で実装されているものの、主なカーネルソースには組み入れられていない。

### スナップショット
XFSはスナップショットを取るための機能そのものは提供しておらず、OS等のボリュームマネージャにより用意されることが想定されている。
そのようなボリュームマネージャによりスナップショットを取るための補助機能として、XFSは`xfs_freeze`により、ファイルシステムの凍結機能を提供している。
なお、2.6系のLinuxではスナップショット作成に`xfs_freeze`は不要である。（実行した場合、デッドロックが発生し正常にスナップショットが作成できない。）

### オンラインデフラグ
XFSは、可変長のエクステントを利用し遅延アロケーションをする為に、断片化に対してもともと高い耐性を持つが、XFSには独自のデフラグツール（`xfs_fsr`、XFS filesystem repackerの略）が用意されている。
これはマウントされていてアクティブなファイルシステムをデフラグすることが出来る。
（`xfs_fsr`は通常、`xfsprogs`パッケージではなく、`xfsdump`パッケージの一部として提供される。）

### オンラインリサイズ
XFSには`xfs_growfs`という、オンラインリサイズのためのツールがある。
そのXFSファイルシステムが存在するディスク上に未使用のスペースがある場合には、ファイルシステムサイズを拡張することが出来る。
この機能は通常ボリュームマネージャと組み合わせて用いられる。

### ネイティブなバックアップ/復元ツール
バックアップのために`xfsdump`と`xfsrestore`というツールがXFSでは利用できる。
`xfsdump`はXFSファイルシステムをinode順を保持したままバックアップすることが出来る。
UNIXの従来のファイルシステムでは書き込み可能としてマウントしたファイルシステムのバックアップを実行するとバックアップ中に更新されたファイルの整合性に問題が出ることがあるが、XFSでは`xfsdump`を用いてファイルシステムのバックアップをマウント中に取ることが出来る。
さらにこれらツールを用いたバックアップとリストアは、それぞれ実行中に一時中断したり再開したりすることが自在に可能である。
また、`xfsdump`は複数スレッドを使って実行することが可能で、複数のストリームに分割しつつ高速にバックアップを取得できる。その場合、各ストリームは異なるメディアに書き込むことも出来る。（しかし、この複数ストリームによるバックアップ機能は、現在の所Linuxでは完全に実装されていない。）

## 欠点
x86マシンのLinuxで使用する場合、等と呼ばれる、レガシーなブートシーケンスに使用されるパーティションの先頭セクタ（他のファイルシステム等では通常使われない）をXFSは使用しているため、ブート可能パーティションにできない。この仕様は IRIX との互換性の維持のため、変更されない。

削除されたファイルの復元はほぼ不可能である（これは長所でもある）。

Linuxでの実装では、異なるCPUアーキテクチャ間で、ジャーナリング最適化のために互換性の問題が発生する。しかしこの問題は、異なるアーキテクチャでマウントする前に`xfs_repair`を実行し、ジャーナルを消去することで、回避可能である。

「XFSはメタデータをジャーナリングする。」これは電源コードを不意に抜いても、再起動後には整合性のある状態に復元することを意味する（例えば、ディレクトリやそこに含まれるファイルリストを表示できるということである）。これは何も表示されなくなるよりはよい。しかし、XFSはデータの変更についてはジャーナルしないから、電源コードを抜いたときにデータを失う可能性はある。この点についてはXFSだけではなく、他のファイルシステム（例えばJFS）についても同じであり、メタデータのみのジャーナリングはアクセス速度と安全性のバランスのとれた優れた妥協点であるからである。

XFSは遅延書き込み最適化と、データとメタデータのディスク書き込み順序の点についてはSuSの解釈に甘さがある。同様に、ext3やdata=orderedモードのReiserFSで動作する操作が、データ破壊を引き起こす場合がある。

```
echo "original data here" > data
echo "new data goes here" > data.new
mv data.new data
*crash*
```

この3つの操作が実行された直後にクラッシュや電源が落ちたりすると、ファイルがランダムデータやNullコードに置き換わったりする可能性がある。なお、bug report in Ubuntu と posting from a XFS developer on linux-xfs にこの点に関する反対意見がある。

ディレクトリエントリの作成（空ファイル、サブディレクトリなど）と削除は他のファイルシステムに比べて遅いという指摘がある。詳細については以下を参照。Filesystem performance tweaking with XFS on Linux。この問題を解決するため、メタデータジャーナルにも遅延書き込み技術が適用され、バージョン3.12以降のLinuxカーネルで標準となった。詳細についてはhttps://lwn.net/Articles/476263/及びカーネルドキュメントの"filesystems/xfs-delayed-logging-design.txt"を参照。

SELinuxが登場した当初、XFSで使用すると性能劣化を引き起こす事が取り沙汰された。
これはXFSの「拡張属性がinode内に収められる場合は追加のディスクI/Oが要らない為高速だが、そうでない場合はinode外に個別のブロックを割り当てる為に拡張属性の参照に通常のデータと同じだけのディスクI/Oを伴う」という特性に対してSELinuxが使用する拡張属性がinode内に収められないサイズであった為に起きた。
この事自体はinodeに収めきれない拡張属性全てに起こるものでSELinux固有のものではないが、「多くのファイルが拡張属性を付加されている」、「至る所で暗黙的に読み出される事」という事情があり性能劣化を引き起こした。この問題は「attr2と呼ばれる新しい拡張属性の格納ポリシーを使用する」、「inodeの大きさをデフォルトより大きくする」のいずれかの行動を取ることで回避できる。xfsprogs バージョン2.7 以降では attr2 の使用がデフォルトになっており、問題回避のための対処を行う必要はない。

## 出典

## 脚注