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 から始まるリストの先頭に入っているはず

getblk は別途きちんと読みます。というか struct buf とか struct devtab あたりの理解が不十分です。