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 システムコールのあと、この時点で小さいと分類されるファイルに関連するディスクブロックは存在しない。_という記述がアレです。