ファイルの移動 rename

ファイルの移動処理は、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ノードとブロックがフリービットマップに返却される。

ファイルの移動の場合を下図に示す。

img49.gif

ディレクトリの移動の場合を下図に示す。

img50.gif

 

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