O_DIRECT フラグを利用した Direct IO
C++ を利用しての Direct IO で詰まった。
Direct IO とはキャッシュを介さずにファイルシステムに直でアクセスしてしまおうという、まぁ通常ではあまり使いそうにないが、アプリ側で別途キャッシュをしていたり、そもそも RAM FS などでメモリをファイルシステムとしてマウントしている場合に利用できそう。
とにもかくにも Direct IO を使いたくなったので、いろいろ調べて実装はしてみたものをまとめてみる。
【参考文献】
今回お世話になった Web サイトは下記のとおり。二つ目はWebサイトではなく man コマンドでいける。
Direct IO の実装とは言っても別にたいした事をするわけではない。open 時に O_DIRECT フラグをセットするだけで Direct IO モードでディスクリプタを開くことができる。
問題は、そのディスクリプタを利用して read/write をするときである。Direct IO の場合、アライメントされたバッファ領域に対してブロックサイズの倍数でアクセスする必要がある。これをしないと、read/write が -1 を返礼し、エラーとして EINVAL (Invalid Argument) が帰ってくる。
ブロックサイズは Linux 2.6 以上は 512 で良いみたい。アライメントされたバッファ領域を得るためには通常の new や malloc ではなく posix_memalign を利用する。これで準備完了。
あとは動かすだけ・・・と思いきや問題が発生。
今回 read してバッファに入れたいファイルのファイルサイズは 512byte の倍数ではなく中途半端な値。例えば 600byte としよう。この時、512byte で read すると 88byte 余ってしまう。仕方が無いから 1024byte の領域を確保して read するのだがこれをするとなぜかメモリーがリークしてしまう・・・
現在原因を調査中である。一筋縄でいかない Direct IO である。