Skip to content

필사 모드: bcachefsがイレイジャーコーディングのexperimentalタグを外した話 — それが何を意味するか

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに — ドラマは終わり、問いは「では今どういう状態か」

bcachefsをめぐる話は、この2年間ほとんど人の話でした。誰が何を言ったか、どのプルリクエストがどの-rcで拒否されたか、メーリングリストで何があったか。その話はすでに十分消費されており、ここで繰り返すつもりはありません。

代わりに、エンジニアにとって実際に役立つ問いを立てます。2026年7月現在、bcachefsは技術的にどんな状態か? そして、その状態を知るためにはツイートやニュースの見出しではなく何を見ればよいのか?

結論から言うと、2026年で最も具体的な変化はイレイジャーコーディングがexperimentalタグを外したことです。そして、この事実を要約した一文がネットに出回っていますが、日付もバージョンも対象も間違っています。その一文がなぜ間違っているかを追う過程が本稿の半分を占めます — なぜなら、その過程こそが「タグを外した」という宣言をどう読むべきかをそのまま示しているからです。

まず事実関係から — カーネルから外れるまでの経緯

まず確認できる事実だけを整理します。カーネルのgitから直接確認したものです。

2025年8月28日。 リーナス・トーバルズがMAINTAINERSファイルの1行を修正します。コミットebf2bfec412a、追加1行削除1行。コミットメッセージは2文だけです — "MAINTAINERS: mark bcachefs externally maintained / As per many long discussion threads, public and private."。LWNは翌日これをBcachefs goes to "externally maintained"として取り上げ、当時はコードがカーネルに残ったままアップストリームのパッチだけ受けなくなる、という意味に読まれていました。

2025年9月29日。 リーナスがコード自体を削除します。コミットf2c61db29f277b9c80de92102fc532cc247495cd、284ファイル、追加0行削除117,483行。コミットメッセージ全文は次の通りです。

Remove bcachefs core code

bcachefs was marked 'externally maintained' in 6.17 but the code
remained to make the transition smoother.

It's now a DKMS module, making the in-kernel code stale, so remove
it to avoid any version confusion.

つまり削除の名分は感情ではなくバージョン混乱です — 「もうDKMSモジュールがあるので、カーネル内のコピーは古くなるだけだ。バージョン混乱を避けるために削除する」。LWNのBcachefs removed from the mainline kernel(Jonathan Corbet、2025年9月30日)がこのコミットを取り上げました。

検証は簡単です。カーネルタグv6.17fs/bcachefs/には260個の項目があり、v6.18にはそのディレクトリがありません(404)。本稿執筆時点のメインラインはv7.2-rc3で、その間どのリリースにも再び入っていません。

ここで順序が重要です。bcachefs-toolsリポジトリにDKMSサポートが入ったコミット(00ad9b1ed126、"add dkms support")は2025年9月10日です。削除コミットより19日早い。リーナスが「It's now a DKMS module」と書いたのは予言ではなく観察でした — 代替の配布経路がすでに存在していたからこそ削除できたのです。

DKMS移行、そして逆転した上下関係

プロジェクト自身の説明が最も簡潔です。bcachefs.orgのトップページにこう書かれています。

As of 6.18, bcachefs is no longer being distributed with the kernel, for reasons too complicated to go into here. (But it might have something to do with QA). So we're shipping as a DKMS module now. (Like ZFS!). The DKMS package supports Linux 6.16 and later.

「(Like ZFS!)」という括弧書きが、この状況の性格を的確にまとめています。ライセンス問題で永遠にツリー外にあるZFSと異なり、bcachefsはGPLですが、配布形態だけを見れば今や同じ立場に立ったことになります。

6.16という下限は、ベンダーのウェブページの主張ではなくコードで確認できます。dkms/dkms.conf.inにこう書き込まれています。

# kernels older than 6.16 are currently not supported
BUILD_EXCLUSIVE_KERNEL_MIN="6.16"

上限はありません。代わりにリリースノートが最新カーネルを追いかけます — v1.37.0は「Linux 7.0 support」、v1.38.7は「Builds against Linux 7.2」と記しています。カーネル7.2はまだrc段階であるにもかかわらずです。ツリー外モジュールが払うべき代償がまさにこれです — カーネル内部のAPIが揺れるたびに追随しなければならず、その作業がいまやリリースノートの定番項目になっています。

