Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
ファイルの移動処理は、vfs sys_rename(do_rename)関数が行っている。移動元のファイルのdentryと移動先になるdentryを、lookup_dentry関数を用いて求めたあと、移動元のファイルの親ディレクトリのiノードのrenameオペレーションを呼び出す。
ext2ファイルシステムの場合、ディレクトリのrenameオペレーションは、 ext2_rename関数である。通常ファイルやシンボリックリンクファイルはrenameオペレーションを持っていない。
ext2_rename(リンク元のファイルのdentry、移動先のディレクトリのiノード, 新しいdentry) 移動元のファイルが登録されているディレクトリエントリを検索(ext2_find_entry関数) 移動先のディレクトリに同名のファイルが登録されているか検索(ext2_find_entry関数) if(移動元と移動先のファイルのiノードが同一) return if(移動するファイルがディレクトリなら) { if(移動先親ディレクトリが移動元の親ディレクトリの下?) return エラー if(移動先に(ディレクトリ)ファイルが存在) { if(空ディレクトリでない) return エラー } 移動する(ディレクトリ)ファイルの先頭データブロックを読みだす(ext2_bread関数) if(移動する(ディレクトリ)ファイルの親ディレクトリのiノード番号が間違っている) return エラー } if(移動先にファイルが存在しないなら) { 移動先の親ディレクトリに新しいdentryを登録(ext2_add_entry関数) } 移動先の親ディレクトリエントリに、移動するファイルのiノード番号を書き込む 移動元の親ディレクトリエントリを削除(ext2_delete_entry関数) if (移動先のファイルを上書きした場合) { 上書きされたiノードのリンク数を1減らす(i_nlinkメンバ) ◇上書きされたiノードの遅延書き込み要求(mark_inode_dirty関数) } 移動元親ディレクトリiノードの更新時間設定 ◇移動元親ディレクトリiノードの遅延書き込み要求(mark_inode_dirty関数) if(ディレクトリファイルの移動の時) { 移動するディレクトリのデータブロック中の親ディレクトリの iノード番号を移動先の親ディレクトリのものに書き換える。 ◇移動する(ディレクトリ)ファイルの先頭データブロックの遅延書き込み要求(mark_buffer_dirty関数) 移動元親ディレクトリiノードのリンク数を一減らす ◇移動元親ディレクトリiノードの遅延書き込み要求(mark_inode_dirty関数) if(移動先のファイルを上書きした場合) { 上書きされたiノードのリンク数を1減らす(i_nlinkメンバ) ◇上書きされたiノードの遅延書き込み要求(mark_inode_dirty関数) } else { 移動先親ディレクトリiノードのリンク数を一増やす(i_nlinkメンバ) ◇移動先親ディレクトリiノードの遅延書き込み要求(mark_inode_dirty関数) } } ◇移動元親ディレクトリブロックの遅延書き込み要求(mark_buffer_dirty関数) if(SYNC属性 ?) { ◆移動元親ディレクトリブロックの書き込み(ll_rw_block関数, wait_on_buffer関数) } ◇移動先親ディレクトリブロックの遅延書き込み要求(mark_buffer_dirty関数) if(SYNC属性 ?) { ◆移動先親ディレクトリブロックの書き込み(ll_rw_block関数, wait_on_buffer関数) } ディレクトリエントリキャッシュ上での移動(d_move関数)
上書きされたファイルは、システムコール出口で呼び出すdput関数の延長で整理される。どこからも参照もリンクもされていないため、ファイルを構成するiノードとブロックがフリービットマップに返却される。
ファイルの移動の場合を下図に示す。
ディレクトリの移動の場合を下図に示す。
(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:46:51, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members