ZFS

**ZFS**は、主にオラクルのSolaris上で実装されている128ビット・アドレッシングを特徴とするファイルシステム。今までSolaris (SunOS) で用いられてきた Unix File System (UFS) の次世代ファイルシステムと位置づけられている。名称は*Zettabyte File System*に由来するが、現在は何の略称でもないとされる。

## 概要
2004年9月にアナウンスがあり、2005年11月リリースのOpenSolaris build 27で実装が公開された。
"Common Development and Distribution License" (CDDL) のもと、オープンソースで開発されている。

特徴として以下の項目が挙げられる。

* チェックサムが64ビット化された
* コピーオンライトの実装
* ボリュームマネージャが必要なく、ボリュームの構成が容易にできるようになった
* ディスクの違い（容量、種類）を吸収する仮想ボリューム（ストレージプールと呼称）をサポート
* ストレージプールの作成・フォーマット・マウントがコマンド一行ですむ
* ファイルシステム自身がRAID機能を持つ
* ブロックサイズが可変長かつファイルシステム単位で指定可能、サイズ上限はストレージプールの仕様上限となる16MBまで
* スナップショットおよびブックマークを用いたフル･差分バックアップおよびリストア

またSolaris10 11/06版より以下の機能が加わった。

* RAID-Z2（ダブルパリティによるRAID-6相当の機能）
* ホットスペア
* クローンプロモーション（アクティブなZFS領域を複製と置換を容易にする機能）
* 再帰的スナップショットコマンドの簡素化オプション

