Linux向けのCopy-on-Write(CoW、書き込み時にコピーを作る方式)ファイルシステムBtrfsに、DirectI/O書き込みのスループットを約59%引き上げる修正が入る。変更点はわずか1行だ。MetaのエンジニアMark Harmstone氏が、2023年の新マウントAPI移行時にあるフラグが誤って外れ、同一ファイルへの書き込みが2年以上にわたって直列化され続けていたことを突き止めた。リファクタリングが静かに招いた性能低下の修正は、6月にマージウィンドウを迎えるLinux 7.2に取り込まれる見込みだ。

AD

Linux 7.2に向かう「1行」の変更

今回の変更は、Btrfsが DirectI/O(DIO、ダイレクトI/O)書き込みを強制的に直列化(シリアライズ)するのをやめる、というものだ。直列化とは、複数の書き込み要求を1つずつ順番に処理することを指す。これをやめれば、同じファイルへの複数の書き込みが並行して進めるようになる。

効果は数字に表れている。Harmstone氏の検証環境では、DirectI/O書き込みのスループットが826 MB/sから1311 MB/sへ、およそ59%向上した。Intelが運用する自動テスト基盤Kernel Test Robotも、別のハードウェアで約12%の改善を報告している。後述するように向上幅は環境やワークロードに左右されるが、1行の修正で得られる利得としては十分に大きい。

注意すべきは、これが新機能の追加ではなく「リグレッション(性能後退)の修正」である点だ。Btrfsはかつて正しい挙動を備えていたが、数年前のある変更でそれを取りこぼしていた。今回の修正は、本来あるべき性能を取り戻す作業にあたる。パッチはすでに次期開発版を集約する「-next」ツリーに投入されており、6月のマージウィンドウを経てLinux 7.2に入る見込みである。

なぜDirect I/O書き込みが直列化されていたのか?SB_NOSEC脱落の仕組み

ここからは、なぜ書き込みが常に直列化されていたのかを順に追っていく。

まずDirectI/Oとは、カーネルのページキャッシュ(メモリ上の書き込みバッファ)を経由せず、ストレージへ直接データを読み書きする方式を指す。データベースのように、自前でキャッシュを管理し、OSの二重キャッシュを避けたいアプリケーションが好んで使う。

問題は、Btrfsが DirectI/O書き込みを行う際にかける「inode(アイノード、ファイルのメタ情報を管理する構造)ロック」にあった。ロックには排他(exclusive、1つの書き込みだけが進める)と共有(shared、複数が並行できる)の2種類がある。Btrfsは本来、条件が整えば共有ロックで済ませられるが、2023年以降は常に排他ロックを取得していた。その結果、同じファイルへのDirectI/O書き込みは1つずつしか進めず、直列化されていたのだ。

なぜ常に排他ロックになっていたのか。鍵を握るのがSB_NOSECというスーパーブロック(ファイルシステム全体の管理情報)のフラグである。Harmstone氏は次のように説明している。

Btrfsが2023年に新マウントAPIへ切り替わる前は、btrfs_mount_root() の中でSB_NOSECを設定していた。このフラグは「セキュリティ拡張属性(xattr)を持たないファイルがあり得る」とVFS(Virtual File System、カーネル内でファイルシステムを抽象化する層)に伝え、VFSがいくつかの最適化を行えるようにする。残念ながら移行時にこの設定が抜け落ちており、btrfs の inode に対してIS_NOSECが常にfalseを返すようになっていた。これにより btrfs_direct_write() は常にinodeロックを排他的に取得し、同じファイルへのDirectI/O書き込みが直列化されていた。

整理すると、因果は次のようにつながる。新マウントAPIへの移行でSB_NOSECの設定が脱落 → 判定関数IS_NOSECが常にfalseを返す → 書き込み処理btrfs_direct_write() が毎回排他ロックを取得 → 同一ファイルへの並行書き込みが直列化、という連鎖だ。修正は、この脱落した1行分の設定を元に戻すだけで済む。原因の特定こそ難しかったが、対処そのものは最小限だった。