そして上下関係が逆転しました。bcachefs-toolsリポジトリのdoc/vendored-kernel-files.mdの冒頭の段落はこう述べます。

bcachefs source itself lives in fs/ and is developed in this repository directly — kernel-side fs/bcachefs/ is downstream of us now.

ファイルシステムのソースは今やtoolsリポジトリ内のfs/ディレクトリに置かれ、カーネル側はダウンストリームです。READMEによれば、scripts/install-to-kernel.shfs/をカーネルツリーのfs/bcachefs/にコピーし、CONFIG_BCACHEFS_FSでビルドできるようにします。方向がすっかり逆になったわけです。

2026年の本当のニュース — イレイジャーコーディングがタグを外した

ここからが本題です。

bcachefsのイレイジャーコーディング(EC)は、2023年11月からCONFIG_BCACHEFS_ERASURE_CODINGという独立したKconfigオプションの陰に隠れていました。コミットのタイトルがそのままです — "bcachefs: Put erasure coding behind an EXPERIMENTAL kconfig option"(6a673880f92b)。ファイルシステム全体が実験的だった時代でも、ECはそれよりさらに一段実験的なものでした。

それが2026年に変わりました。順序はこうです。

2026年2月2日。 コミットf42ccc690dd7 — "bcachefs: kill CONFIG_BCACHEFS_ERASURE_CODING"。Kconfigのゲートが消えます。今日のmasterのfs/Kconfigを取得してgrepすると、「ERASURE」は0件です。

2026年3月15日、v1.37.0。 リリースノートのハイライト最初の1行が宣言します。

- Erasure coding is no longer experimental; all the core functionality is
  complete.

同じリリースで新しいオンディスクのメタデータバージョンbcachefs_metadata_version_erasure_codingが入り、EC節はこう説明します — "Erasure coding is now hooked up to reconcile: degraded stripes are now automatically repaired, like other degraded data, and can be reshaped as needed."。つまり、破損したストライプが他の破損データとまったく同じようにバックグラウンドで自動修復される経路が付いた、ということです。ティアリング構成やサイズが混在したデバイス構成も動作するはずだと記されています。

これがニュースです。 そしてこのニュースの日付は2026年3月15日です。この日付を覚えておいてください。

広く出回った一文が間違っている3つの理由

このトピックを検索すると、こんな趣旨の一文に出会います — 「2026年6月17日、bcachefs-tools v1.38.6がexperimentalタグを外してリリースされた」。もっともらしく、日付もバージョンも具体的で、そして完全に間違っています。三重に間違っています。

第一に、バージョンが間違っています。 問題のコミットは8fc60dd30a8c、タイトルは「ec is not experimental」です。作成時刻は2026-06-18T01:58:15Zです。ところがv1.38.6タグは2026-06-17T19:03:36Zに打たれています。コミットはタグより約7時間遅れています。gitで確認すれば明確です — v1.38.6はこのコミットを含んでおらず、最初に含んだリリースはv1.38.7(2026年7月3日)です。v1.38.6のリリースノートは「Feature and performance release on top of v1.38.5. No on-disk format changes.」で始まり、「experimental」という単語は一度も出てきません。

第二に、規模が間違っています。 このコミットはファイル1つ(fs/opts.h)の文字列1行を直すだけです。それが全部です。

-	  NULL,		"Enable erasure coding (DO NOT USE YET)")	\
+	  NULL,		"Enable erasure coding (RAID5/6, but no write hole)")\

コミットメッセージの本文はたった4語です — "hasn't been for awhile."。ケント・オーバーストリート本人が「もうしばらく前からexperimentalじゃない」と言っているわけです。実際の宣言は3か月前のv1.37.0ですでになされており、6月のこのコミットはそれ以来放置されていたオプション説明文字列を後追いで直しただけの雑務です。マニュアルページ(bcachefs.8)はさらに長く放置されていました — そこの「DO NOT USE YET」が消されたのは6月30日のコミットc2b1c10fdd35("docs: clarify erasure coding replica limit")になってからです。同じコミットがfs/opts.hの文言も再度手直しし、12日間存在していた「RAID5/6, but no write hole」は現在の「Enable erasure coding (RAID5/6; data replicas are capped at 3)」に変わりました。

