バッファキャッシュ


Linux(vfs)

*** バッファキャッシュ ***

ディレクトリやinodeなどのI/Oはバッファキャッシュを経由して行われる。
バッファキャッシュのインタフェースによって、ファイルシステムモジュールとデバイスドライバがお互いを意識しなくて済む。
バッファキャッシュはすべてのファイルシステムから使用できる。

・バッファの状態
バッファには、その状態を表すメンバ(b_state)がある。
状態には以下のものがある。

	BH_Uptodate	バッファの内容は有効
	BH_Dirty	ディスクに未反映
	BH_Lock		I/O中
	BH_Req		このビットが0ならバッファは無効
	BH_Mapped	対応するディスクブロックがある
	BH_New		新規確保されたディスクブロックに対応したバッファ
	BH_Protected	特殊用途。勝手に開放しないことを指示


バッファのリストには以下のものがある

	hash_table[]	ハッシュヘッダ。デバイス番号とブロック番号から計算
	lru_list[BUF_CLEAN]	従来のフリーリストに相当
	lru_list[BUF_DIRTY]	遅延書き込みのバッファがリンクされる
	lru_list[BUF_LOCKED]	書き込みI/O処理中のバッファがリンクされる
				読み込みは lru_list[BUF_CLEAN]のまま
	lru_list[BUF_PROTECTED]	BH_Protectedのバッファがリンクされる
	free_list[]	利用されていない空のバッファがバッファサイズ毎に分類されてつながる


・バッファのフラッシュ
Dirtyの立ったバッファは、デーモンまたはsyncの実行によりディスクに反映される。
デーモンの設定は、bdflushシステムコールで行うことができる。

[kflushd]
kflushdは以下の場合に起動され、遅延書き込みのバッファがある水準以下になるまでディスクに書き込んで行く。

    ・遅延書き込みのバッファが一定水準を越えた時(balance_dirty関数) バッファをdirtyにする時(mark_buffer_dirty)にチェックしている。
      デフォルト設定では、全バッファに占める割合が20%を越えた時、待ち合わせ無しでbdflushを起動し、全バッファに占める割合が40%を越えた時、待ち合わありでbdflushを起動する。
    ・空きバッファの確保に失敗したとき(refill_freelist関数)
    ・空きメモリが不足した時(filemap_swapout関数) 


[kupdated]
kupdateは、定期的に動作してバッファをフラッシュする。
kupdateはkflushdと異なり、 Dirtyな状態のまま一定時間経過したバッファを書き込み対象としている。
バッファのフラッシュに先立って、inodeやスーパブロックもフラッシュする。

[sync(2)]
syncシステムコールはDirtyなバッファ全てをディスクに書き込む。
inodeやスーパブロックも対象。

バッファキャッシュ関連関数
[I/O関連]
・struct buffer_head * getblk(kdev_t dev, int block, int size)

	バッファの獲得処理。まずハッシュ上を検索し、みつからなければ free_list[] から取りに行く。~
	なければ新たにメモリを確保する。
	バッファの参照数を1増やす。


・void brelse(struct buffer_head *buf)

	バッファの開放(参照数を1下げるだけ)
	引き数がNULLなら何もしない


・struct buffer_head * bread(kdev_t dev, int block, int size)

	ブロックの読み込み。
	getblk()でバッファを保存し、その内容が有効なら確保したバッファのポインタを返す。
	そうでなければ、ll_rw_block(READ, 1, &bh)関数を使用してディスクからデータを読み込んでから、確保したバッファのポインタを返す。


・struct buffer_head * breada(kdev_t dev, int block, int bufsize, unsigned int pos, unsigned int filesize)

	bread()に先よみの機能をもたせたもの。
	最大16ブロックまで先よみする。


・bwrite()はありません

	必要に応じて ll_rw_block() でI/Oする。


・void wait_on_buffer(struct buffer_head * bh)

	I/O完了の待ち合わせのための関数


・void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])

	ドライバへのI/O要求。
	同じ装置の場合であれば、複数のバッファのI/Oを一度に要求できる。

最新の20件

2006-12-20 2005-11-17 2005-11-09 2005-10-28 2005-10-24 2005-10-13

  • counter: 1283
  • today: 1
  • yesterday: 0
  • online: 1