最終更新:ID:2prRD+ZbPQ 2011年06月15日(水) 14:04:16履歴
- 画像は Understanding_the_Linux_Kernel_Third_Editionから引用
- 仮想ファイルシステム:異なるシステム(Windows,他のUNIXなど)上のファイルを透過的に扱えるようにする
- この章は、VFSの目的、構造、実装を述べる
- 通常ファイル、ディレクトリ、シンボリックリンク
- 関連
- デバイスファイル(13章)
- Ext2,Ext3ファイルシステム(18章)
- パイプ(19章)
- 伝統的なUNIXファイルシステムを踏襲
- ディレクトリが他ディレクトリのリストを持つ通常のファイルとして扱われる、など
- 他のファイルシステムをVFSで使えるように変換
- read,writeなどの関数はカーネルにポインタとして登録
- これから使うファイルシステム用の関数をさすポインタ
- 共有ファイルモデルは4つ型ののオブジェクトから構成
- スーパーブロックオブジェクト:マウントされたファイルシステムに関する情報を保存
- iノードオブジェクト:個々のファイルのついての情報を保存
- ファイルオブジェクト:オープンされているファイルとプロセスの間のやり取りに関する情報を保存
- dエントリオブジェクト:ディレクトリエントリと対応するファイルとのリンクついての情報を保存
- dエントリキャッシュ:使用したdエントリオブジェクトを置くキャッシュ
- 同じエントリが呼び出されるときに使用
- super_block構造体
- システム上の全てのスーパーブロックオブジェクトは1つの双方向循環リストにリンクしている
- ディスク上のデータを更新する必要があるかどうかのフラグ(s_dirt)を持つ
- 汚れたスーパーブロックは定期的に書き出される
- それぞれのファイルシステムは独自のスーパーブロック操作メソッドを持つ
- inode構造体
- 1つのファイルに対して一意のiノードオブジェクトを持つ
- dirtyフラグを持つ
- 3つの双方向循環リストのうち1つに必ず入っている
- 未使用のiノードオブジェクトのリスト
- 使用中のiノードオブジェクトのリスト
- 汚れているiノードオブジェクトのリスト
- ファイルシステムごとにスーパーブロックオブジェクトのメンバを先頭とした双方向循環リストにつながれている
- inode_hashtableハッシュテーブルにも含まれている
- iノードオブジェクト検索の高速化のため
- プロセスとプロセスによってオープンされたファイルがどのようにやり取りを行うかを記述
- file構造体
- ファイルオブジェクトはディスク上に存在しない
- 必要なときにスラブキャッシュから割り当てる
- それぞれが属するファイルシステムのスーパーブロックを基点とするリストにつながれている
- 現在そのファイルオブジェクトを使用中のプロセス数を数えるカウンタを持つ
- dentry構造体
- ディスク上に存在しない
- プロセスが参照するパス名の要素1つにつき1つ存在
- 各要素を対応するiノードと結びつける
- 次の4つの状態のいずれかになる
- 空き:スラブアロケータに利用される
- 未使用:現在使用されていないが、iノードとの対応は保持している(キャッシュで使用)
- 使用中
- 負:dエントリに対応するiノードが存在しない状態
- 一度使用したdエントリオブジェクトをキャッシュしておくことで、エントリ処理を高速化
- 2つのデータ構造からなる
- 「使用中」「未使用」「負」いずれかの状態にあるdエントリオブジェクトの集合
- ハッシュテーブル
- iノードキャッシュの役割も持つ
- 未使用のdエントリは最長不使用順リスト(LRUリスト)に置かれる
- 最も使用されていない時間が長いdエントリをキャッシュから削除
- 負のdエントリオブジェクトも登録されて優先的に削除される
- プロセスがファイルシステムとの間で処理するのデータ構造が必要
- fs_struct構造体:プロセスディスクリプタはfs_struct構造体へのポインタを持つ
- files_struct構造体:使用中のファイルオブジェクトへのポインタを持つ
- システムプログラムや管理者がカーネルのデータ構造を操作する為のシステム
- 特殊ファイルシステムをマウントするとき、カーネルは擬似ブロック型デバイスを割り当てる
- 通常のファイルシステムと同じように操作できるようになる
- カーネルのコンパイル時に必要なファイルシステムを認識するようにしてある
- モジュールとして組み込む事もできる
- VFSは、カーネルに含まれる全てのファイルシステムの種別を把握するため、ファイルシステム種別の登録を行う
- file_system_typeオブジェクトに登録
- システムの初期化スクリプトや重要なシステムプログラムを含むルートファイルシステムは起動時にカーネルがマウント
- その他のファイルシステムはマウント済みのファイルシステムの上にマウントできる
- マウントする側、された側で子、親の関係をなすツリー構造を作る
- Linuxは全てのプロセスが独自のファイルシステムツリーを持つことができる(名前空間)
- 大部分のプロセスはルートファイルシステムを基点とする名前空間を持つ
- clone()システムコールなどで新しい名前空間を作ることができる
- Linuxは同じファイルシステムを何回もマウントすることができる
- ファイルシステムが増えるわけではない
- 同じマウントポイントに複数のマウントを重ねることができる
- マウント済みのファイルシステムの情報はマウント済みファイルシステムディスクリプタに登録され幾つかのリストに保持されている
- マウントポイントのパス名を検索(12.5節)
- 引数のフラグを見て、処理を決定
- ファイルをマウントする場合は do_kern_mount()関数を呼び出す
- 名前空間を変更
- ファイルシステム種別のフラグを確認し、マウント操作の方法を決定
- ファイル種別を識別する
- 新しいファイルシステムディスクリプタを確保
- スーパーブロックオブジェクトを割り当てる
- 構造体のメンバを新しいものに置き換える
- 空のルートディレクトリを提供する特殊ファイルシステムrootfsをマウント
- do_kern_mount()でrootfsをマウント
- 名前空間オブジェクトを確保し、システム上の全てのプロセスをこの名前空間に設定
- プロセス0のルートディレクトリと作業ディレクトリをルートファイルシステムに設定
- rootfsに/dev/root デバイスファイルを作成
- プロセスのカレントディレクトリをrootに変更
- ファイルシステムのマウントポイントをrootfsファイルシステムのルートディレクトリ上に移動
- パス名を分析し、ファイル名の並びへと分割する操作
- dエントリキャッシュによって高速化できる
- UNIXとVFSファイルシステムの特徴を考慮する必要がある
- ディレクトリのアクセス権の確認
- ファイルがシンボリックリンクの場合
- シンボリックリンクが無限ループをなす場合
- ファイルがマウントポイントである場合
- パス名検索は、システムコールを発行したプロセスの名前空間内でなければならない
パス検索の流れ
- path_lookup()関数
- カレントプロセスの読み書きロックを取得
- パス名が絶対パスか相対パスか判断
- /で区切られたパス名をnameidataデータ構造に格納
- ロックを解放
- link_path_walk()関数を呼び出す
- パス名から/を全て省く
- 先頭からパス名を解決していく
- '.'(カレントディレクトリ)、'..'(親ディレクトリ)などを処理する
- dエントリキャッシュを検索し、なければディスクを直接検索して、dエントリオブジェクトを求める
- パス名の最後が/の場合はディレクトリとして処理
- 要素がシンボリックリンクの場合はリンクの処理を続ける
- パス名がシンボリックリンクの場合、カレントディレクトリをそのシンボリックリンクの位置にしてパス名検索を始める
- シンボリックリンクは5回までしか参照されない
- パスが40を超えた場合は処理を中断
- パス名検索を利用してopenするファイルがあるかどうかを判定し、無ければ新たにファイルを作成する
- システムコールの各種フラグに従ってファイルのアクセス権限を設定
- openしたファイルオブジェクトのアドレスを返す
- openされているファイルオブジェクトのアドレスを確認
- ファイルが読み/書きが可能である事を確認し、データを転送する
- ファイルオブジェクトを解放
- 複数のファイルロック方式
- 勧告ロック:ロックを無視するタイプのプロセスに対して勧告する
- 強制ロック:確実なロック
- 共有読み取りロック:あるファイルの読み取りロックを持つことができるプロセスに制限は無い
- 排他的書き込みロック:書き込みロックを持てるのは1つのプロセスのみ、読み取りロックがかけられた領域は書き込みロックすることはできない
- 共有モード強制ロック:他のプロセスがオープンすることができないようにする
- リース:他のプロセスがオープンしようとすると、現在実行中のプロセスが矛盾が起きないようにファイルを更新してロックを解放する
- ロックはファイルの任意の領域に対してかけることができる
- flock()システムコール:ファイル全体にロックをかける
- fcntl()システムコール:ファイルの一部だけにかけることができる
- お互いのロック状況を知ることはできない
- デッドロックをさけるため
- file_lock構造体
- プロセスが排他ロックを要求し、指定したファイルに共有ロックがかけられていた場合は、プロセスを待ちキューに挿入する
- 2のリストでロックの状態を管理
- アクティブなロック
- ブロック中のロック
最新コメント