第三に、対象が間違っています。 そしてこれが一番重要です。タグを外したのはイレイジャーコーディングであってファイルシステムではありません。今日のmasterのfs/Kconfig冒頭はこうです。

config BCACHEFS_FS
	tristate "bcachefs filesystem support (EXPERIMENTAL)"
	depends on BLOCK

(EXPERIMENTAL)。2026年7月16日現在、bcachefsは自分のKconfigで自らを実験的だと呼んでいます。この行は最近手も付けられていません — fs/Kconfigの最終変更は2026年5月21日で、クォータのデフォルト値を変える無関係なコミットでした。

まとめるとこうなります。「あるサブシステムが実験タグを外した」が「ファイルシステムが実験タグを外した」に、「3月のリリース」が「6月のリリース」に、「含まれていないバージョン」が「含まれているバージョン」に、それぞれ一段ずつずれたのです。個々の歪みは小さくても、合わさると意味は反対側に行っています。

bcachefsのイレイジャーコーディングは実際にどう動くか

タグの話はここまでにして、タグが貼られていたもの自体を見てみましょう。プロジェクトのPrinciples of Operation(doc/bcachefs-principles-of-operation.tex)とEC実装ソース(fs/data/ec/create.c)のドキュメントコメントが一次ソースです。

基本的な骨組み。 bcachefsはReed-Solomonイレイジャーコーディングを使います — ほとんどのRAID5/6実装と同じアルゴリズムです。erasure_codeinode単位のオプションなので、set-file-optionで特定のディレクトリだけに有効化できます。ファイルシステム全体を作り替えなくてよいということです。冗長度はdata_replicasオプションから取られます。

  • data_replicas=1 — EC無効
  • data_replicas=2 — パリティブロック1個(RAID-5スタイル)
  • data_replicas=3 — パリティブロック2個(RAID-6スタイル)

パリティは最大2ブロックに制限されます。これがオプション説明にある「data replicas are capped at 3」の正体です — 任意の数字ではなく、Reed-Solomonのパリティ個数上限から出てきた値です。そしてメタデータのイレイジャーコーディングはサポートされていません。

write holeをどう避けるか。 ここが設計の核心です。PoOの説明を訳すと、従来のRAIDではwrite holeは深刻な問題です — ストライプ内の小さな書き込みがP/Qパリティブロックの更新を要求するのに、この書き込みをアトミックに行えないため、クラッシュがパリティを不整合な状態のまま残すと、同じストライプにある無関係なデータの再構成読み取りまで壊れてしまいます。ZFSはすべての書き込みを新しいストライプにすることでこれを避けますが、PoOはその代償として断片化が性能を損なうと指摘します — 断片化したデータの読み取りは最も遅い断片のレイテンシに縛られ、そのため中央値レイテンシがテールレイテンシ側に引きずられます。

bcachefsの答えは、COWを使って両方を避けることです。PoOの表現をそのまま使えば — その場更新が根本原因なのだからそもそも行わない、そしてextent単位のストライプはZFSと同じ断片化を招くのでバケット全体をエンコードする。

実装コメントが説明する書き込みパスは次の通りです。

1. フォアグラウンドの書き込みは普通に複製される (data_replicas=2なら複製2個)
2. reconcileスレッドがECの候補バケット(複製データが入ったバケット)を追跡
3. 候補が十分に溜まると、バックグラウンドのEC処理が:
   - データバケットを一まとまり取り (例: 無関係なデータが入ったバケット5個)
   - パリティバケットを割り当て (例: RAID-6スタイルなら2個)
   - データバケット群にまたがってReed-Solomonパリティを計算して書き込み
   - 元のバケットを指していたすべてのextentを更新:
       余分な複製ポインタを捨て、
       再構成読み取りが必要というフラグとともにパリティポインタを追加

コメントの結論はこう明快です — "This approach avoids the write hole entirely: parity is computed once for immutable data, and the extent updates are atomic btree operations."。パリティはすでに不変になったデータに対して一度だけ計算され、extentの更新はアトミックなbtree操作です。更新するパリティがないのだから、開く穴もありません。

