Lions' 本読み (125)
bio.c のあたりを確認。ちょっと色々理解しきれていない部分多数。
例えば incore 手続きですが定義が以下。
4899 incore (adev, blkno) 4900 { 4901 register int dev; 4902 register struct buf *bp; 4903 register struct devtab *dp; 4904 4905 dev = adev; 4906 dp = bdevsw[adev.d_major].d_tab; 4907 for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) 4908 if (bp->b_blkno==blkno && bp->b_dev==dev) 4909 return(bp); 4910 return(0); 4911 }
これ、よくよく見たら繰り返し継続な条件式の bp != dp とかorz
直後で定義されている getblk もそうなんですが、どうも循環リストの先頭/末端の目印として (?) struct devtab なオブジェクトが繋がっている模様。この当時の C だからできる芸当ですねこれ。
binit 手続きでも同様の発想で初期化しているのが分かります。これはこれは。
- bfreelist のリンクな属性を全部自分自身にして初期化
5062 bfreelist.b_forw = bfreelist.b_back = 5063 bfreelist.av_forw = bfreelist.av_back = &bfreelist;
- buf 配列の b_back および b_forw を使って bfreelist に buf 配列の各要素を繋げる形で初期化
5064 for (i=0; i<NBUF; i++) { 5065 bp = &buf[i]; 5066 bp->b_dev = 01; 5067 bp->b_addr = buffers[i]; 5068 bp->b_back = &bfreelist; 5069 bp->b_forw = bfreelist.b_forw;
-
- 5068、5069 で bp から出ているリンク属性を初期化
5070 bfreelist.b_forw->b_back = bp; 5071 bfreelist.b_forw = bp;
-
- 5070、5071 で bp に向かうリンク属性を初期化
- bdevsw 配列の d_tab 属性の 0 でないものも b_forw および b_back なリンクを自分自身にして初期化
5076 for (bdp = bdevsw; bdp->d_open; bdp++) { 5077 dp = bdp->d_tab; 5078 if(dp) { 5079 dp->b_forw = dp; 5080 dp->b_back = dp;
brelse 手続きとか別途確認必要。
getblk に手を付けてみる
ええとざくっと処理を列挙してみます。
- 4931、4932 は dev が NODEV の場合の処理
- そうでない場合、rktab (?) な b_forw 属性から手繰れるリストから b_dev 属性および b_blkno 属性が引数と同じ値な要素を捜す
- ここは incore 手続きの探索と同じですね
- bfreelist.av_forw から始まるリストが空の場合、sleep した後に再度 4930 から処理をやり直す
- 何故にここの判定を割り込み禁止にしているのか
- ディスク割り込み、からガードしてるのかどうか
- bfreelist の av_ なリストの先頭要素を処理対象とする
- (テキストによれば) 遅延書き込みが有効になっているのであれば書き込んでl 4930 から処理をやり直す
- bp の各属性を設定
- bp を bp の b_ なリストから外す
- 基本的に bfreelist なリストから外す、という意味という理解で良いはず
- bp を dp の b_ なリストに入れる
- dp の b_forw から始まるリストの先頭に入っているはず
- bp を bp の b_ なリストから外す
getblk は別途きちんと読みます。というか struct buf とか struct devtab あたりの理解が不十分です。