以下に記載されていない機能追加として、Oracle Solaris Solaris SRU 11.2.8.4.0などより、Persistant L2ARC (ブートをまたがるL2ARCの内容の再利用）が追加されている（他の環境での実装状況を記載する必要あり） 。

以降の追加機能は下記のバージョン番号を参照。 

### バージョン番号
利用可能な形式と特徴を指定するために、新機能が導入されるに従ってZPoolとZFSのバージョン番号が増える。バージョン番号の一覧は以下の通り。（[]内はサポートしているオペレーティングシステム）

# Initial ZFS version [Supported by Solaris 10 06/06]
# Ditto blocks (replicated metadata) [Supported by Solaris 10 06/06 build 09]
# Hot spares and double parity RAID-Z [Supported by Solaris 10 11/06]
# zpool history [Supported by Solaris 10 08/07]
# Compression using the gzip algorithm
# bootfs pool property [Supported by FreeBSD 7.0]
# Separate intent log devices
# Delegated administration [Supported by Solaris 10 10/08]
# refquota and refreservation properties
# Cache devices
# Improved scrub performance
# Snapshot properties
# snapused property [Supported by OpenSolaris 2008.11, FreeBSD 8.0]
# passthrough-x aclinherit [Supported by OpenSolaris 2009.06, FreeBSD 8.1]
# user/group space accounting [Supported by Solaris 10 10/09, FreeBSD 8.2, FreeBSD 8-STABLE]
# stmf property support
# Triple-parity RAID-Z
# Snapshot user holds
# Log device removal
# Compression using zle (zero-length encoding)
# Deduplication
# Received properties [Supported by Solaris 10 9/10]
# Slim ZIL
# System attributes
# Improved scrub stats
# Improved snapshot deletion performance
# Improved snapshot creation performance
# Multiple vdev replacements [Supported by FreeBSD 9-CURRENT]
# RAID-Z/mirror hybrid allocator [Supported by Solaris 10 8/11]
# ZFS data set encryption
# Improved 'zfs list' performance [Supported by Solaris 11 Express b151a]
# One MB blocksize
# Improved share support [Supported by Solaris 11 EA b173]
# Sharing with inheritance [Oracle Solaris 11.1 or later]
# Sequential resilver [Oracle Solaris 11.2 or later]
# Efficient log block allocation [Oracle Solaris 11.3 or later]
# lz4 compression
# xcopy with encryption [Oracle Solaris 11.4 or later]
# reduce resilver restart
# Deduplication 2
# Asynchronous dataset destroy
# Support for reguid
# RAID-Z enhancements and cloud device support
# Device Removal

今、自分のシステムでどのバージョンまでサポートしているか知りたい場合はコマンド`zpool upgrade -v`で確認できる。

2012年1月、OpenZFSは従来のバージョン番号に代わり、機能フラグ（feature flag）を導入した。これにより、新規に追加された機能は個別にサポートを有効化ないしは無効化できるようになっている。機能フラグの状況についても、コマンド`zpool upgrade -v`で確認できる。

## 訴訟合戦
2007年9月、ネットアップがZFSは自社の特許を侵害しているとして、開発したサン・マイクロシステムズを訴えた。10月にサン・マイクロシステムズは特許は無効と反訴。互いの経営者同士が自らのブログで応酬を繰り広げていたが、サンがオラクルに買収された後の2010年9月9日、訴訟取り下げで合意した。

## キャパシティ
128ビット・アドレッシングで主な制限は以下の通り。

* 16エクサバイト &mdash; ファイルシステムの最大値
* 16エクサバイト &mdash; 1ファイルの最大値

## プラットホーム
; Solaris（10 6/06以降）
: 10/08版よりブートパーティションとしても作成可能になった。

; OpenSolaris→OpenIndiana
: SPARC及びx86版のOpenSolaris build 27以降で動作する。2008.05版よりデフォルトファイルシステム。
: OpenIndianaは初期リリースoi_148からデフォルトファイルシステムである。

このほか、SunOS系列（Illumos系統含む）ディストリビューションでもサポートされている。

### 移植
CDDLでライセンスされるオープンソースであり、Solaris系以外のUnix系オペレーティングシステムにも移植が進んでいる。
; FreeBSD
: FreeBSDが採用しているBSDライセンスはCDDLとの親和性に優れていることから、サンが開発していた頃からソースに統合された形での利用が可能であった。ZFSが初めてサポートされたのは7.0-RELEASEである。
: 64ビットアーキテクチャとしてのx64上の9.0-RELEASEでZFS v28をサポートしている。IA-32でも一応動作するが、実用的に使うのは難しい（カーネルが多量のメモリを必要とするが、32ビット空間の限界がある等）。iSCSIを経由した共有ZVOLs機能 (zfs set shareiscsi) はFreeBSD側に同等の機能があるためZFS側では実装されていない。また10.x以降はAFT（4KB/セクタ）を自動的に認識してZFS poolを作成するようになった。
: 13.0-RELEASEにてZFS実装をOpenZFS 2.0へ変更した。同バージョンにてカーネルモジュール実装からOS依存部が分離され、LinuxとFreeBSDの同時サポートが容易になったことを受けたもの。
: x64の他、arm64等でもサポートされている。
; NetBSD
: 2007年の Google Summer of Code で開発が始められたが、2016年時点でメンテナンスされていない。
; macOS(旧Mac OS X)
: 10.5 Leopardより搭載されているが、初期リリースの10.5.0では読み込みのみの対応にとどまる。10.6 Snow Leopard では、サーバ版で標準対応することが発表されていたものの10.6.1 リリースでも実現せず、結局AppleはZFSプロジェクトを停止した。Btrfsを開発中のオラクルによるサン・マイクロシステムズ買収に伴いZFSの将来が不透明になったためと報じられている。その後、**MacZFS**プロジェクトがGoogle Codeのホスティングで続いていたが2013年に終了したhttps://code.google.com/archive/p/maczfs。アップルは別途、Apple File Systemを開発、2017年に iOS 10.3とmacOS High Sierraでリリースした。
:2020年11月30日にMacOS Big Sur, Catalina, Mojaveに対応したがリリースされた。
; Linux
: ZFSの採用するCDDLと、Linuxの採用するGPLとの間にライセンスの抵触が発生するという問題があり、また、ZFSの権利を保有するオラクルの姿勢を踏まえ、Linuxの生みの親リーナス・トーバルズがカーネル本体のソースレポジトリへマージしない姿勢を表明している為、Linuxではメインラインのカーネルソースおよびこれをビルドしたバイナリのみでの利用は出来ない。
: Linuxカーネル内でのZFS利用にあっては、（）がZFSの機能を提供しており、独立したカーネルモジュールとして、ないしはLinuxカーネルのソースにOpenZFSのソースを統合した上でまとめてビルドすることにより利用できる。 Debian / CentOS / Ubuntu / FedoraなどといったLinuxディストビューションに含まれている。このうちUbuntuは16.04にてに依存しない手段を用いたZFSのサポートを発表した。
: OpenZFS以外では、FUSEというユーザー空間のファイルシステムドライバを利用する形での実装例は存在しているが、ユーザー空間の実装であるため、一部の機能は制限される。この実装は2006年のGoogle Summer Codeから始まっている。zfs-fuseの名称で、Red Hat Enterprise LinuxのEPEL（）リポジトリやUbuntu 10.04以降など各種Linuxディストリビューションに含まれている。
: この他、2010年頃から別個に2本のネイティブポート版開発プロジェクトが動いており、そのうちKQ infotechのパッケージはPOSIX準拠である。

## 制限事項
ZFSはデータの更新を常にコピーオンライト処理とする。これに起因して、既存のUnix向けファイルシステムでは発生しないような問題が生じることがある。

ZFSにて、データが頻繁に更新されるファイルシステムにて空き容量が少なくなると、空き容量がゼロでないにもかかわらずデータ更新に失敗することがある。これはコピーオンライトを採用したファイルシステムでは避けられない問題である。具体的な例として、固定サイズのファイルに`[[mmap|mmap()]]`を用いてアクセスする場合、ページをファイルへ書き戻す際にファイルシステムの空き容量不足によるエラーを防ぐため、`fallocate()`ないしは`posix_fallocate()`を用いてファイルブロックを確保する習慣があるが、ZFSではコピーオンライトが必須となっている影響により、これを実行してもなおエラーが発生する場合がある。この影響で、ZFSは当初`fallocate()`の実装を見送っていた。2020年6月までに、Linuxに限って`fallocate()`の互換実装がマージされている。しかし、実際にはスナップショットや圧縮機能との干渉が指摘されており、本質的な対応は困難とされている。また、詳細な調査の結果、illumosにてZFSへのカーネルコアダンプをサポートするため、ファイルブロックを確保する機能がZFSに存在することが確かめられた。しかし、この機能はコピーオンライトをバイパスした書き込みを実行するなど利用目的がカーネルコアダンプに限定されており、`fallocate()`を含めた通常運用下での使用は考慮されていないことも明らかになっている。

ZFS上のファイルに対してランダムアクセスによるデータ更新を行うと、予め`fallocate()`などにより物理的に連続したファイルブロックを確保することを期待していてもブロックが断片化する。ext4が`fallocate()`による連続したファイルブロックの確保を正式にサポートしていることから、これを前提としたソフトウェアをZFSへ持ち込むと問題が発生しやすい。これもデータ更新がコピーオンライト処理となる直接の結果であり、`mmap()`の使用により特に顕著となる。このような場合はファイルブロックに対して連続性を前提とするのではなく、断片化を容認した上で、それが機能や性能に影響しないようにする必要がある。また、ファイルシステム単位での可変長ブロック機能を利用すれば最大16MBの物理的に連続したブロックが使用できる。ext4の最大エクステント（4KBブロックの場合、128MB）よりは小さいものの、個々のファイルに対する特殊な設定変更は不要である。

## 脚注

## 外部リンク
* OpenSolaris Community Group zfs Pages
* Solaris 10ファイルシステムZFS誕生エピソード『心を解き放て！』 
* ZFS - FreeBSD Wiki
* Native ZFS for Linux
* OpenZFS