Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
ディレクトリから、ファイル名で指定されるファイルのエントリを見つけ出す。アクセス高速化のため、ディレクトリブロック用のバッファを先行して読みだしている。(現在は8ブロック先行読みだし)
ext2_find_entry(ディレクトリのiノード, ファイル名, ... ) ディレクトリの先頭ブロックから8つ分のバッファを確保(ext2_getblk関数) for(ディレクトリブロックがある間) { if(確保したバッファにまだディレクトリデータが読み込まれていないなら) まとめて読み込む(ll_rw_block関数) 次に検索するディレクトリブロックの入ったバッファのI/O完了を待つ(wait_on_buffer関数) while(ディレクトリブロック中にディレクトリエントリがある間) { if(ディレクトリエントリとファイル名が一致) { 先行確保したバッファを解放(brelse関数) return 見つかったディレクトリエントリ } } 検索が終わったバッファを解放(brelse関数) if(先行読み込みしたバッファが無くなったら) { 次のディレクトリブロックから8つ分のバッファを確保(ext2_getblk関数) } } バッファを全て解放(brelse関数) return NULL(発見できず)
ext2_add_entry関数は、ディレクトリにファイル名で指定されるファイルのエントリを追加する。ext2_find_entry関数と異なりディレクトリブロックの先行読み込み処理は行わず、1ブロックずつゆっくりと読み込み処理を行っている。
ext2_add_entry(ディレクトリのiノード, ファイル名, ... ) 先頭のディレクトリブロックを読み込む(ext2_bread関数) while(1){ if(このブロック中のディレクトリエントリを全て検索しつくした) { ディレクトリブロックを読み込んだバッファを解放(brelse) 次のディレクトリブロックを読み込む(ext2_bread関数) if (ディレクトリが拡張された) { 拡張されたブロックをディレクトリブロックとして初期化 iノード中のディレクトリサイズ情報を変更 ◇ディレクトリのiノードの遅延書き込み要求(mark_inode_dirty関数) } } if (既に存在しているエントリと同じ名前なら) return エラー if (ディレクトリブロック内にファイル名を登録可能なスペースが見つかった){ ディレックブロックを読み込んだバッファ内に、目的のファイルを登録する。 (空エントリならそこに登録する) (大きなエントリなら、二つのエントリに分割し、そこに登録する) ◇ディレクトリiノードの遅延書き込み要求(mark_inode_dirty関数) ◇ディレクトリブロックの遅延書き込み要求(mark_buffer_dirty関数) } } ディレクトリのデータブロックを読み込んだバッファを解放(brelse)
ディレクトリブロックの先頭のディレクトリエントリ以外は、空のディレクトリエントリは置かず、削除されたディレクトリエントリは一つ前のディレクトリエントリにマージしてしまう。次にディレクトリエントリを追加する場合は、これら大きな空きスペースを持ったディレクトリエントリを探し出し、二つに再分割し利用する。
下図は、ファイル"baa"をディレクトリに登録/削除する時の動きを示している。
ext2_delete_entry(ディレクトリエントリ, ディレクトリエントリが含まれるディレクトリブロックのバッファ) ディレクトリブロックのバッファの中から、目的のエントリを削除する (途中のエントリの削除は、一つ前のエントリと結合することにより実現) (先頭のエントリの削除は、iノード番号フィールドに0を入れることで実現)
(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:45:06, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members