Direct I/Oのなにがいいかというとページキャッシュを使わないのがいいです。仮想VMのディスクイメージとかそういったものをバックアップするとかでcpしたりすると当然ページキャッシュを使ってくれます。でも、そういったワンタイムなリードやライトをいちいちキャッシュしてもらっても意味ないし、まあイロイロと困るわけですよ。何百GBとかメモリ積んでると困らないようで、余計に困ったり・・・。
Linuxではページキャッシュを使用したくない場合Kernel 2.6からO_DIRECTを使ってDirect I/Oできるのですが、Linus いわく「O_DIRECT でいつも困るのは、インタフェース全部が本当にお馬鹿な点だ。 たぶん危ないマインドコントロール剤で 頭がおかしくなったサルが設計したんじゃないかな」 と言うくらい腐ってます。
Testing disk I/O with the O_DIRECT flagで紹介されてたDirect I/O対応cpパッチがここからダウンとロードできますが
https://oss.oracle.com/~smushran/.coreutils/
すごいことに、というかLinuxの仕様なんですがDirect I/Oでコピーできるファイルのサイズが512Bytesまたは4KBの倍数でなければcpできません(ちなみにFreeBSDやほかのOSにはそんな制限ありません)。腐りすぎ。
コピーしようとするとエラーメッセージを出して異常終了してしまいます。
いくらなんでもこれは酷いので、512Bytesまたは4KBのセクタサイズでとにかくコピって最後に元ファイルのサイズが512Bytesまたは4KBの倍数で終わってなかったらコピった後にtruncateするよう作り直しました。これでどんなサイズでも普通にcpできます。
作り直したパッチはこちらからダウンロードできます。
coreutils-directio.patch
Sunilさん作のcoreutils-directio.patchと差し替えて使ってください。
で、このパッチをあてたcpでは –directio オプションが使えるようになります。
つうか、このcoreutils古いのでもうちと新しいcoreutilsにこのパッチを元に手パッチした方がいいです。私もそうしてます。