ディレクトリの削除

ディレクトリの削除も、基本的にファイルの生成と同様である。vfs sys_rmdir(do_rmdir)関数において、 パス検索(lookup_dentry関数)により親ディレクトリのiノードを求めた後、親ディレクトリのiノードのrmdirオペレーションを呼び出すことにより実現されている。

ファイルの削除と異なる点は、ディレクトリの削除処理がdentryの参照カウントが2のまま行われるところにある。そのため自動的なdentryの解放処理が動作しないので、vfs側で無理矢理d_drop関数を呼び出しdentryをキャッシュから落し、解放されるようにしている.(設計に失敗したと思われる)

ext2ファイルシステムの場合、rmdirオペレーションは、 ext2_rmdir関数である。この関数はunlinkと同じく親ディレクトリのエントリから登録を抹消するだけであり、削除するディレクトリブロックを構成するブロックの解放は、ディレクトリへの参照が無くなった時である。

ディレクトリへの参照が無くなるタイミングは、do_rmdirの最後に呼び出されるdput関数でdentryの参照数が0になった時である。後は通常ファイルの場合と全く同じ処理でディレクトリを構成するiノードとブロックが解放される。

  ext2_rmdir(親ディレクトリのiノード, 削除するディレクトリのdentry)
      削除するディレクトリエントリを検索(ext2_find_entry関数)
      if (削除するディレクトリエントリが空でない(empty_dir関数)) return エラー
      ディレクトリエントリを削除(ext2_delete_entry関数)
      ◇ディレクトリブロックの遅延書き込み要求(mark_buffer_dirty関数)
      if(SYNC属性 ?) {
          ◆ディレクトリブロックの書き込み(ll_rw_block関数, wait_on_buffer関数)
      }
      削除するディレクトリのiノードのリンク数を0にする(i_nlinkメンバ)
      削除するディレクトリのiノードのファイルサイズ数を0にする(i_sizeメンバ)
      ◇削除するディレクトリのiノードの遅延書き込み要求(mark_inode_dirty関数)
      親ディレクトリのiノードのリンク数を1減らす(i_nlinkメンバ)
      親ディレクトリのiノードの更新時間変更
      ◇親ディレクトリiノードの遅延書き込み要求(mark_inode_dirty関数)
      dentryの解放要求(d_delete関数)
img47.gif

問題点

  1. SYNCモードでマウントしている場合、通常ファイルの場合と同じく、 解放処理が無駄に重いという性能上の問題がある。(同じルーチンを 利用するのでまったく同じ)
  2. SYNCモードでマウントしている場合でも、親ディレクトリのiノードは 遅延書き込みとなっている。システムクラッシュが発生すると、 親ディレクトリは実際よりもリンク数が一つ多い状態になる。 ただし、ファイルシステム構造に影響を与えるものではなく、 fsckにより容易に修復できる。

(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST
1