Lions' 本読み (146)

396p の open1 の解説に

prele (7882) は i ノードをアンロックするのに使われる。「どこで、なぜ、i ノードがロックされるのか」と疑問に思う人がいるかもしれない。

Lions' Commentary on UNIX より引用
という記述があります。確認してみます。
prele 手続きの定義が以下。

7882 prele(ip)
7883 int *ip
7884 {
7885    register *rp;
7886
7887    rp = ip;
7888    ip->i_flag =& ~ILOCK;
7889    if(rp->i_flag&IWANT) {
7890            rp->i_flag =& ~IWANT;
7891            wakeup(rp);
7892    }
7893 }

ここで問題になってくるのは ILOCK なフラグで xref で確認してみるに iget 手続きでこのフラグを立てているのを確認。おそらくは namei あたりだろう、と勝手に目星をつけて namei 手続きを確認してみるとやはり iget 呼び出して云々ですね。
確認したところでは、open も creat も namei して open1 してます。その間に手を出されないようにその inode なオブジェクトを、なのかどうか。
あ、ILOCK で xref をもっかい見てみれば良いのかな。見てみるに iget で ILOCK とか IWANT なソレがありますね。iget における排他制御のため、なのか。
prele で IWANT が云々であれば wakeup ってのも iget 関連ですね。

7287                    if((p->i_flag&ILOCK) != 0) {
7288                            p->i_flag =| IWANT;
7289                            sleep(p, PINOD);
7290                            goto sleep;
7291                    }

テキスト的にはまだ iget 手続きは読んでない、ということなのでなのかどうなのか。

falloc 手続き

つうか以下の一連のソレ達が微妙な味わいです。

5827    if ((fp = falloc()) == NULL)
5828            goto out;
5829    fp->f_flag = m&(FREAD|FWRITE);
5830    fp->f_inode = rip;
5831    i = u.u_ar0[R0];
5832    openi(rip, m&FWRITE);
5833    if(u.u_error == 0)
5834            return;
5835    u.u_ofile[i] = NULL;
5836    fp->f_count--;
5837
5838 out:
5839    iput(rip);
5840 }

falloc から戻る fp はテンポラリなソレなのか、とか openi って何なんだ、とか u.u_ar0[R0] て、とか u.u_ofile[i] て、とか iput 手続きが、とか謎だらけ。
上記を見つつ順に確認していきます。とりあえず falloc は 5507 で定義されている struct file な構造体配列の file から f_count が 0 な要素をチョイスして云々するのですが、その前に ufalloc 手続きを呼び出すのですが ufalloc では以下な処理をしてます。

  • u.u_ofile な配列の中身が NULL な要素の添字を u.u_ar0[R0] に格納
  • i を戻す

で、file な配列から取り出した要素について

  • u.u_ofile[i] に取り出した要素のアドレス格納
  • 取り出した要素なアドレスを戻す

ということをしてますね。で、戻った呼び出しもとで属性を設定して (5829, 5830) openi 手続きを呼び出して

  • u.u_ofile[i] に NULL 格納
  • fp->f_count をゼロに

してます。最後に 5839 を実行して戻っているんですが、openi と iput がポイントですね。u.u_ar0[R0] に添字が入ってて、u.u_ofile[u.u_ar0[R0]] に fp が入ってて、というのがアレなのかどうか。
あ、超カン違いしてました。openi 呼び出して u.u_error が 0 値なら return してるんですね。5835 以降はエラー処理でした。ちなみにテキストにある通り、openi 手続きはディスクデバイスに対しては副作用はないですね。
struct file 型の file 配列については使途を別途確認の方向で。あと、_creat システムコールのあと、この時点で小さいと分類されるファイルに関連するディスクブロックは存在しない。_という記述がアレです。