web-dev-qa-db-ja.com

ファイルシステムは、OSに移植可能な方法で設計および実装できますか?

主要なOS(Windows、macOS/OS X/Mac OS X、Linux)がファイルシステムに提供するインターフェイスを考えると、ファイルシステムはOSに大きく依存しない方法で設計および実装できますか?

私はファイルシステムの専門家ではありませんし、実装したこともありませんが、ファイルシステムの熱心なユーザーです。私の素朴な期待は、ほとんどすべてのファイルシステムロジックがオペレーティングシステムから独立していることです。 OSはC互換の方法でファイルシステムにパスについてクエリを実行し、ファイルシステムはC互換の方法で応答します。深い相互依存性は必要ありません。実際には、そうではないようです。たとえば、WindowsまたはmacOSを使用しているときにext2/3/4ファイルシステムから読み取るだけでは、ユーザーの観点からかなりの労力がかかります。

ファイルシステムがオペレーティングシステムと深くかかわっているように見える技術的な理由はありますか?主要なOSは、基本的に互換性のない方法でファイルシステムと相互作用しますか?または、これは主に法的問題によるものですか?あるいは、質問の前提に欠陥があり、ポータブルファイルシステムに対する需要がまったくないのでしょうか。

(ほとんどのOSはOSカーネル自体にコアファイルシステムドライバーを組み込んでいますが、ほとんどの場合、ロード可能なOSモジュールが新しいファイルシステムを記述できるようにしていますので、問題が残っています:主にOSであるファイルシステムのOSモジュールがないのはなぜですか?独立していますか?)

専門家ではないので、私はいくつかの詳細について間違っているかもしれません。たとえば、WindowsとmacOSがext2/3/4ファイルシステムを読み書きできるツール/拡張機能doは、Linuxカーネルと多くのコードを共有します。その場合でも、良い答えはapparentの難しさと、他のOS +ファイルシステムの組み合わせがそれほど簡単ではない理由を説明するはずです。

編集:明確にするために、私はABIレベルでの非互換性について尋ねていません。多くの特殊性がABIレベルで問題を作成する可能性があり、ほとんどはこの質問に固有ではありません。この質問は、主要なOSによってファイルシステムに提供されるAPIに基本的に互換性がないかどうかについてです。

3
Praxeolitic

あなたの質問に対する答えが「はい」と「いいえ」の両方であることを示す例を挙げます。Fuse

ヒューズはFilesystem in Userspaceの略です。 FuseはLinuxカーネルのファイルシステムドライバーで、実際にはファイルシステムを実装していません。代わりに、抽象化レイヤー、API、およびユーザースペースからFuseカーネルドライバーと対話するためのプロトコルをエクスポートするABIを提供します。 Fuseの2番目のコンポーネントは、そのプロトコルのAPIラッパーを実装するユーザー空間ライブラリです。

これらすべての最終結果として、libfuseライブラリにリンクして必要なコールバックを実装することにより、ユーザースペースにファイルシステムドライバーを記述できます。また、考えられるほとんどすべての言語に対応する言語バインディングのセットがあるため、たとえば、Python、Ruby、PHP、ECMAScript、Java、C♯、Scala、および考えられるあらゆる言語でファイルシステムドライバーを作成できます。

さて、それはこの質問とどう関係しているのでしょうか?まあ、Fuseカーネルユーザー空間プロトコルとFuseライブラリは他のオペレーティングシステムにも実装されており、FuseライブラリAPIのサブセットに対して記述されたコードは、ほとんどのオペレーティングシステム間で移植可能です。したがって、その意味では、あなたの質問に対する答えは「はい、ファイルシステムドライバーは移植可能な方法で実装できます」です。

