プリアロケート機能

これは、ファイル拡張時に将来の再拡張を見越して連続するブロックを予約してしまう機能である。次回のファイル拡張の高速化と、ファイルブロックが並ぶことによる、ファイルアクセスの高速化を期待できる。

プリアロケート機能のコンパイルフラグを立ててコンパイルすると組み込まれる。(デフォルトはオン)

  • ext2_alloc_block(iノード, ヒント値)
    • 既にプリアロケートしたものがあればそれを利用する。 なければext2_new_block()で、フリービットマップから確保し、 iノードに登録する。(メモリ上のみ) プリアロケートしたものがあってもヒント値付近のものでなければ、 一度ext2_discard_preallocで一度捨ててしまう。
    • 先行拡張は通常ファイルのみが対象
    • プリアロケート機能のコンパイルフラグが立っていない時は、 ここでは何もせず即ext2_new_block関数を呼び出す
  • ext2_new_block(iノード, ヒント値)
    • プリアロケートされたブロックが無くなった時のみ、 ext2_alloc_block関数から呼び出される。
    • ヒント値を元にあるブロックを確保した後、 それに続くブロック列を先行確保する。 先行確保の最大値はスーパブロックに指定された数分(mkfs時に指定?) である。未指定のときは8ブロックになる。
  • ext2_discard_prealloc(iノード)
    • ファイルの参照が0になったとき(close等)に呼び出される。
    • プリアロケートしておいたブロックをフリービットマップに戻す。 (ext2_free_blocks関数を呼び出す)

ext2_new_block()にて先行確保されたブロックは下図のようにメモリiノードの中のリザーブ域にのみ登録される。次に ext2_alloc_block()が呼び出された時は、このリザーブ域からブロックを取り出し、iノードに直接ブロックまたは間接ブロックとして登録する。先行確保されたブロックはメモリ上にのみ存在する。

img40.gif

問題点など

  1. SYNCモードのマウントをした場合、 ブロックの解放時にブロックビットマップを同期書き込みしているが 実はこの処理は必須ではない。もし同期書き込みをせずマシンが クラッシュしてもこのビットが示すブロックが誰からも参照できなく なるだけであり、ファイルシステム破壊を引き起こすことはない。 性能の面から考えても、ここは非同期書き込みで十分だと思われる。
  2. ブロックのプリアロケート機能(8ブロック先行確保)があるが、 システムがクラッシュしてもプリアロケートしたブロックが 失われる方向に倒れるため、信頼性には問題がない。 プリアロケートしたブロックはフリービットマップ上から削除され、 ファイルに組み込まれるまでの間はメモリ上にしか存在しないため、 DUPブロックとなる危険性はない。
    大きなファイルの生成と読み出しにはそこそこの効果が期待できそう。

(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1