fs.c void iupdate(struct inode *ip)
トップページ
jupiteroak.hatenablog.com
fs.c
https://github.com/mit-pdos/xv6-public/blob/master/fs.c#L220
void iupdate(struct inode *ip) { struct buf *bp; struct dinode *dip; bp = bread(ip->dev, IBLOCK(ip->inum, sb)); dip = (struct dinode*)bp->data + ip->inum%IPB; dip->type = ip->type; dip->major = ip->major; dip->minor = ip->minor; dip->nlink = ip->nlink; dip->size = ip->size; memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); log_write(bp); brelse(bp); }
iupdate関数は、メインメモリ上にあるiノードipを使って、ハードディスク上にあるiノードdipを更新します。
引数 struct inode *ip
ハードディスク上にあるiノードを更新するために使用するメインメモリ上にあるiノードのアドレスです。
処理の内容
- ハードディスクから該当するiノードを含んだセクタに対応しているバッファを取得する
- 取得したバッファのデータから該当するiノードを取り出す
- ハードディスク上にあるiノードの内容を更新する①
- ハードディスク上にあるiノードの内容を更新する②
- ブロック(セクタ)をロギングにおけるトランザクションの管理対象として登録する
- バッファのスリープロックを解放する
ハードディスクから該当するiノードを含んだセクタに対応しているバッファを取得する
bp = bread(ip->dev, IBLOCK(ip->inum, sb));
bread関数を呼び出して、ハードディスク上にあるiノードの読み込みを行います(あるいは、ハードディスクからiノード番号がinumであるiノードを含んだセクタに対応しているバッファを取得します)。
第二引数に設定されているIBLOCKマクロは、iノード番号がinumであるiノードを含んだセクタのセクタ番号を算出します。
bread関数は、第二引数で指定されたセクタ番号を持つセクタのデータ512バイト(= dinodeのデータサイズ × 32個のiノード)を取得します。
取得したバッファのデータから該当するiノードを取り出す
dip = (struct dinode*)bp->data + ip->inum%IPB;
iノード番号inumのiノードを取得するために、取得したバッファに格納されているデータの先頭アドレスbp->dataをdinode構造体へのポインタに格納し、そのポインタにinum%IPBを加算します。dinode型へのポインタに加算する操作により、sizeof(struct dinode)バイト境界のアドレス(dinode構造体のデータサイズの倍数値となるアドレス)で、取得したバッファに格納されているデータにアクセスすることができます。これは、取得したバッファに格納されているデータがdinode構造体の配列として、ポインタに加算する値inum%IPBが配列のインデックスとして、機能していることと実質的に同じです。
IPBは、ブロック1個当たりのiノード数を算出するマクロです。inumをIPBで剰余演算した値であるinum%IPBは、dinode構造体の配列(取得したバッファに格納されているデータ→セクタ内のデータ)において、iノード番号inumのiノードを指定するインデックスとなります。
ハードディスク上にあるiノードの内容を更新する①
dip->type = ip->type; dip->major = ip->major; dip->minor = ip->minor; dip->nlink = ip->nlink; dip->size = ip->size;
inode構造体(メインメモリ上にあるiノードを表現したデータ構造)の各メンバの値で、dinode構造体(ハードディスク上にあるiノードを表現したデータ構造)の各メンバの値を、更新します。
ハードディスク上にあるiノードの内容を更新する②
memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
memmove関数を呼び出して、inode構造体が持つaddrs配列からdinode構造体が持つaddrs配列へ、データブロックの参照をコピーします。
addrs配列には、iノードが直接的に所有しているデータブロックのセクタ番号がそれぞれ格納されています。