bio.c struct buf* bread(uint dev, uint blockno)

トップページ
jupiteroak.hatenablog.com


bio.c
https://github.com/mit-pdos/xv6-public/blob/master/bio.c#L96

struct buf* bread(uint dev, uint blockno)
{
  struct buf *b;

  b = bget(dev, blockno);
  if((b->flags & B_VALID) == 0) {
    iderw(b);
  }
  return b;
}

bread関数は、引数devと引数blocknoによって指定されるハードディスク上のセクタに対応しているバッファを取得します。
取得したバッファはスリープロックした状態になっているので、bread関数を呼び出したプロセスがbrelse関数を呼び出すまで、他のプロセスはそのバッファを使用することができません。

引数 uint dev
取得対象となるバッファに対応しているセクタが属するハードディスクドライブを指定します。
引数devが1の値の時は、マスタードライブを指定しています。
引数devが0の値の時は、スレイブドライブを指定しています。

引数 uint blockno
取得対象となるバッファに対応しているセクタのセクタ番号を指定します。

戻り値 buf *b または 0
引数devと引数blocknoが指定するセクタに対応しているバッファを取得できた場合は、そのバッファを指定するアドレスが戻り値となります。
引数devと引数blocknoが指定するセクタに対応しているバッファを取得できなかった場合は、0が戻り値となります。


処理の内容

bget関数を呼び出してバッファを取得する

b = bget(dev, blockno);

bget関数を呼び出して、引数devと引数blocknoによって指定されるハードディスク上のセクタに対応しているバッファを、バッファキャッシュから取得します。

バッファにデータが保存されていない場合はハードディスクからの読み込み処理を行う

if((b->flags & B_VALID) == 0) {
    iderw(b);
  }

b->flagsをB_VALID(#define B_VALID 0x2)でマスク処理することにより、バッファbのflagsメンバのbit1の値を取り出しています。
(b->flags & B_VALID) == 0が真となる場合→バッファbのflagsメンバのbit1が0の場合→バッファbがハードディスクから読み込んだデータを保存していない状態である場合は、iderw関数を呼び出してハードディスクからの読み込み処理を開始させます。

取得したバッファを指定するアドレスを戻り値としてリターンする

return b;