だが!これが問題です。または、実際には2つのキャッチがあります。まず、ヒューズ自体はかなり複雑です。たとえば、kernel-userspaceプロトコルを実装するLinuxカーネルファイルシステムドライバーは9000行です。 macOSカーネルファイルシステムドライバーは17000行を超えています。そして、ユーザースペースファイルシステムドライバーが書き込むAPIを実装するユーザースペースライブラリは、別の10000行です。つまり、これは36000行のコードであり、LinuxとmacOSの違いをスムーズにするためのものです。覚えておいてください。これらの36000行は実際には何もしません。 APIに対して作成されたFuseユーザースペースファイルシステムドライバーがmacOSおよびLinuxで実行できるように、これらは共通APIのみを実装します。

また、たとえば、Windows用のポートはありません。ただし、Windowsには同様のプロジェクトがあり、そのいくつかはFuseの互換性レイヤーを提供しています。ただし、WindowsファイルシステムドライバーのアーキテクチャーがUnixファイルシステムドライバー(LinuxとmacOSの両方の派生元)とはあまりにも異なるため、これらの互換性レイヤーは通常完全ではありません。

2つ目の問題は、Fuseファイルシステムが遅くなる傾向があることです。現在、その一部は、ユーザー空間に実装されており、カーネルとユーザー空間の境界を越えるにはコストがかかるためです。しかし、その一部は、Fuseがブロックレイヤー、I/Oスケジューラー、ファイルシステムキャッシュ、さまざまなゼロコピー実装などの重要なOS固有の多くの要素を抽象化するためでもあります。また、Fuseはそれらを抽象化するため、Fuseユーザースペースファイルシステムはそれらを利用できません。

つまり、要約すると、Fuse(またはFuseを使用して実装されたさまざまなファイルシステム)は、OS間の違いを抽象化するAPIを設計することが可能であることの存在証明です。しかし、いいえ、ファイルシステムドライバーはnot "オペレーティングシステムに依存しないほぼすべてのロジック"です。 Fuseを見ると、オペレーティングシステムごとに〜10000〜〜20000行のカーネルコードと、ユーザー空間ライブラリに追加の〜10000行のコードが必要です。これにより、OSに依存しないファイルシステムを作成できる抽象化レイヤーを作成できます。マナー。実際のファイルシステム自体は通常、はるかに小さいです。たとえば、Fuseベースのsshfsはわずか3000行のコードです。つまり、OSに依存しないコードの最大3000行と、OSに依存するコードの最大10000〜20000行です。そして、実用性に対するもう1つの「いいえ」:この方法で高性能ファイルシステム実装を作成することはできません。

ZFSはもう1つの興味深いケーススタディです。通常、ほとんどのUnixライクなOSには、同様の階層化を持つファイルシステムの階層化された実装があります。下部に物理ブロックデバイス、中央に論理ブロックデバイス(RAID)、上部にファイルシステム。 1つのファイルシステムは1つの論理ブロックデバイス上にあり、1つの論理ブロックデバイスは1つ以上の物理ブロックデバイス上にあります。 ZFSのレイヤーは完全に異なります。ストレージプールとファイルシステムの2つのレイヤーしかありません。境界は、従来の階層化スキームの中間層となるものの中間にあります。ファイルシステムはストレージプールから動的にスペースを割り当てます。1つのファイルシステムは複数のストレージプールに存在でき、1つのストレージプールは複数のファイルシステムをホストできます。これには、Solarisカーネルに大幅な変更を加える必要がありました。さて、ZFSがOSの大幅な変更を必要とする場合でもそれが設計されたためなら、何も変更せずにLinuxまたはWindowsに移植することはできないと想像できます。

あなたの主な問題はあなたのファイルシステムの見方があまりにも単純すぎるということだと思います:

OSはC互換の方法でファイルシステムにパスについてクエリを実行し、ファイルシステムはC互換の方法で応答します。深い相互依存性は必要ありません。

うーん。これはかなり退屈なファイルシステムです。どうして?さて、ディスクにアクセスするファイルシステムについては何も書きませんでした。現実の世界では、ファイルシステムはディスクまたはRAIDから読み書きする必要があります。または、ネットワークファイルシステムの場合はネットワーク。 OSのファイルシステムキャッシュとやり取りする必要があります。 OSのブロックキャッシュとやり取りする必要があります。 OSのI/Oスケジューラと対話する必要があります。 OSの仮想メモリシステムと対話する必要があります(mmapなどの場合)。 Linuxでは、Linux仮想ファイルシステムスイッチ(VFS)と相互作用して適合する必要があります。ユーザー、権限、役割、属性、セキュリティコンテキスト、ドメイン、アクセス制限、ACL、ポリシーなどがあります。たとえば、これらはUnixとWindowsでまったく異なります。

