HN 日本語サマリー

← 一覧へ戻る
プログラミング

F*ファイルシステム – OSカーネルをバイパスしてSSDを直接読み込むファイル検索

F* file system – file search that reads SSD directly bypassing OS kernel (github.com)

89 pointsby neogoose44 コメント

要約

FFSは、OSカーネルを介さずにディスクを直接読み込むことでファイルを検索するCLIツールです。これは実用性よりも面白さに重点を置いており、特に大規模なファイル検索において既存のツール(ripgrepなど)よりも高速になる可能性があります。macOSではSIPの無効化が必要な場合もありますが、非マウントボリュームの検索も可能です。

全文翻訳

FFS - F*ファイルシステム これは、OSカーネルを使ってファイルを読み込まず、ディスクを直接読み込むことでファイルを検索する(grepのような)CLIツールです。実用性はほとんどありませんが、とてつもなくクールです。 これはたった約1.5k行のCコードで、次のことを行います。 生のデバイスノード(例: /dev/rdisk*)を読み取る場合にのみsudoが必要 イメージファイルを検索するのに管理者権限は不要 macOSのメインディスクで実行するにはSIP保護を無効にする必要がある 一部の最近のファイル書き込みを見落とす可能性がある(手動でのsync呼び出しが必要) OS内で他のシステムコンポーネントがファイルを書き込んでいる間、非常に揮発性の高いファイルシステム上でツリーを検索できない可能性がある このプロジェクトで手動で実装されたファイルシステムでのみ動作 しかし同時に、ディスクから直接ブロックを読み取る VFS/バッファリングされたread()パスをバイパスし、代わりにブロックデバイスを直接preadする ripgrepよりも漸進的に高速(検索する必要があるファイルが多いほど、ripgrepよりも高速になる) アンマウントされたボリュームを検索できる - バイナリBLOBを解析するだけ バイナリファイルを検出し、スキップする OpenMPを介してすべてのコアに負荷を分散 Linuxでサポートされているファイルシステム ほとんどすべてのファイルシステムは簡単に実装できます Ext4 ./fs/ext4.c これはサポートが最も簡単なファイルシステムです。インプレースで書き込むジャーナリングファイルシステム(コピーオンライトなし)であるため、ほとんどの場合、ffsにとって最適なファイルシステムです。ffsがファイルの最近の更新の一部を確認できない場合がありますが、これはカーネルが最近の更新をキャッシュに保持し、ディスクへの書き込みを遅延させている場合に発生する可能性があります。syncを使用して同期を強制できます。 Btrfs ./fs/btrfs.c B-treeファイルシステムははるかに複雑で、より効率的なファイルストレージであり、追加の制限があります。ファイルシステム上の任意のファイルが更新されると、スーパーブロック全体も更新が必要になります。つまり、ffsがスーパーブロック(高レベルBツリー)を読み取った後、カーネルがツリーを更新すると、読み取り全体が無効になります。これはfsfreezeを使用するか、別のデタッチされたボリュームを作成することでバイパスできます。 Apfs (MacOS) ./fs/apfs.c APFSはAppleが実装した独自のファイルシステムで、リバースエンジニアリングされており、ここでもサポートされていますが、Appleはセキュリティポリシーを大幅に強化しています。SIPを無効にしない限り、メインディスクでffsを実行することはできません。SIP(System Integrity Protection)は、rootユーザーであってもメインディスクのスーパーブロックへのアクセスを禁止する特別なセキュリティ機能です。sudoを使ってもバイパスできません。この機能を無効にする必要があります(yabaiのようなプロジェクトを使用している場合は、すでに無効になっているかもしれません)。メインディスクに触れずにAppleファイルシステムでffsをテストする方法があります。管理者権限なしで生の.dmgファイルを検索できます(そうです、アプリのインストーラは単なるデタッチされたボリュームです)。ffsを使用すると、何もマウントする必要はありません。ファイルシステムタイプとともにボリュームの生バイトへのパスを指定するだけです: ffs "<QUERY>" /path/to/volume.dmg apfs デタッチされたボリュームの検索 ffsはバイトを直接読み込むため、ファイルシステムにマウントすることなく、デタッチされたボリュームを検索するために使用できます。例えば、.isoや.dmgファイルを読み込む場合などです。 速度 ここが最も面白い部分です。ffsはVFS/カーネルファイルシステムキャッシュにアクセスできません。そのため、小さな(またはすでにキャッシュされている)ディレクトリでは遅くなりますが、キャッシュが使い果たされ、カーネルが実際のディスク状態を読み取る必要が生じると、漸進的に高速になります。なぜか?まさに、ある時点でカーネルVFSがオーバーヘッドになるという点を証明するためです。これは、btrfsがマウントされたドライブでffsとripgrepを比較した検索結果です。ripgrepははるかに高度なSIMDベースのマッチャーとファイルウォーカーを使用しているのに対し、ffsはわずか約1.8k行のCコードであることに注意してください。 [repos — 631kファイル] ffs |#### | 5.505s rg |### | 4.813s [dev — 1.50Mファイル] ffs |############ | 18.413s rg |################# | 25.673s [home — 3.25Mファイル] ffs |######################## | 36.205s rg |##################################################| 74.690s ripgrepに使用されたフラグは -F --no-heading -H -n --no-ignore --hidden --one-file-system --no-messages であり、これによりffsと同じ結果が出力されます。 プロジェクトのビルド プロジェクトをコンパイルするために必要なのは、btrfs用のlibzstdとpkg-config内のopenmpだけで、あとは単純に make ffs ffs --help を実行します。