log.c static void read_head(void)

トップページ
jupiteroak.hatenablog.com


log.c
https://github.com/mit-pdos/xv6-public/blob/master/log.c#L85

static void read_head(void)
{
  struct buf *buf = bread(log.dev, log.start);
  struct logheader *lh = (struct logheader *) (buf->data);
  int i;
  log.lh.n = lh->n;
  for (i = 0; i < log.lh.n; i++) {
    log.lh.block[i] = lh->block[i];
  }
  brelse(buf);
}

read_head関数は、ハードディスク上にあるログスペースのヘッダーブロック(ハードディスク上にあるログスペースの先頭セクタ)の内容を読み込み、読み込んだ内容をメインメモリ上で管理されているlogheader構造体に保存します。


処理の内容

ハードディスクからログスペースのヘッダーブロックのデータを読み込んで取得する

struct buf *buf = bread(log.dev, log.start);

bread関数を呼び出して、ハードディスク上にあるログスペースのヘッダーブロックに対応しているバッファ(ヘッダーブロックのデータが保存されている)を取得します。第一引数にはヘッダーブロックが所属するハードディスク(マスタードライブ)を指定し、第ニ引数にはヘッダーブロックのセクタ番号を指定します。

ハードディスクから読み込んで取得したログスペースのヘッダーブロックのデータをlogheader構造体で表現する

struct logheader *lh = (struct logheader *) (buf->data);

buf構造体のメンバである配列data(uchar data[BSIZE])にハードディスクから読み込んで取得したログスペースのヘッダーブロックのデータ512バイトが保存されています。 この配列data(uchar data[BSIZE])の先頭アドレスをlogheader構造体へのポインタlhに代入することで、dataに格納されているデータ(ハードディスクから読み込んで取得したログスペースのヘッダーブロックのデータ)をlogheader構造体として扱うことができます。logheader構造体はログスペースのヘッダーブロックを表現したデータ構造です。

メインメモリ上で管理されているlogheader構造体をハードディスクから読み込んで取得したlogheader構造体で更新する

ハードディスクからの読み込みで取得したlogheader構造体lhで、メインメモリ上で管理されているlogheader構造体log.lhを更新します。
ログスペースのヘッダーブロックの読み取りは、メインメモリで管理されているlogheader構造体log.lh(log構造体内にあるlogheader構造体)を利用しているので、以下の操作によりログスペースのヘッダーブロックの最新の値を読み取れるようになります。

メインメモリ上で管理されているlogheader構造体のnメンバを更新する

log.lh.n = lh->n;

ハードディスクから読み込んで取得したlogheader構造体のnメンバの値で、メインメモリ上で管理されているlogheader構造体log.lhのnメンバの値を更新します。logheader構造体のnメンバの値は、トランザクション内で管理されているブロックの数を示しています。

メインメモリ上で管理されているlogheader構造体のblock配列メンバの各要素を更新する

 for (i = 0; i < log.lh.n; i++) {
    log.lh.block[i] = lh->block[i];
  }

ハードディスクから読み込んで取得したlogheader構造体が持つblock配列の各要素で、メインメモリ上で管理されているlogheader構造体のメンバであるblock配列の各要素を、更新します。
block配列の各要素には、トランザクション内で管理されている各ブロック(セクタ)のセクタ番号がそれぞれ保存されています。

バッファのスリープロックを解放する

brelse(buf);

brelse関数を呼び出して、バッファに関連しているスリープロックを解放し、他のプロセスがこのバッファを利用できるようにします。