技術

[xv6 #65] Chapter 5 – File system – Code: Path names

テキストの73〜74ページ

本文

ディレクトリのように、パス名を実現するために必要となる追加のコードは少ししかない。
なぜなら、dirlookup関数を再帰的に呼び、namei関数などの関連がある関数を使うだけだからである。
namei関数は、引数のpathを階層的なパス名として評価し、それに一致するinodeを返す。
nameiparent関数は、namei関数の変種である。
nameiparent関数は、最後の要素の直前で止まり、親ディレクトリのinodeを返し、最後の要素を引数nameにコピーする。
両方の関数とも、実際の仕事をさせるために、一般化された関数であるnamex関数を呼ぶ。

fs.cのnamex, namei, nameiparent関数

// Look up and return the inode for a path name.
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
static struct inode*
namex(char *path, int nameiparent, char *name)
{
  struct inode *ip, *next;

  if(*path == '/')
    ip = iget(ROOTDEV, ROOTINO);
  else
    ip = idup(proc->cwd);

  while((path = skipelem(path, name)) != 0){
    ilock(ip);
    if(ip->type != T_DIR){
      iunlockput(ip);
      return 0;
    }
    if(nameiparent && *path == '\0'){
      // Stop one level early.
      iunlock(ip);
      return ip;
    }
    if((next = dirlookup(ip, name, 0)) == 0){
      iunlockput(ip);
      return 0;
    }
    iunlockput(ip);
    ip = next;
  }
  if(nameiparent){
    iput(ip);
    return 0;
  }
  return ip;
}

struct inode*
namei(char *path)
{
  char name[DIRSIZ];
  return namex(path, 0, name);
}

struct inode*
nameiparent(char *path, char *name)
{
  return namex(path, 1, name);
}

namex関数は、まずパスをどこから評価するかを決定する。
パスが”/”で始まっている場合、評価はルートディレクトリから開始される。
パスが”/”で始まっていない場合は、現在のディレクトリから評価が開始される。
そしたら、パスの各要素について処理を行うためにskipelem関数を使う。
ループ中の各反復では、現在のinodeであるipからnameを探さなければならない。
ループ中は、まずipをロックし、それがディレクトリであるかどうかをチェックする。
ディレクトリでなければ、namexは失敗となり0を返す。
(ipのロックが必要なのは、ip->typeが他のプロセスによって変更される可能性があるからではない。それは不可能である。ipのロックが必要なのは、ilockが実行されるまでは、ip->typeが、ディスクから読み込まれた直後のままであるかどうかは保証されないからである。)
nameiparent関数から呼び出され、かつパスの最後の要素の場合、nameiparent関数の定義に基づきループは早めに止まる。
最後のパスの要素は、すでにnameにコピーされているので、namex関数はアンロックされたipを返すだけでよい。
最後に、ループ中ではdirlookup関数を使ってパスの要素を調べ、ip = nextを実行することによって次の反復に備える。
ループでパスの要素を走査し尽くしたときは、ipを返す。

感想

すぐ下のディレクトリの層を使って階層的なパスをどう表現するかについてです。

ディレクトリの層では、各ディレクトリは名前とinodeの組をデータ構造上は1階層分しか持ちません。
そのinodeがディレクトリの場合、階層構造を成します。
今回は、その階層構造と、パス(各ディレクトリ階層を”/”で区切った文字列表現)を対応付けるコードの説明となります。

コメントを残す

メールアドレスが公開されることはありません。



※画像をクリックして別の画像を表示