代わりに付く制約。 タダではありません。コメントはストライプの寿命をこう説明します — バケットが一つのストライプにまとめられると、そのストライプ内のすべてのデータが死ぬか移動するまで、そのどのバケットも再利用できません。copygcはこの制約を把握していて、ストライプが断片化するとストライプ全体を空にします — 生きているデータを新しいバケットに書き直し、古いストライプを回収する形です。つまりwrite holeを避けた分をバックグラウンドの書き込み増幅で支払っているわけです。

読み取りパスは平凡です。ECポインタの付いたextentを読むとき、まずデータバケットを直接読み、失敗すると(デバイスがオフライン、チェックサムエラー)、再構成読み取りに切り替えて生き残っているデータバケットとパリティバケットを集め、Reed-Solomonで復元します。

「タグを外した」に付随した注記

ここからは正直になる部分です。v1.37.0のEC節は「no longer experimental」だけで終わっていません。その次の項目はこうです。

Erasure coding is no longer hidden behind CONFIG_BCACHEFS_ERASURE_CODING, but one significant item is still remaining - stripe allocation needs to allocate blocks on different devices at similar LBAs, to avoid seeking when resilvering an array. This should land in 1.38.

訳すと — ゲートはなくしたが、重要な項目が1つまだ残っている。 ストライプ割り当てが複数のデバイスで似たLBAにブロックを確保しないと、アレイをリシルバリングするときにシーク(seek)が発生してしまう。これは1.38に入る予定だ。

では、1.38に入ったのでしょうか?

入っていません。 v1.38.0(4月19日)からv1.38.8(7月3日)まで、リリースノートのどこにもこの項目はありません。該当する作業と思われるコミットは6cf75ca7c70f — "ec: allocate stripe blocks near the stripe's centroid"、作成時刻2026-07-04T17:45:18Zfs/data/ec/create.cに48行追加6行削除です。v1.38.8タグ(2026-07-03T19:15:42Z)より1日遅い。gitで確認するとv1.38.8はこのコミットを含んでいません。2026年7月16日現在、この作業はmasterにのみ存在し、どのリリースにも入っていません。

しかもそのコミット自体が自ら未完だと述べています。最後の段落はこうです — "Outlier reallocation - fixing up early blocks when the centroid settles elsewhere - follows in the next patch."。重心が後で別の場所に落ち着いたときに初期のブロックを直す作業は次のパッチに持ち越されています。

この問題がなぜ3月には「1.38に入る予定」だったのに7月までずれ込んだのかも、コミットメッセージにヒントがあります。素朴なアプローチ — ブロックの生のオフセットの平均を目標にする方式 — はむしろ状況を悪化させたそうです。コミットメッセージによれば、その方式はすべてのブロックを同じ絶対バケット番号に収束させてしまいシーク局所性をまったく与えず、しかもアロケータの比例充填(proportional fill)と衝突します。著者が挙げた例は1G/2G/4G/8Gのデバイスを混在させたテストで、1Gデバイスが26%埋まる間、8Gの相方は3%にとどまり、小さいデバイスの空き容量に穴を開けて早期ENOSPCの方向へ押しやったとのことです。(著者自身の測定であり、特定のテスト構成での観察であり、採用された設計ではなく却下された代案の失敗を説明する数字です。ベンチマークとして引用できる値ではありません。)そのため採用されたのは、生のオフセットではなくデバイスごとの位置比率の平均を重心とする方式です — ストライプはサイズの異なるデバイスをまたぐため、同じオフセットでもデバイスごとに違う位置になるからです。

まとめると、3月に「残る項目が1つ」と記されていたものは、実は設計上の落とし穴がある問題だったとわかり、7月中旬現在で部分的な解法がmasterに入ったばかりで、その解法自体も後続パッチを予告している、というのが実情です。

では今これをどう扱うべきか

ここまでの事実を実務的な判断に落とし込むとこうなります。

「no longer experimental」が実際に保証すること。 中核機能が完成しており、独立したビルドゲートの陰に隠れておらず、破損したストライプが自動修復経路につながり、オンディスクのフォーマットバージョンが割り当てられたということ。これは本物の前進であり、リリースノートの主張はコードでそのまま確認できます。

