Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
ファイルの削除は二つの処理から成り立つ。
ディレクトリエントリからの登録削除処理は、unlinkシステムコールにおいて行う。ファイルを構成するiノードとデータブロックの解放は、そのファイルへの参照が無くなった時点で行われる(iput関数の延長)。通常はunlinkシステムコールと同時に、どこのディレクトリからも登録されておらず、どのプロセスからも参照されていない状態になるため、ほとんどの場合この二つの処理は同時に行われる。
open中のファイルの削除を行った場合は、unlinkシステムコール上ではファイル実体解放は行われず、closeシステムコールの延長でファイル実体の解放が行われることとなる。
unlinkシステムコールは、vfs sys_unlink(do_unlink)関数においてこれから削除するファイルのdentryを求めた後、親ディレクトリのiノードのunlinkオペレーションを呼び出すことにより実現されている。ext2ファイルシステムの場合は、 ext2_unlink関数が呼び出される。ext2_unlink関数はディレクトリエントリから目的のエントリを消した後、d_delete関数を呼び出す。
ext2_unlink(親ディレクトリのiノード, 削除するファイルのdentry) 削除するディレクトリエントリを検索(ext2_find_entry関数) ディレクトリエントリを削除(ext2_delete_entry関数) ◇ディレクトリブロックの遅延書き込み要求(mark_buffer_dirty関数) if(SYNC属性 ?) { ◆ディレクトリブロックの書き込み(ll_rw_block関数, wait_on_buffer関数) } 親ディレクトリのiノードの更新時間変更 ◇親ディレクトリiノードの遅延書き込み要求(mark_inode_dirty関数) 削除するファイルのiノードのリンク数を1減らす ◇削除するファイルのiノードの遅延書き込み要求(mark_inode_dirty関数) dentryの解放要求(d_delete関数) ディレクトリエントリを読み込んだバッファの解放(brelse関数)
ファイル実体の削除処理はiput関数が行っている。通常はd_delete関数の処理の延長で呼び出され、ファイル本体の解放が行われる。(d_delete関数 → dentry_iput関数 → iput関数)一方open中のファイルの場合は、closeシステムコールから呼び出されるdput関数を通してiput関数が呼び出される。(dput関数 → dentry_iput関数 → iput関数)iput関数は対象のファイルの参照カウントとリンクカウントが共に0となるとそのスーパブロックに登録されているdelete_inodeオペレーションを呼び出す。
ext2ファイルシステムでは、delete_inodeオペレーションは以下の関数である。
ext2_delete_inode(iノード) iノードに削除時刻を設定(i_dtimeメンバ) ◇iノードの遅延書き込み要求(mark_inode_dirty関数) ◆iノードを書き込む(ext2_update_inode関数) iノード情報のファイルサイズを0にする(i_sizeメンバ) if(iノードにデータブロックが登録されていれば(i_blocksメンバ) ) { 登録されている全てのブロックの解放を行う(ext2_truncate関数) } iノードの解放を行う(ext2_free_inode関数)
(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:45:08, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members