これまで2回にわたって解説したファイル・システムですが,今回は,その締めくくりとしてファイル・システムの最下層部分(ハードウエアに近い部分)について解説していきます。

 過去の記事の繰り返しになりますが,Linuxのファイル・システムは図1のような階層構造を採っています。VFS(Virtual File System)という抽象化層を用意することで,さまざまなローカル・ファイル・システムに対応しやすくなっているのです。ローカル・ファイル・システムは,「ファイル」の形式のデータを「ブロック」の形式に変換し,それをデバイス・ドライバを通じてハード・ディスクなどの記録装置に記録します。

図1●ファイル・システムの構造
図1●ファイル・システムの構造
ローカル・ファイル・システムが処理したブロック・データを,ブロック入出力共通層で処理してから,デバイス・ドライバを使ってハード・ディスクに書き込みます。

 今回解説するのは,ブロック・データをカーネルがどのように扱うかについてです。ファイルをブロック・データに変換する仕組みは,ローカル・ファイル・システムごとに異なります。しかし,変換後のブロック・データについては,データの扱い方に違いはありません。最終的に利用するデバイス・ドライバでも,ファイル・システムを作成可能な「ブロック・デバイス」のものでは,共通の処理をします。この共通部分には,処理効率を高めるさまざまな工夫が施されています。

 なお,ブロック・デバイスの対となるデバイスは,データを1バイト単位で入出力する「キャラクタ・デバイス」です。キャラクタ・デバイスはブロック・デバイスと異なり,さまざまな用途に利用されますので,データを処理する共通の仕組みは備えていません。

入出力の際はバッファを経由

 ハード・ディスクなどの記録デバイスは,セクターという単位で形成されています。入出力効率を高める目的から,Linuxでは,複数のセクターをまとめたブロックという単位でデータを記録装置とやり取りします。このブロックは,ローカル・ファイル・システムで変換されるブロックと同じ大きさになっています。

 しかし,ローカル・ファイル・システムが変換したブロック・データが,そのまますぐに記録デバイスに書き込まれるわけではありません。ブロック・データは,一度,バッファ*1と呼ばれるメモリー領域に記録されます(図2)。記録デバイスには,このバッファからデバイス・ドライバがブロック・データを取得して書き込みます。

図2●ブロック入出力はバッファを経由する
図2●ブロック入出力はバッファを経由する
ブロック入出力において,データは一度バッファと呼ばれるメモリー領域を経由します。

 逆に,記録デバイスからファイルを読み出す場合は,まず,デバイス・ドライバが記録デバイスからブロック・データを読み取って,バッファに書き込みます。そして,バッファのデータをローカル・ファイル・システムが読み出して,それをファイルに変換します。

 以前の解説と合わせて,ここまででファイル・システムの基本機能を一通り説明したことになります。確かに,このような仕組みがあれば,ファイル・システムとして機能します。しかし,これだけの実装では,実利用に際して,さまざまな問題が出て来ます。

 その一つが,パフォーマンスの問題です。ご存じの通り,ハード・ディスクなどの記憶装置のアクセス速度は,主メモリーのアクセス速度と比べて極端に遅いのです。

 一般的なシステムでは,OSそのものやデータなど,コンピュータを使うための情報のほとんどすべてをハード・ディスクに納めています。アプリケーションを実行するときは,そのアプリケーション自体のバイナリ・データをハード・ディスクから読み出しますし,利用するデータも同じです。ハード・ディスクへのアクセスは,何か操作を行うたびに起きると言っても過言ではありません。

 処理効率を高めるには,先ほど示した主メモリーとハード・ディスクのアクセス速度の差を小さくしたり,差が大きくならないような工夫をする必要があります。Linuxのファイル・システムにも,さまざまな工夫が凝らしてあります。