たとえば、WindowsとmacOSがext2/3/4ファイルシステムを読み書きできるツール/拡張機能は、Linuxカーネルと多くのコードを共有します。

Linuxカーネルではありません。違います。ただし、Linux Ext開発者は実際にロックステップでのExtの実装2、Linuxカーネルファイルシステムドライバー、およびユーザースペースであるlibext2fse2fsprogsの一部)を開発しています。 ext2/3/4のサポート(ほとんどが読み取り専用)を実装するライブラリ(そしてdebugfse2fscktune2fsmke2fsなどのツールによって使用されます)。そしてserlevel WindowsおよびmacOSで利用可能なツールcould必要に応じてこのライブラリを使用します。

5
Jörg W Mittag

はい、可能です。通常、そうではない理由は、さまざまなOSを制御している人々が、他のプラットフォームとの互換性に興味がないことが多いためです。 Linuxには、NTFSを含むさまざまなファイルシステム用のドライバーがあり、Windows用のext2/3ドライバーもあります。

MicrosoftがNTFSを作成したのは、FAT32にはなかった、アクセス制御リストによる包括的なセキュリティ機能が必要だったためです。彼らはそれを実装し、ウィンドウにプラグインして、完了しました。 競合するオペレーティングシステムのニーズを気にする理由はありませんでした。最終的には、他の人々が他のオペレーティングシステム用のNTFSドライバを作成し、今日多くのシステムで使用されています。

あなたの疑い:

あるいは、質問の前提に欠陥があり、ポータブルファイルシステムに対する需要がまったくないのでしょうか。

主に何が起こっているかです。

最終的に、ディスクは任意のバイトの巨大な文字列と見なすことができ、それらのバイトの読み取りと書き込みは、基本的には個々のファイルのバイトの読み取りと書き込みと同じです。 NTFSにはWindowsを必要とするものは何もありません。データ構造の知識があるだけなので、一般的なファイルアクセスメソッドを提供するドライバーを作成できます。他のファイルシステムと同じです。

ファイルシステム仕様の機密性により、これらのドライバーの作成が難しくなる可能性がありますが、これは技術的な制限ではありません。

あなたの質問は、 "なぜ私はGMトヨタ車にウォーターポンプを置くことができないのですか?"に相当しますGMとトヨタのウォーターポンプは、各企業が競合他社の部品との互換性を気にしていないだけです。彼らは積極的にそれを回避することがありますが、通常は無関心で十分です。

4
whatsisname

それは可能ですが、これは常に完全に望ましいとは限りません。 POSIX(Portable Operating System Interface)は、ファイルシステムから期待される動作と、OSに移植できるAPIを定義します。

問題は、ファイルシステムを設計するときに、通常、最適化する一連のワークロードがあり、場合によってはPOSIXセマンティクスによってこの最適化が困難になることです。

分散ファイルシステムの場合:ネットワークを介して同じファイルにアクセスしている複数のユーザーがいて、ファイルが開いている間に開いているファイルを自分のコンピューターにキャッシュしたい。 POSIX準拠のファイルシステムでは、一部のユーザーによって行われたファイルの変更は、今後の読み取りですべてのユーザーに表示されます。複数のユーザーが同じファイルに同時にアクセスすることは、ほとんどのワークロードでは非常に珍しいため、POSIXのセマンティクスを緩和して、この最適化を可能にしたり、システムを簡略化したりしたい場合があります。

ファイルシステムを作成するとき、予想されるワークロードの実行を高速化したり、アーキテクチャを簡素化したりするために、特定のケースでインターフェイスまたは特定の操作のセマンティクスを変更しようとするいくつかのトレードオフが現れます。

0
Daniel Mitre