保証しないこと。 プロジェクト自身が明示した未完項目がない、という意味ではありません — リシルバー時のシーク局所性の作業はまだリリースされていません。そしてファイルシステム全体の成熟度についての言明ではなおさらありません。BCACHEFS_FSは今日も(EXPERIMENTAL)のままです。

使うべきでないとき。

  • 取り戻せないデータを載せるとき。 ファイルシステムが自らを実験的と呼んでいる間は、バックアップがあり、そのバックアップから復元したことのあるデータだけを載せるのが正しい態度です。これはbcachefsをけなす話ではなく、プロジェクト自身のKconfigをそのまま読んだだけです。
  • リシルバー時間がSLOであるアレイ。 よりによって、まだリリースされていない作業がまさにその点を狙っています。大きな回転ディスクのアレイでECを使い、デバイス交換にかかる時間が重要なら、今はその改善がないバージョンを使うことになります。
  • カーネルを自由に選べない環境。 DKMSは6.16以上を要求します。エンタープライズディストリビューションの固定された古いカーネルを使っているなら選択肢になりません。そしてツリー外モジュールなので、カーネルを上げるたびに再ビルドが発生し、セキュアブートを使っているならモジュール署名が別途の関心事になります(v1.38.7で署名サポートと事前ビルド済みモジュールの配布が入りました)。
  • メタデータまでECで節約しようともくろむとき。 サポートされていません。容量計算をそう組んでいたなら、やり直す必要があります。

試す価値があるとき。 上の条件をすべて読んだうえで問題なければ — バックアップ済みのデータ、柔軟に選べるカーネル、リシルバー時間の余裕 — EC自体の設計は真剣に魅力的です。バケット単位のバックグラウンドエンコーディングでwrite holeなしにRAID5/6級の空間効率を得つつ、ZFS流のストライプ断片化を避けるという組み合わせは、成立するなら実際に新しい立ち位置です。そしてinode単位のオプションなので、コールドデータのディレクトリだけで試すといった段階的な導入も可能です。既存のファイルシステムとの一般的な比較はext4・XFS・ZFS・btrfs深掘り比較の回にまとめてあります。

おわりに

2つのことを持ち帰ってもらえればと思います。

第一に、bcachefsの2026年はドラマではなくエンジニアリングです。 カーネルから117,483行が抜けたのは2025年9月のことで、それ以降プロジェクトはDKMSで配布されながらリリースを出し続けています — Changelog.mdwnで2026年の日付が付いたリリース項目はv1.35.0(1月12日)からv1.38.8(7月3日)まで20個です。カーネルのソースがtoolsリポジトリに移ってカーネル側がダウンストリームになり、リリースノートはrc段階のカーネルまで追いかけます。これは安定した運用であって、漂流ではありません。

第二に、「experimentalを外した」という文はいつも3つを問い直すべきです — 何が(ファイルシステムかサブシステムか)、いつ(どのリリースノートが宣言したか)、そして残っている注記は何か。この事例では、3つの問いへの答えはそれぞれ「イレイジャーコーディングのみ」「2026年3月15日のv1.37.0」「リシルバーのシーク局所性 — まだ未リリース」でした。ネットに出回っている要約はこの3つとも取りこぼしています。

そして、これを突き止めるのに特別なアクセス権は必要ありませんでした。公開されているgitタグの日付、コミット1つのdiff、Changelog.mdwnfs/Kconfigファイル1つで十分でした。要約を引用する前にタグの日付を一度確認する習慣 — 本稿から持ち帰るものが一つあるとすればそれです。この誠実さは、プロジェクト自身が先に示していたことでもあります。「no longer experimental」と「one significant item is still remaining」を同じリリースノートの連続する2つの段落に並べて書いたのは、ケント・オーバーストリート本人なのですから。注記を消したのはプロジェクトではなく、それを伝えた人々の方でした。

参考資料

현재 단락 (1/96)

bcachefsをめぐる話は、この2年間ほとんど人の話でした。誰が何を言ったか、どのプルリクエストがどの-rcで拒否されたか、メーリングリストで何があったか。その話はすでに十分消費されており、ここで繰...

작성 글자: 0원문 글자: 12,696작성 단락: 0/96