Linuxには「実ファイル」と「仮想ファイル」があり、実ファイルはハードディスク上にあるファイルであり、仮想ファイルはカーネルによってファイルとして表される単なるデータであることがわかりました。
たとえば、_/proc
_ディレクトリ内のファイルは仮想ファイルです。
read()
のような関数が実際のファイルの読み取り方法と仮想ファイルの読み取り方法をどのように知っているかを理解したいと思います。私はこの主題についての私の理解を示すために次の図を作成しました。私の理解について間違っている場合は訂正してください。
VFSレイヤーでは、すべてのファイルが仮想です(実際には、UFS(ディスクベース)ファイルシステムとNFS(ネットワークベース)ファイルシステムを結び付けるためにSunOSエンジニアによって発明されました)。
開いている各file
には、一般的なルーチンの実装を提供する関数_f_op
_のテーブルがあり(一部は汎用である可能性があります)、各inode
には添付の_address_space
_オブジェクトがあります。必要な実装を含むC関数(_a_ops
_)のテーブルがあります。シーケンスは次のとおりです。
sys_read()
:アプリケーションがシステムコールを使用してファイルの読み取りを開始しますvfs_read()
)file->f_op->read()
またはdo_sync_read()
またはnew_sync_read()
を使用してファイルシステムドライバーに渡されます。a_ops->direct_IO()
、ext4_direct_IO()
for _ext4
_)が呼び出され、データが返されます。file_get_page()
a_ops->readpage()
を使用してファイルシステムから読み取られます。これは_ext4
_ドライバーからext4_readpage()
によって実装されます。submit_bio()
を使用してブロック入出力要求を作成しますhttp://myaut.github.io/dtrace-stap-book/kernel/fs.html から、これを書いた後にVFSスタックが少しリファクタリングされたため、少し古くなっています
私は決してこれについて徹底的な答えをするつもりはありません...
1つの重要な分離を除いて、基本的に正しいです:read()kernelにファイル記述子に何が含まれているかを尋ねます。 kernelが残りを処理します。物理ファイルシステム、ネットワークファイルシステム、仮想ファイルシステム(/ proc、/ sys、...)のいずれであっても、read()とは関係ありません。カーネルには、リクエストを処理する(または処理しない)ための基礎となるコードがあります。これは、ドライバーと呼ばれるものです。