DragonFly - VFS/filesystem Device Operations ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ The New VFS Model 新しい VFS モデル Fixing the VFS subsystem is probably the single largest piece of work we will be doing. VFS has two serious issues which will require a lot of reworking. First, the current VFS API uses a massive reentrancy model all the way to its core and we want to try to fit it into a threaded messaging API. Second, the current VFS API has one of the single most complex interfaces in the system... VOP_LOOKUP and friends, which resolve file paths. Fixing VFS involves two major pieces of work. おそらく VFS サブシステムを修正することは私達が取り組む作業の中では最大の ものです。 VFS には多くの作業が必要となるであろう、2つの深刻な問題がありま す。第一に、現在の VFS の API は、大規模な再入モデルをそのコア部分にまで幅 広く使っており、私達はスレッド化されたメッセージング API へそれを適合させ ることを望んでいます。第二に、現在の VFS の API はシステムの中で最も複雑な インターフェースのひとつを持っています ... 例えば、ファイルパスを解析する VOP_LOOKUP 等。 VFS を修正するには主に 2つの作業が必要です。 First, the VOP_LOOKUP interface and VFS cache will be completely redone. All file paths will be loaded in an unresolved state into the VFS cache by the kernel before ANY VFS operation is initiated. The kernel will recurse down the VFS cache and when it hits a leaf it will start creating new entries to represent the unresolved path elements. The tail of the snake will then be handed to VFS_LOOKUP() for resolution. VFS_LOOKUP() will be able to return a new VFS pointer if further resolution is required. For example, it hits a mount point. The kernel will then no longer pass random user supplied strings (and certainly not using user address space!) to the VFS subsystem. 第一に、VOP_LOOKUP のインターフェースと VFS キャッシュは完全に再修正される 予定です。全てのファイルパスはいかなる VFS の動作がはじまるよりも前にカー ネルによって VFS キャッシュの中に未解決の状態のまま読み込まれるようになる でしょう。カーネルは VFS キャッシュ を再帰的に検索し、要素に当たった時に未 解決のパスの要素を表現するために新しいエントリを作りはじめるでしょう。蛇の 尾はその次に変換(:?)のために VFS_LOOKUP() によって掴まれることになります。 もしさらなる変換が必要となっても、VFS_LOOKUP() は新しい VFS ポインタを返す ことが可能になるでしょう。例えば、それはマウントポイントにも当てはまります。 カーネルはもはや VFS サブシステムに対しユーザが提供したランダムな文字列(そ してユーザアドレス空間を使用することはなくなります)を渡すことはなくなりま す。 Second, the VOP interface in general will be converted to a messaging interface. All direct userspace addresses will be resolved into VM object ranges by the kernel. The VOP interface will NOT handle direct userspace addresses any more. As a messaging interface VOPs can still operate synchronously, and initially that is what we will do. But the intention is to thread most of the VOP interface (i.e. replace the massive reentrancy model with a serialized threaded messaging model). For a high performance filesystem running multiple threads (one per cpu) we can theoretically achieve the same level of performance that a massively reentrant model can achieve. However, blocking points, such as the bread()'s you see all over filesystem code, would either have to be asynchronized, which is difficult, or we would have to spawn a lot more threads to handle parallelism. Initially we can take the (huge) performance hit and serialize the VOP operations into a single thread, then we can optimize the filesystems we care about like UFS. It should be noted that a massive reentrancy model is not going to perform all that much better then, say, a 16-thread model for a filesystem because in both cases the bottleneck is the I/O. As long as one thread is free to handle non-blocking (cached) requests we can achieve 95% of the performance of a massive reentrancy model. 第二に、一般的に VOP インターフェースはメッセージインターフェースに変換さ れることになる予定です。直接ユーザ空間のアドレスはカーネルによって VM オブ ジェクトの範囲の中で解決されるでしょう。 VOP インターフェースは直接ユーザ 空間のアドレスをそれ以上扱いません。メッセージインターフェースとしての VOP はまだ同期的に動作することができますし、それが私達がはじめにしようと考えて いることです。しかし、われわれの狙いは VOP インターフェースの大部分をスレ ッドとして動作するようにすることです(例えば、大規模な再入可能モデルをシリ アライズされスレッド化されたメッセージモデルによって置き換える)。複数のス レッド(1CPU につきひとつ)が走る高性能ファイルシステムでは、理論上、大規模 な再入可能モデルが実現できるものと同じレベルの性能を実現することが可能です。 しかしながら、全てのファイルシステムのコードで見られる bread() のような扱 いにくいブロッキングポイントは非同期的でなくてはならないか、あるいは並列処 理を扱うために更に多くのスレッドを生成しなければならないのです。はじめに私 達は(莫大な)性能を達成しひとつのスレッドの中で VOP の動作をシリアライズし、 次に UFS のように配慮するファイルシステムを最適化できるようになります。大 規模な再入可能モデルはファイルシステムに対して、 16スレッドモデルよりよく 機能することはありません(:?)。なぜなら、双方の場合で I/O がボトルネックに なるからです(:?)。ひとつのスレッドがノンブロッキングな(キャッシュされた)要 求を扱う限り、大規模な再入可能モデルの 95% の性能を実現することが可能です。 A messaging interface is preferable for many reasons, not the least of which being that it makes stacking actually work the way it should work, as independant and opaque elements which stack together to form a whole. For example, with the new API a capability layer could be slapped onto a filesystem that otherwise doesn't implement one of its own, and the enduser would not know the difference. Filesytems are almost universally self-contained entities. A message-based API would allow these entities to run in userspace for debugging or even in a deployment when one absolutely cannot afford a crash. Why run msdosfs or cd9660 in the kernel and risk a crash when it would operate just as well in userland? Debugging and filesystem development are other good reasons for having a messaging API rather then a massively reentrant API. メッセージインターフェースは多くの理由から望ましく、それが実際に作業を保存 (:stacking?)することを行うことだけでなく、独立し全てを形成することと共に保 存(:stack)するあいまいな要素です(:?)。例えば、新しい API では、機能層(:?) はそれ自身に実装されていない他のファイルシステムを置くことが可能になり、ま たエンドユーザはその違いを知る必要がありません。ほとんどのファイルシステム は一般的にそれ自身を含む実体です。メッセージベースの API は、デバッグのた めにそれをユーザ空間で、あるいは確実にクラッシュを提供することができない時 の配置で動作することを、それらの実体に許可します。ユーザランドで動作するこ とが好都合なときに、なぜ msdosfs や cd9660 はカーネル内で動作し、クラッシ ュの危険性を負わなければならないのでしょう。デバッグやファイルシステムの開 発では、大規模な再入可能 API より、メッセージ API を持つための他のよい理由 があるのです。