AD

59%という数字をどう読むか

向上幅をどう受け止めるべきか。まず押さえておきたいのは、826 MB/sから1311 MB/sという数値がHarmstone氏個別の環境で測られたものであり、すべての環境で59%が再現されるわけではないことだ。IntelのKernel Test Robotが示した約12%という数字との開きは、ハードウェアやテスト内容の違いを反映している。向上幅は使うストレージ、スレッド数、書き込みパターンに依存する。

それを踏まえたうえで、誰が恩恵を受けるのかを考えると輪郭がはっきりする。今回効くのは「同一ファイルに対して複数スレッドが並行してDirectI/O書き込みを行う」場面だ。これは抽象的な条件に見えるが、実際にはデータベースが典型例にあたる。多くのデータベースエンジンは、巨大なデータファイルへO_DIRECT(DirectI/Oを要求するフラグ)で書き込み、複数の接続やワーカースレッドから同時に更新をかける。直列化が外れれば、こうした並行書き込みがそのまま並列で流れるようになる。

逆に、単一スレッドで順番に書き込むワークロードや、そもそもページキャッシュ経由の通常の書き込み(バッファードI/O)には、今回の変更は影響しない。あくまで「DirectI/Oかつ同一ファイルへの並行書き込み」という条件下での改善である点は、過度な期待を避けるためにも明確にしておきたい。

2年間気づかれなかったリグレッションが映すもの

この一件には、単なる性能改善以上の含意がある。まず、成熟したコードベースにも性能リグレッションは静かに潜むという事実だ。Btrfsは十分にテストされた主要ファイルシステムでありながら、機能上は何も壊れていなかったため、約2年間この後退は見逃され続けた。クラッシュやデータ破損を伴わない性能劣化は、誰かが実測して比較しない限り表面化しにくい。

次に、リファクタリングが落とし穴になり得ることだ。今回の原因は新マウントAPIへの移行という、いわばコードを整えるための作業だった。インターフェースを刷新する過程で、SB_NOSECを立てるという一見些細な1行が抜け落ちた。挙動を変えないはずの変更が、実際には性能を左右する設定を取りこぼしていたわけである。

発見者がMetaのエンジニアであることも示唆に富む。Metaはbtrfsを大規模な本番環境で運用し、長年にわたり主要なコントリビュータであり続けてきた。実環境で大量のDirectI/O書き込みを扱う立場だからこそ、本来あるべきスループットとの差に気づけたとも言える。性能の番人は、その性能に最も依存する利用者であることが多い。

そして見落とせないのが、この利得が「ほぼ無償」である点だ。新しいアルゴリズムやハードウェアを必要とせず、過去の正しい挙動に戻すだけで数十%のスループットが返ってくる。カーネル開発の世界では、派手な新機能だけでなく、こうした地味な原状回復が実利用者に最も近い恩恵をもたらすことがある。

AD

本来あるべき性能を取り戻す

BtrfsのDirectI/O書き込みを直列化していた原因は、2023年の新マウントAPI移行で脱落したSB_NOSECフラグという、たった1つの設定だった。それを元に戻す1行の修正で、同一ファイルへの並行書き込みが解放され、検証環境では約59%のスループット向上が得られている。

この修正はすでに-nextツリーに入っており、6月のマージウィンドウを経てLinux 7.2に取り込まれる見込みだ。Linux 7.2の安定版リリースは2026年8月末頃が見込まれている。FedoraやopenSUSEのようにBtrfsを標準採用するディストリビューション、あるいはLinux 7.2を同梱予定のUbuntu 26.10などでBtrfsを使う読者は、いずれこの改善を意識せずとも受け取ることになる。派手さはないが、自分の使う基盤がどこで速くなっているのかを知っておくことは、性能を読む目を養ううえで小さくない手がかりになるはずだ。