Linux カーネルで認識されるファイルシステムを含むディスクがあります。このファイルシステムで現在空いているすべてのブロックの物理ブロック番号を取得する必要があります。どうやってやるの?
5 に答える
空きブロック数を取得する:
インカーネル方式:
.statfs
ファイルシステムが実装するスーパーブロックフックを見てください。それらは、パラメーター、空きブロックの数kstatfs
を持つオブジェクトを返します。f_bfree
これで呼び出せるはずです。
ユーザー空間から:
コマンドは最もdf
単純です(もちろん、これによりカーネルが呼び出されますstatfs
-他にどこで情報を取得しますか? :)
編集:あなたの最初の質問は、無料のブロック数だけを伝えました。
ブロックの場所を取得する:
カーネルの現在の構造では、ファイルシステムに依存しない方法で、合計数だけでなく、すべての空きブロックの場所を取得することは不可能です (そして、おそらくこの方法のままになります)。VFS は、ファイルシステムがビットマップを維持する方法に共通の構造を課しません。ビットマップは、スーパーブロックのファイルシステムに依存する部分で追跡されます。
したがって、すべてのファイルシステムで機能するソリューションが必要な場合は、運が悪い. ファイルシステムが何であり、その数が少ないことがわかっている場合はfsck
、それらのそれぞれのユーザー空間コードを調べて、期待する形式でビットマップを書き出す関数を追加するか、.statfs
フックを変更してビットマップを書き出すことができます。
残りのすべての空きブロックを割り当てる大きなファイルを割り当てる方法は、特にジャーナルが関係している場合は、あまり良い考えではないように思えます。これを行うと、ファイルが書き込まれたり削除されたりするアクティブなファイルシステムでも機能しません。
これはファイルシステムに依存します。統一されたインターフェースはなく、JFFS などの一部のファイルシステムには実際には空きブロックの概念がありません。さらに、ファイルシステムがマウントされている場合、取得した情報はすぐに古くなる可能性があります。ドキュメントが不十分なファイルシステムの内部コードを読まなければならないことが予想されます。ただし、必ずしもカーネルでこれを行う必要はありません。たとえば、ext[234] フリースペース ビットマップの取得に関心がある場合は、libext2fsのビットマップ関数を参照してください。一般に、ユーザー空間 fsck があれば、おそらくそのコードを悪用して必要な情報を取得できます。
とにかく、これは何のために必要ですか?
Afraredのような関数は、空き fs ブロックの数statfs
だけを教えてくれますが、それらの位置は教えてくれません。
空きブロックの位置を取得するために私が見つけた最も簡単な方法は、fallocate()
使用可能なすべてのスペースを埋める (または呼び出しでのみ予約する)ファイルを作成し、 FIBMAP
ioctl を使用してブロック マップを取得し、ファイルを削除することです。しかし、このようにすることは、いくつかの理由で私が望んでいることではありません。
もう 1 つの方法は、具体的なファイル システムの下位レベルに入り、そのドライバーから空き領域のビットマップを取得することです。私にとっては良い方法ですが、ファイルシステムごとに依存して実装する必要があり、良くありません:)
たぶん、私が見つけることができないいくつかのvfs関数、またはその場合に役立ついくつかのfs ioctlがありますか?
とにかくあなたの答えをありがとう!
古いスタイルの C をフォークして、UNIX で「stat」というプログラムを実行できます。その出力をファイルにパイプしてから、いくつかの文字列ストリームを使用して解釈し、空きブロックの数を見つけることができます。(これには、合計 IO ブロックの数を取得し、使用された IO ブロックの数を差し引く必要があります。
これよりも簡単な方法があるかどうかはわかりません。ここにいくつかの擬似コードがあります:
main() {
fork()
if child{
execl(stat / %B >> output.txt)
}
if parent {
wait until output.txt is populated
read in data with stringstream
calculate number of free blocks
}
}
それが役立つことを願っています。
system() コマンドから stdout を最適にキャプチャする
探しているのは syscall かもしれません。最初に Linux で popen が標準であることを確認してください。また、次のようなことを行う必要があることを忘れていました。
FILE* test = popen("df","r");
df は、システム上の空きブロックの数を示しているためです。