04.02.2014 Views

hX1P8B

hX1P8B

hX1P8B

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Linux/OSS Support Center, IBM Japan<br />

Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

Version 1.2<br />

Linux/OSS Support Center<br />

Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

2009/11/6<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

はじめに<br />

• この 資 料 の 内 容 に 関 しては 正 式 な IBM のテストを 受 けておりません。この 資 料 は、 資 料 作 成 時 に<br />

おける 最 新 情 報 をご 参 考 のために 提 供 することを 目 的 として 記 載 されており、IBM は、 情 報 の 正 確<br />

性 、 完 全 性 または 有 用 性 について 何 ら 保 証 するものではありません。また、 内 容 は 予 告 なしに 変 更<br />

または 更 新 されることがあります。<br />

• この 資 料 の 内 容 は、 限 られた 検 証 環 境 における 結 果 に 基 づくものであり、 全 ての 環 境 で 同 一 の 結<br />

果 を 保 証 するものではありません。お 客 様 固 有 の 環 境 に 対 し、 適 切 であるかどうか、また、 正 確 で<br />

あるかどうかは 十 分 検 証 されていません。この 資 料 の 情 報 に 基 づき 導 入 ・ 設 定 を 実 施 される 場 合 に<br />

は、 十 分 な 検 証 テストを 行 ってください。また、 予 め 各 社 より 提 供 される 情 報 および 製 品 のマニュア<br />

ルをご 覧 ください。<br />

• この 資 料 の 情 報 に 基 づいて 導 入 ・ 設 定 ・ 運 用 した 結 果 について、IBM はいかなる 保 証 も 責 任 も 負 い<br />

かねますので 予 めご 了 承 ください。<br />

2 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

前 提<br />

• このドキュメントでは、Linux カーネルのブロックデバイス I/O サブシステムについて 解 説 していま<br />

す。<br />

► Linux カーネルは、キャラクターデバイスとブロックデバイスの 2 種 類 のデバイスを 区 別 して 取 り 扱 います。<br />

このドキュメントは、ブロックデバイスのみを 対 象 としていますので、ブロックデバイス I/O サブシステムのこ<br />

とを、 単 に I/O サブシステムと 表 現 しています。<br />

► 一 般 に、テープデバイスなどのシーケンシャルアクセスのみを 提 供 するデバイスがキャラクターデバイス、<br />

ハードディスクなどのランダムアクセスが 可 能 なデバイスがブロックデバイスに 分 類 されます。<br />

• このドキュメントは、 読 者 の 理 解 を 助 けるために、あえて 厳 密 ではない 表 現 をしている 箇 所 があり<br />

ます。また、Linux カーネルの 内 部 仕 様 は、カーネルバージョン、 適 用 パッチ、および、コンパイル<br />

時 の 設 定 により 変 化 します。このドキュメントの 内 容 は、あくまで、 一 般 的 な 参 考 情 報 としてご 理 解<br />

ください。<br />

• I/O サブシステムの 実 装 は、カーネル 2.4 とカーネル 2.6 で 大 きく 変 化 しています。このドキュメン<br />

トでは、カーネル 2.6 および IA32 アーキテクチャーを 前 提 としています。<br />

3 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

目 次<br />

• I/O サブシステムの 構 造<br />

• VFS (Virtual Filesystem)<br />

• ディスクキャッシュ<br />

• ブロックレイヤー<br />

• I/O リクエストの 発 行<br />

• 参 考 資 料<br />

4 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

I/O サブシステムの 構 造<br />

5 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

I/O サブシステムの 構 造 (1)<br />

• Linux の I/O サブシステムは VFS (Virtual Filesystem) とブロックレイヤーに 分 かれます。<br />

► VFS は、ユーザープロセスとメモリー 上 のディスクキャッシュの 間 のデータ 転 送 を 行 います。<br />

► ブロックレイヤーは、ディスクキャッシュと 物 理 デバイスの 間 のデータ 転 送 を 行 います。<br />

ユーザープロセス<br />

システムコール<br />

ブロックレイヤー<br />

リクエストキュー<br />

リクエストキュー<br />

VFS<br />

I/O スケジューラー<br />

I/O スケジューラー<br />

ファイルシステム<br />

address_space<br />

_operations<br />

デバイスドライバー<br />

file_operations<br />

ディスクキャッシュ<br />

データ 転 送<br />

物 理 デバイス<br />

物 理 デバイス<br />

6 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

I/O サブシステムの 構 造 (2)<br />

• VFS (Virtual Filesystem)<br />

► ユーザープロセスにブロックデバイスを 利 用 するための、 統 一 的 なインターフェースを 提 供 します。<br />

– デバイスに 格 納 されたデータを、デバイスやファイルシステムの 種 類 によらず、ツリー 構 造 のディレクトリ 内 のファイルとし<br />

て 見 せます。<br />

– open(), read(), write(), close() などのシステムコールを 通 じて、 各 ファイルへのアクセスを 提 供 します。<br />

► VFS に 登 録 された 各 ファイルシステムは、データアクセスに 必 要 な 関 数 群 である、file_operations テーブル<br />

と address_space_operations テーブルを 提 供 します。<br />

– file_operations テーブルは、メモリー 上 のディスクキャッシュにデータを 読 み 書 きするための 関 数 群 です。<br />

– address_space_operations テーブルは、ブロックレイヤーのリクエストキューに、 物 理 デバイスとディスクキャッシュの<br />

データ 転 送 を 依 頼 するリクエストを 登 録 するための 関 数 群 です。<br />

• ブロックレイヤー<br />

► 各 物 理 デバイスは、それぞれ 独 立 したリクエストキューを 持 ちます。 各 リクエストキューの I/O スケジューラー<br />

が、キューに 登 録 されたリクエストに 基 づいて、 物 理 デバイスとディスクキャッシュの 間 のデータ 転 送 を 行 いま<br />

す。<br />

– 各 リクエストキューの I/O スケジューラーは、 物 理 デバイスの 特 性 に 応 じて、 異 なったスケジューリングポリシーを 持 つこと<br />

が 可 能 です。<br />

► デバイスドライバーは、 物 理 デバイスにアクセスするために 必 要 な 関 数 を I/O スケジューラーに 提 供 します。<br />

– SCSI デバイスの 場 合 、デバイスドライバー 自 身 も、 上 位 モジュール(sd_mod)、 中 間 モジュール(scsi_mod)、 下 位 モ<br />

ジュール(ホストアダプター 用 ドライバー)からなるレイヤー 構 造 となっています。<br />

7 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルの Read 処 理 の 流 れ<br />

• VFS の 処 理 とブロックレイヤーの 処 理 は、 非 同 期 に 実 行 されます。<br />

• ファイルの read 処 理 は 以 下 の 流 れになります。<br />

► ユーザープロセスはシステムコールにより、read 要 求 を 発 行 します。<br />

► VFS はディスクキャッシュに 該 当 データが 存 在 するか 確 認 します。 (*)<br />

– ディスクキャッシュに 該 当 データが 存 在 する 場 合 、データをユーザープロセスに 返 して、 処 理 を 終 了 します。<br />

► ディスクキャッシュに 該 当 データが 存 在 しない 場 合 、リクエストキューに read 要 求 を 登 録 して、 要 求 を 発 行 し<br />

たユーザープロセスを、 一 旦 sleep 状 態 にします。<br />

– 具 体 的 には、 該 当 するディスクキャッシュのメモリー 領 域 を Lock し、Lock が 解 除 されるまで sleep します。<br />

► リクエストキューの I/O スケジューラーは、リクエストに 応 じて、 物 理 デバイスからディスクキャッシュへのデー<br />

タ 転 送 をデバイスドライバーを 通 じて 行 います。<br />

► ディスクキャッシュへのデータ 転 送 が 完 了 すると、I/O スケジューラーは、 該 当 するディスクキャッシュのメモ<br />

リー 領 域 の Lock を 解 除 します。<br />

– この 時 、Lock 解 除 待 ちで sleep していたユーザープロセスが 再 び 起 動 し、VFS はディスクキャッシュ 上 のデータをユー<br />

ザープロセスに 返 して、 処 理 を 終 了 します。<br />

(*) Linux カーネルはファイルの 先 読 み 機 能 を 持 っており、これが 有 効 な 場 合 は、ディスクキャッシュ 上 の 該 当 データを 検 索 する<br />

前 に、 要 求 されている 範 囲 よりも 先 の 部 分 を 含 めたファイルの 物 理 read 処 理 ( 物 理 デバイスからディスクキャッシュへのデータ<br />

転 送 )を 行 います。ここでは、ファイルの 先 読 み 機 能 は 考 慮 していません。<br />

8 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルの Write 処 理 の 流 れ<br />

• ファイルの write 処 理 は 以 下 の 流 れになります。<br />

► ユーザープロセスはシステムコールにより、write 要 求 を 発 行 します。<br />

► VFS はディスクキャッシュに 該 当 データを 書 き 込 みます。<br />

► ディスクキャッシュの 使 用 状 況 から 物 理 デバイスへのデータ 転 送 ( 書 き 込 み)が 必 要 か 判 断 し、 必 要 に 応 じて、<br />

カーネルスレッド pdflush を 起 動 します。<br />

– pdflush を 起 動 する 条 件 は p.35 『pdflush について』を 参 照 。<br />

– ユーザープロセス 側 の 処 理 は、ここで 終 了 します。<br />

► カーネルスレッド pdflush が、リクエストキューに write 要 求 を 登 録 します。<br />

► リクエストキューの I/O スケジューラーは、リクエストに 応 じて、ディスクキャッシュから 物 理 デバイスへのデー<br />

タ 転 送 をデバイスドライバーを 通 じて 行 います。<br />

9 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

VFS<br />

(Virtual Filesystem)<br />

10 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルシステムの 管 理 オブジェクト<br />

• ext2, ext3, vfat, iso9660 など、 構 造 の 異 なるファイルシステムを 統 一 的 に 扱 うため、ファイルシス<br />

テムの 種 類 によらず、 下 記 の 4 種 類 のデータでファイルを 管 理 します。 (*)<br />

► スーパーブロックオブジェクト<br />

– マウント 中 のファイルシステム 全 体 の 構 成 に 関 する 情 報 を 保 持 します。マウント 中 の 1 つのファイルシステムにつき 、1 つ<br />

のスーパーブロックオブジェクトが 存 在 します。<br />

– スーパーブロックオブジェクトに 格 納 されるデータの 種 類 は 事 前 に 定 義 されていますが、 具 体 的 なデータの 内 容 や 設 定 方<br />

法 は、ファイルシステムによって 異 なります。<br />

► inode オブジェクト<br />

– ディスク 上 の 個 々のファイル、および、ディレクトリの 管 理 情 報 を 保 持 します。1 つのファイル(もしくはディレクトリ)につき、<br />

1 つの inode オブジェクトが 対 応 します。<br />

– ファイルシステムのマウント 時 に 全 てのファイルの inode オブジェクトを 作 成 するのではなく、ディスク 上 のファイルにアク<br />

セスしたタイミングで、そのファイルに 対 する inode オブジェクトを 作 成 します。<br />

► file オブジェクト<br />

– オープン 中 のファイルの 管 理 情 報 を 保 持 します。<br />

– 同 一 のファイルを 複 数 のプロセスがオープンした 場 合 、 同 一 のファイルに 対 して、 複 数 の file オブジェクトが 作 成 されます。<br />

► dentry オブジェクト<br />

– ファイルの 存 在 するディレクトリパス 名 から 対 応 するファイルの inode オブジェクトをポイントするオブジェクトです。<br />

– ディレクトリパス 名 でファイルが 指 定 されたときに、 対 応 する inode オブジェクトをすばやく 検 索 するために 利 用 します。<br />

(*) これらの『オブジェクト』は、カーネルメモリー 上 の 変 数 に 格 納 されるデータであり、ext2/ext3 ファイルシステムの<br />

( 物 理 ディスク 上 に 存 在 する)スーパーブロック、および、inode とは 異 なる 概 念 です。<br />

11 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルシステム 固 有 の 情 報<br />

• カーネルが 利 用 可 能 なファイルシステムは、file_system_type オブジェクトに 登 録 されています。<br />

► 各 ファイルシステムを 使 用 するためのカーネルモジュールをロードした 時 に、 該 当 ファイルシステムの 情 報 を<br />

持 つ file_system_type オブジェクトが 作 成 されます。<br />

► file_system_type オブジェクトは、スーパーブロックオブジェクトにデータを 設 定 する 関 数 get_sb() を 提 供 し<br />

ます。get_sb() は、 必 要 に 応 じて 物 理 ディスク 上 の 情 報 を 読 み 込 み (*) 、inode オブジェクトを 操 作 する 関 数 群<br />

(super_operations テーブル)をスーパーブロックオブジェクトに 登 録 します。 super_operations テーブルは、<br />

各 ファイルシステムに 固 有 の 関 数 となります。<br />

• 物 理 ディスク 上 のデータの 配 置 方 法 は、ファイルシステムによって 異 なります。super_operations<br />

テーブルを 起 点 として、このような、ファイルシステム 固 有 の 設 定 がなされていきます。<br />

► super_operations テーブルは、inode オブジェクトを 操 作 する 関 数 を 提 供 します。 特 に、inode オブジェクトを<br />

作 成 する 関 数 を 含 みます。<br />

► super_operations テーブルから 作 成 された inode オブジェクトは、ディスクキャッシュにアクセスする 関 数 群<br />

(file_operations テーブル)、および、 物 理 ディスクへのアクセス 要 求 をリクエストキューに 登 録 する 関 数 群<br />

(address_space_operations テーブル)を 含 みます。address_space_operations テーブルの 関 数 群 は、ファ<br />

イルシステムに 固 有 の 配 置 で 物 理 ディスク 上 にファイルのデータを 配 置 します。<br />

(*) 例 えば、ext2/ext3 ファイルシステムの 場 合 、get_sb() は、( 物 理 ディスク 上 に 存 在 する)ファイルシステムのスーパー<br />

ブロックを 読 み 込 んで、スーパーブロックオブジェクトのデータの 一 部 として 格 納 します。ただし、スーパーブロックオブ<br />

ジェクトは、スーパーブロックそのものよりも 広 範 なデータや 機 能 を 持 っています。<br />

12 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

管 理 オブジェクトの 関 係<br />

• これまでに 紹 介 した 管 理 オブジェクトの 関 連 を 表 す 図 です。 例 として、ユーザープロセス 1 と 2 が /<br />

にマウントした ext2 ファイルシステム(ルートファイルシステム)の /var/log/messages ファイルを<br />

参 照 している 状 況 を 示 しています。<br />

► 詳 細 は 次 ページからの 説 明 を 参 照 してください。<br />

file_system_type<br />

ext2<br />

get_sb()<br />

マウント 中 のファイルシステム /<br />

スーパーブロックオブジェクト<br />

物 理 デバイス<br />

ポインターによる 参 照<br />

関 数 による 操 作<br />

super_operations<br />

inode オブジェクト<br />

address_space<br />

_operations<br />

データ 転 送<br />

dentry オブジェクト<br />

/var/log/messages<br />

ディスクキャッシュ<br />

ユーザープロセス 1<br />

ファイル<br />

ディスクリプター<br />

file オブジェクト<br />

file_operations<br />

ユーザープロセス 2<br />

file オブジェクト<br />

13 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルシステムのマウント 処 理<br />

• マウントするファイルシステムの 種 類 に 応 じた file_system_type オブジェクトの 情 報 に 基 づいて、<br />

スーパーブロックオブジェクトが 作 成 され、super_operations テーブルが 定 義 されます。<br />

► file_system_type オブジェクトに 登 録 された get_sb() 関 数 が 物 理 デバイスから 必 要 なデータを 読 み 込 んで、<br />

スーパーブロックオブジェクトにデータとして 格 納 します。 ext2 ファイルシステムであれば、 物 理 デバイス 上 の<br />

スーパーブロックが 読 み 込 まれます。<br />

• 右 図 は ext2 ファイルシステムの super_operations<br />

の 定 義 です。 定 義 名 から inode オブジェクトを 操 作<br />

する 関 数 が 含 まれていることが 想 像 できます。<br />

► 特 に .read_inode 関 数 (ext2_read_inode)は、 物 理 デ<br />

バイスから ext2 ファイルシステムの inode 情 報 を 読 み<br />

込 んで、 対 応 する inode オブジェクトを 構 成 する 関 数 で<br />

す。これにより、 物 理 ディスク 上 の 個 々のファイルにアク<br />

セスする 準 備 ができたと 言 えます。<br />

► また、read_inode は、 各 inode オブジェクトに 対 して<br />

file_operations テーブルと address_space_operations<br />

テーブルも 定 義 します。(ここで 定 義 された<br />

file_operations は、file オブジェクトが 作 成 された 時 に、<br />

各 file オブジェクトにコピーされます。)<br />

static struct super_operations ext2_sops = {<br />

.alloc_inode = ext2_alloc_inode,<br />

.destroy_inode = ext2_destroy_inode,<br />

.read_inode = ext2_read_inode,<br />

.write_inode = ext2_write_inode,<br />

.delete_inode = ext2_delete_inode,<br />

.put_super = ext2_put_super,<br />

.write_super = ext2_write_super,<br />

.statfs = ext2_statfs,<br />

.remount_fs = ext2_remount,<br />

.clear_inode = ext2_clear_inode,<br />

#ifdef CONFIG_QUOTA<br />

.quota_read = ext2_quota_read,<br />

.quota_write = ext2_quota_write,<br />

#endif<br />

};<br />

14 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

inode オブジェクトの 作 成<br />

• 指 定 のファイルパスから、 物 理 ディスク 上 のファイルを 検 索 し、 対 応 する inode オブジェクトを 作 成<br />

する 処 理 は 下 記 の 流 れで 行 われます。( 例 として /var/log/messages ファイルの 場 合 を 示 します。)<br />

► ファイルシステムのマウント 時 に、マウントポイントのディレクトリに 対 応 する inode オブジェクトおよび dentry<br />

オブジェクトが 作 成 されています。 一 般 に、ディレクトリの inode オブジェクトは、ディレクトリ 直 下 のファイルお<br />

よびサブディレクトリを 検 索 し、それらの inode オブジェクトを 新 規 に 作 成 する 機 能 を 持 ちます。<br />

► 指 定 されたファイルパスの 起 点 となるディレクトリ / の inode オブジェクトを 利 用 して、その 直 下 のディレクトリ<br />

/var の inode オブジェクトを 作 成 します。( 必 要 に 応 じて、 物 理 ディスクから /var ディレクトリの inode を 読 み 込<br />

みます。)また、この 結 果 を 記 憶 する 意 味 で、”/var” というパス 名 に 対 して、 対 応 する inode オブジェクトをポイ<br />

ントする dentry オブジェクトも 作 成 します。<br />

– 次 回 に /var の inode オブジェクトが 必 要 になった 場 合 は、 再 度 、/ の inode オブジェクトから 検 索 するのではなく、/var に<br />

対 応 する dentry から、ポイントされる inode オブジェクトを 取 得 します。<br />

– シンボリックリンクなどにより、 同 一 のファイルが 複 数 のファイルパスを 持 つ 場 合 、それぞれのファイルパスに 対 応 した<br />

dentry が 作 成 されますが、これらは、 同 一 の inode オブジェクトをポイントします。<br />

► 同 様 に /var の inode オブジェクトを 利 用 して、/var/log の inode オブジェクトと、 対 応 する dentry オブジェク<br />

トを 作 成 します。 ( 必 要 に 応 じて、 物 理 ディスクから /var/log ディレクトリの inode を 読 み 込 みます。)<br />

► 最 後 に /var/log の inode オブジェクトから /var/log/messages の inode オブジェクトと、 対 応 する dentry オ<br />

ブジェクトを 作 成 します。<br />

• 上 記 のように、ファイルパス 名 に 含 まれるディレクトリの inode オブジェクトを 順 に 構 成 することで、<br />

任 意 のファイルの inode オブジェクトを 取 得 することができます。<br />

15 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルのオープン 処 理<br />

• ユーザープロセスが 指 定 したファイルパスに 基 づいて、 該 当 するファイルをオープンする 処 理 は、 下<br />

記 の 流 れで 行 われます。<br />

► 前 ページの 処 理 により、 指 定 したファイルパスから 該 当 するファイルの inode オブジェクトと dentry オブジェ<br />

クトを 作 成 します。 また、 新 たに file オブジェクトを 作 成 し、dentry オブジェクトへのポインターを 設 定 します。<br />

– file オブジェクトは、 該 当 ファイルをオープンするごとに 作 成 されます。 複 数 のプロセスが 同 一 のファイルをオープンした 場<br />

合 、 同 一 の dentry オブジェクトをポイントする、 複 数 の file オブジェクトが 作 成 されます。<br />

► inode オブジェクトが 保 持 する file_operations テーブルを file オブジェクトにコピーします。<br />

– file_operations は、 該 当 ファイルの 内 容 をディスクキャッシュに 対 して 読 み 書 きする 関 数 を 提 供 します。 特 殊 なオプション<br />

でファイルをオープンした 場 合 、オプションに 応 じて、コピーされた file_operations が 修 正 されることもあります。<br />

► ユーザープロセスのファイルディスクリプターテーブルに file オブジェクトへのポインターを 設 定 します。(ファ<br />

イルディスクリプターテーブルについては 次 ページを 参 照 。)<br />

• 以 上 の 結 果 、ユーザープロセスは、ファイルディスクリプターから file オブジェクトを 取 得 して、 該 当<br />

ファイルにアクセスすることが 可 能 となります。<br />

► ユーザープロセスがファイルディスクリプタを 指 定 して、read()、write() などのシステムコールを 発 行 すると、<br />

それに 対 応 する file_operations が 実 行 され、ディスクキャッシュとのデータのやりとりが 発 生 します。(ディスク<br />

キャッシュと 物 理 ディスクの 間 のデータ 転 送 については、 次 章 で 説 明 します。)<br />

16 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ファイルディスクリプターテーブルについて<br />

• 各 ユーザープロセスは、ファイルオブジェクトへのポインターを 格 納 する 配 列 を 持 ちます。これを、<br />

ファイルディスクリプターテーブルといいます。<br />

► この 配 列 の 添 字 番 号 が、いわゆる、ファイルディスクリプター 番 号 になります。 通 常 、0, 1, 2 番 はそれぞれ、<br />

標 準 入 力 、 標 準 出 力 、 標 準 エラー 出 力 に 対 応 するファイルオブジェクトをポイントします。<br />

► 各 ファイルディスクリプターに 対 応 するファイルは proc ファイルシステムから 確 認 することができます。ディレ<br />

クトリ /proc//fd/ の 下 にファイルディスクリプター 番 号 があり、 対 応 するファイルへのシンボリックリンクと<br />

なっています。<br />

– 図 は sendmail プロセスのファイルディスクリプターの 例 です。Linux カーネルは、ネットワークソケットも file オブジェクト<br />

で 管 理 しており、この 例 では、3 番 と 4 番 が TCP ソケットをポイントしています。<br />

# ls -l /proc/2417/fd/<br />

total 6<br />

lr-x------ 1 root root 64 Jan 18 16:03 0 -> /dev/null<br />

l-wx------ 1 root root 64 Jan 18 16:03 1 -> /dev/null<br />

l-wx------ 1 root root 64 Jan 18 16:03 2 -> /dev/null<br />

lrwx------ 1 root root 64 Jan 18 16:03 3 -> socket:[5459]<br />

lrwx------ 1 root root 64 Jan 18 16:03 4 -> socket:[5452]<br />

l-wx------ 1 root root 64 Jan 18 16:03 5 -> /var/run/sendmail.pid<br />

17 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ディスクキャッシュ<br />

18 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ディスクキャッシュの 種 類<br />

• ディスクキャッシュには、ページキャッシュとバッファキャッシュの 2 種 類 があります。<br />

► ファイルシステム 上 のファイルにアクセスする 場 合 は、ページキャッシュを 使 用 します。ファイルシステムを 経<br />

由 せずに、ブロックデバイスに 直 接 アクセスする 場 合 は、バッファキャッシュを 使 用 します。 (*)<br />

– 後 者 の 例 には、ユーザープロセスが、デバイスファイル(/dev/sda など)を 介 してブロックデバイスにアクセスする 場 合 と、<br />

Linux カーネルが(スーパーブロックや inode を 読 み 取 るために)ブロックデバイス 上 の 特 定 の 1 つのブロックのデータに<br />

アクセスする 場 合 があります。<br />

► free コマンドや vmstat コマンドでは、ページキャッシュとして 使 用 しているメモリー 容 量 とバッファキャッシュと<br />

して 使 用 しているメモリー 容 量 をそれぞれ 確 認 することができます。<br />

# f r e e<br />

t o t a l u s e d f r e e s h a r e d b u f f e r s c a c h e d<br />

M e m : 1 2 6 2 0 8 1 1 1 9 9 2 1 4 2 1 6 0 1 2 3 7 6 4 8 5 1 6<br />

- / + b u f f e r s / c a c h e : 5 1 1 0 0 7 5 1 0 8<br />

S w a p : 2 6 5 0 6 4 0 2 6 5 0 6 4<br />

# v m s t a t<br />

p r o c s - - - - - - - - - - - m e m o r y - - - - - - - - - - - - - s w a p - - - - - - - i o - - - - - - s y s t e m - - - - - - c p u - - - -<br />

r b s w p d f r e e b u f f c a c h e s i s o b i b o i n c s u s s y i d w a<br />

0 0 0 1 4 2 1 6 1 2 3 7 6 4 8 5 1 6 0 0 5 6 1 0 1 0 2 8 0 2 9 6 1<br />

(*) カーネル 2.4 とカーネル 2.6 でバッファキャッシュの 使 い 方 が 変 わっており、カーネル 2.4 では、この 関 係 は 成 り 立 ちません。<br />

19 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ディスク 上 のデータ 配 置<br />

• 物 理 ディスクは、 通 常 、512B のセクター 単 位 でデータを 書 き 込 みます。<br />

• 各 ファイルシステムには、セクターの 整 数 倍 の 大 きさのブロックサイズが 定 義 されており、ファイルシ<br />

ステム 内 のファイルは、この 大 きさのブロック 単 位 に 分 割 して 物 理 ディスクに 書 き 込 まれます。<br />

► ブロック 内 のデータは、 物 理 ディスク 上 で 連 続 した 領 域 に 書 き 込 まれることが 保 証 されます。<br />

► 1 つのファイルが 複 数 のブロックに 跨 る 場 合 、 異 なるブロックは、 物 理 ディスク 上 で 離 れた 位 置 に 配 置 される<br />

場 合 もあります。<br />

► ext2/ext3 ファイルシステムのブロックサイズは、ファイルシステムの 作 成 時 に mke2fs コマンドの –b オプショ<br />

ンで 指 定 します。 作 成 済 みのファイルシステムのブロックサイズは 図 の tune2fs コマンドで 確 認 できます。<br />

ファイルデータ<br />

・・・<br />

# t u n e 2 f s - l / d e v / s d a 1 | g r e p " B l o c k s i z e "<br />

B l o c k s i z e : 1 0 2 4<br />

物 理 ディスク<br />

1 つのブロック<br />

20 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ページキャッシュの 構 造<br />

• Linux カーネルは、メモリーを 4KB のページと 呼 ばれる 単 位 に 分 割 して 管 理 します。 (*)<br />

• ページキャッシュに 割 り 当 てられたメモリーページには、ファイルの 連 続 する 領 域 のデータがブロッ<br />

ク 単 位 で 書 き 込 まれます。<br />

► ファイルシステムのブロックサイズは、 整 数 倍 が 4KB のページサイズに 一 致 する 大 きさのみが 選 択 可 能 です。<br />

具 体 的 には、512B, 1KB, 2KB, 4KB のいずれかになります。<br />

► 1 つのページキャッシュ 内 のブロックで、 物<br />

理 ディスク 上 で 連 続 した 領 域 に 書 き 込 まれて<br />

いる 部 分 を、 特 に、セグメントといいます。<br />

ファイルデータ<br />

セグメント<br />

・・・<br />

• ページキャッシュと 物 理 ディスクの 間 の<br />

データ 転 送 は、 原 則 として、ページ 単 位 で<br />

行 われます。<br />

► 通 常 、ページ 内 の 一 部 のブロックのみを 物<br />

理 ディスクに 対 して 読 み 書 きすることはありま<br />

せん。<br />

ページキャッシュ<br />

物 理 ディスク<br />

(*) このドキュメントでは、ディスクキャッシュ(ページキャッ<br />

シュ、もしくは、バッファキャッシュ)として 使 用 されるメモ<br />

リーページを、 一 般 に、『キャッシュページ』と 呼 びます。<br />

1 つのブロック<br />

21 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ページキャッシュの 管 理<br />

• Linux カーネルは、 各 ページについて、そのページの 情 報 を 記 憶 するページディスクリプターを 持 ち<br />

ます。 特 に、ページキャッシュに 割 り 当 てられたページでは、 対 応 するページディスクリプター 内 の 変<br />

数 に、 下 記 の 情 報 が 保 存 されます。<br />

► mapping : ファイルの inode オブジェクトに 含 まれる address_space オブジェクトへのポインター<br />

– 各 inode オブジェクトは、その 中 に、address_space オブジェクトと 呼 ばれるデータを 持 ちます。mapping 変 数 は、その<br />

ページにデータが 保 存 されたファイルの inode オブジェクトに 含 まれる、address_space オブジェクトをポイントします。<br />

► index : ファイル 内 のデータの 位 置<br />

– そのページに 保 存 されたデータの、 該 当 ファイル 内 での 位 置 (ページサイズ 単 位 で 先 頭 から 何 個 目 の 位 置 か)を 表 します。<br />

► flags : キャッシュの 状 態 を 表 すフラグ<br />

– PG_dirty : キャッシュの 内 容 が 物 理 ディスクに 書 き 出 されていないことを 示 します。<br />

– PG_writeback : キャッシュの 内 容 を 物 理 ディスクに 書 き 出 す 処 理 が 実 行 中 であることを 示 します。<br />

– PG_locked : ページにアクセスロックがかけられていることを 示 します。<br />

• 上 記 の 情 報 により、そのページキャッシュに 含 まれるデータが、どのファイルのどの 位 置 に 対 応 する<br />

かが 分 かります。 (*)<br />

► mapping 変 数 でポイントされる address_space オブジェクトを 所 有 する inode オブジェクトを 特 定 することで、<br />

どのファイルのデータが 含 まれるかが 分 かります。<br />

► index 変 数 の 値 から、 該 当 ファイルのどの 位 置 のデータが 含 まれるかが 分 かります。<br />

(*) 逆 に、あるファイルの 特 定 の 位 置 のデータを 含 むページキャッシュを 検 索 するために、Linux カーネルは、Radix Tree と<br />

呼 ばれる、 検 索 用 ツリーデータも 保 持 しています。<br />

22 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

バッファーキャッシュの 構 造<br />

• ファイルシステム 上 のファイルを 介 さずに、ブロックデバイスに 直 接 アクセスする 場 合 、 物 理 ディスク<br />

とディスクキャッシュの 間 のデータ 転 送 は、ブロック 単 位 で 行 われます。<br />

► これは、ユーザープロセスが、デバイスファイル(/dev/sda など)を 介 してブロックデバイスにアクセスする 場<br />

合 と、Linux カーネルが(スーパーブロックや inode を 読 み 取 るために) 特 定 の 1 つのブロックにアクセスする<br />

場 合 があります。<br />

• バッファーキャッシュは、メモリーページをバッファーページとして 割 り 当 てた 後 、バッファーページを<br />

ブロックサイズのブロックブッファーに 分 割 することで 作 成 します。<br />

► データ 構 造 上 は、バッファーページはページキャッシュと 同 じ 構 造 を 持 っており、 後 述 のバッファーヘッドがア<br />

サインされている 点 のみが 異 なります。 (*)<br />

• バッファーページに 対 応 するページディスクリプターには、 下 記 の 情 報 が 保 存 されます。<br />

► mapping : ブロックデバイスに 対 応 するデバイスファイル(/dev/sda など)の inode オブジェクトに 含 まれる<br />

address_space オブジェクトへのポインター<br />

– VFS の 機 能 により、デバイスファイルに 対 しても inode オブジェクトが 提 供 されます。<br />

► private : バッファーページ 内 の、 先 頭 のブロックバッファーに 対 するバッファーヘッドへのポインター<br />

– 各 ブロックバッファーには、その 情 報 を 保 存 するバッファーヘッドがアサインされます。バッファーページ 内 のバッファーヘッ<br />

ドは、 次 ページの 図 のように 循 環 するポインターで 互 いをポイントしています。<br />

(*) ページキャッシュも、 物 理 ディスクとの 読 み 書 きのタイミングで、 補 助 的 にバッファーヘッドを 使 用 します。<br />

23 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

バッファーキャッシュの 管 理<br />

• バッファーヘッドには、 対 応 するブロックバッファーの 下 記 の 情 報 が 保 存 されます。<br />

► b_dev : 対 応 するブロックデバイスを 示 すディスクリプターへのポインター<br />

► b_data : バッファーページ 内 のブロックバッファーの 位 置<br />

– 先 頭 から 何 個 目 のブロックバッファーかを 表 します。<br />

► b_blocknr : ブロックデバイス 内 のデータの 位 置<br />

– そのブロックバッファーに 保 存 されたブロックの、ブロックデバイス 内 での 位 置 (ブロック 単 位 で 先 頭 から 何 個 目 か)を 表 し<br />

ます。<br />

►b_state : ブロックバッファーの 状 態 を 表 すフラグ<br />

– BH_Uptodate : ブロックバッファーに 最 新 の<br />

データが 読 み 込 まれていることを 示 します。<br />

– BH_Dirty : ブロックバッファーの 内 容 が 物 理<br />

ディスクに 書 き 出 されていないことを 示 します。<br />

– BH_Lock : ブロックバッファーにアクセスロッ<br />

クがかけられていることを 示 します。<br />

ページディスクリプター<br />

バッファーヘッド<br />

• 上 記 の 情 報 により、ブロックバッファーに<br />

含 まれるデータが、どのデバイスのどの<br />

位 置 に 対 応 するかが 分 かります。<br />

バッファーページ<br />

ブロックバッファー<br />

24 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ブロックレイヤー<br />

25 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

ブロックレイヤーの 管 理 オブジェクト<br />

• ブロックレイヤーは、 物 理 デバイスに 対 するデータの 読 み 書 きを 実 施 するために、 下 記 の 4 種 類 の<br />

オブジェクトを 利 用 します。<br />

► gendisk オブジェクト<br />

– 個 々の 物 理 ディスクについて、その 構 成 情 報 、デバイス 番 号 (メジャー 番 号 、マイナー 番 号 )などのデータを 保 持 します。<br />

特 に、 次 のリクエストキューオブジェクトへのポインターを 持 ちます。<br />

► リクエストキューオブジェクト<br />

– 1 つの gendisk オブジェクトに 対 して、1 つのリクエストキューオブジェクトが 割 り 当 てられます。これは、リクエストオブ<br />

ジェクトが 連 なるキューと、 個 々のリクエストを 実 際 に 処 理 する I/O スケジューラーから 成 ります。<br />

► リクエストオブジェクト<br />

– 物 理 ディスクに 対 するデータの 読 み 書 きを 依 頼 するリクエストデータである bio オブジェクトをまとめたオブジェクトです。リ<br />

クエストキューが 新 たな bio を 受 け 取 ると、リクエストキュー 内 の 既 存 のリクエストに 追 加 するか、もしくは、 新 たなリクエス<br />

トを 作 成 して、キューに 追 加 します。<br />

– 1 つのリクエストオブジェクトに 含 められる bio オブジェクトの 構 成 は、I/O スケジューラーのアルゴリズムによって 決 まりま<br />

す。データ 転 送 は、リクエスト 単 位 で 処 理 されますので、ユーザープロセスの PID 単 位 でリクエストを 分 けて、 全 てのプロ<br />

セスのリクエストを 平 等 に 受 け 付 ける、などのアルゴリズムが 考 えられます。 (*)<br />

► bio オブジェクト<br />

– ディスクアクセスリクエストの 最 小 単 位 であり、 物 理 ディスク 上 の 1 つの 連 続 した 領 域 に 対 する、データの 読 み 書 きのリク<br />

エストを 記 述 します。<br />

(*) 実 際 には、Linux カーネルには、 後 述 の 4 種 類 のアルゴリズムが 実 装 されており、 個 々のリクエストキューは、それぞれ<br />

異 なるアルゴリズムの I/O スケジューラーを 持 つことができます。<br />

26 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

bio オブジェクトの 構 造 (1)<br />

• bio オブジェクトは、 物 理 ディスク 上 の 1 つの 連 続 領 域 に 対 するアクセス 要 求 を 表 し、 次 のデータを<br />

持 ちます。<br />

► bi_sector : アクセスする 領 域 の 最 初 のセクター 番 号<br />

► bi_size : 転 送 するデータ 量 (Byte)<br />

► bi_rw : データ 転 送 の 方 向 (Read または Write)<br />

► bi_io_vec : この bio に 含 まれる bio_vec オブジェクトの 配 列 へのポインター( 次 の 説 明 を 参 照 )<br />

► bi_end_io : この bio に 含 まれるデータ 転 送 か 完 了 したときに 実 行 する 関 数 へのポインター<br />

• 一 般 に、 物 理 ディスク 上 の 連 続 領 域 に 対 応 するディスクキャッシュは、 複 数 のセグメントに 分 割 され<br />

ます。1 つの bio オブジェクト 内 に 含 まれる 各 セグメントは、bio_vec オブジェクトで 表 現 されます。<br />

► 例 えば、2 ページ 分 のキャッシュのデータ<br />

が、 図 のように 配 置 されていた 場 合 、この 2<br />

ページ 分 のデータ 転 送 要 求 は、 次 のように<br />

表 現 されます。<br />

– 物 理 ディスク 上 の 連 続 領 域 が 2 つあるので、<br />

対 応 する 2 つの bio で 表 現 されます。<br />

– 各 bio は、それぞれ 2 つのセグメントを 持 つ<br />

ので、それぞれ 2 つの bio_vec を 持 ちます。<br />

– 図 で bio 1は、セグメント1とセグメント4の<br />

bio_vec を 持 ちます。bio 2は、セグメント2<br />

とセグメント3の bio_vec を 持 ちます。<br />

ページキャッシュ<br />

セグメント1 セグメント2 セグメント3 セグメント4<br />

物 理 ディスク<br />

bio 1<br />

bio 2<br />

27 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

bio オブジェクトの 構 造 (2)<br />

• bio_vec オブジェクトは 次 のデータを 持 ちます。<br />

► bv_page : 対 応 するキャッシュページのページディスクリプターへのポインター<br />

► bv_len : セグメントの 大 きさ(Byte)<br />

► bv_offset : キャッシュページ 内 のセグメントの 開 始 位 置 (Byte)<br />

• 図 は、bio オブジェクトが、 物 理 ディスク 領 域 を、データを 転 送 するべきメモリー 領 域 とどのように 結<br />

び 付 けているかを 表 しています。<br />

bv_page<br />

bio_vec オブジェクト<br />

bv_len = 512 × 3<br />

bi_io_vec<br />

bio オブジェクト<br />

bi_size = 512 × 6<br />

bv_page<br />

bv_offset = 0<br />

bio_vec オブジェクト<br />

bv_len = 512 × 3<br />

bv_offset = 512<br />

bi_sector<br />

物 理 ディスク<br />

ページ<br />

キャッシュ<br />

セグメント1<br />

セグメント4<br />

ページディスクリプター<br />

ページディスクリプター<br />

28 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

リクエストキューオブジェクトの 仕 組 み<br />

• 各 リクエストキューオブジェクトは bio オブジェクトを 受 け 取 る 関 数 make_request_fn を 提 供 します。<br />

► bio オブジェクトを 受 け 取 ると、リクエストキューオブジェクトに 付 随 する I/O スケジューラーのアルゴリズムに<br />

従 って、キュー 内 の 既 存 のリクエストオブジェクトに 追 加 するか、もしくは、 新 たなリクエストオブジェクトを 作 成 し<br />

て、キューに 追 加 します。<br />

• リクエストキューオブジェクトは、キューに 溜 まったリクエストを 処 理 するモード(device unplugging)<br />

と、 実 際 のデータ 転 送 は 行 わず、キューにリクエストを 溜 めていくモード(device plugging)を 切 り 替<br />

えながら 処 理 を 進 めます。<br />

► unplugging、および、plugging を 実 行 するタイミングは、 厳 密 には、I/O スケジューラーのアルゴリズムに 依<br />

存 します。 大 雑 把 には、3 msec (もしくは、4 個 以 上 のリクエストオブジェクトがキューに 溜 まるまで)の<br />

plugging の 後 、 全 てのリクエストがなくなるまで unplugging されます。<br />

► このようにして、 物 理 的 に 連 続 する 領 域 のリクエスト(bio)を、さらに、ある 程 度 、 溜 めてから 処 理 することで、<br />

ディスクヘッドの 動 きの 少 ない、 最 適 化 されたデータアクセスを 実 現 します。<br />

• リクエストキューオブジェクトは、 自 分 が 所 属 する gendisk オブジェクトに 対 応 したデバイスドライ<br />

バーの 情 報 を 持 っており、 最 終 的 なデータ 転 送 処 理 は、デバイスドライバーを 通 じて 実 行 します。<br />

► デバイスドライバーは、1 つの bio に 対 する 処 理 が 終 るごとに、bio オブジェクトの bi_end_io データで 指 定 さ<br />

れた 関 数 を 実 行 します。Read アクセスの 場 合 、この 関 数 は、 通 常 、 対 応 するキャッシュページのロックを 解 放<br />

します。(p.8 『ファイルの Read 処 理 の 流 れ』を 参 照 。)<br />

29 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

I/O スケジューラーの 動 作 概 要<br />

• I/O スケジューラーは、 次 のようにして、bio オブジェクトの 受 け 入 れと、 物 理 I/O の 実 施 を 行 います。<br />

► リクエストキューオブジェクトが 関 数 make_request_fn で 受 け 取 った bio オブジェクトは、 一 旦 、I/O スケ<br />

ジューラーに 固 有 のサブキュー 内 にリクエストオブジェクトとして 追 加 され、その 後 、I/O スケジューラーのアル<br />

ゴリズムに 従 って、 実 際 に I/O 処 理 を 行 う 順 序 でディスパッチキューに 移 動 されます。<br />

► ディスパッチキューにある 程 度 のリクエストオブジェクトがたまると、 対 応 するデバイスドライバーが 提 供 する<br />

request_fn 関 数 を 呼 び 出 して device unplugging モードに 移 行 します。デバイスドライバーが、ディスパッチ<br />

キューに 含 まれる 全 てのリクエストの 処 理 を 終 えると、 再 び device plugging モードに 移 行 して、ディスパッチ<br />

キューへのリクエストの 移 動 を 再 開 します。<br />

– ディスパッチキューに 含 まれるリクエストをどのような 順 序 で 処 理 するかは、デバイスドライバーの 実 装 に 依 存 します。<br />

デバイス<br />

ドライバー<br />

request_queue<br />

オブジェクト<br />

make_request_fn<br />

リクエストオブジェクト<br />

request_fn<br />

queue_head<br />

リクエストオブジェクトに<br />

従 って 物 理 I/O を 実 施<br />

ディスパッチキュー<br />

サブキュー<br />

物 理 デバイス<br />

I/O スケジューラー<br />

30 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

I/O スケジューラーの 選 択<br />

• デフォルトの I/O スケジューラーは、カーネルの 起 動 オプション elevator で 指 定 可 能 で、 下 記 の 4<br />

種 類 が 選 択 可 能 です。<br />

► noop (No Optimization)<br />

– 受 け 取 った bio は、 物 理 ディスク 上 のセクターの 位 置 に 応 じて、キューの 先 頭 、または、キューの 末 尾 に 追 加 されます。<br />

► cfq (Complete Fairness Queueing)<br />

– 受 け 取 った bio は、それを 送 ったユーザープロセスの PID をキーとするハッシュで 64 本 のサブキューに 分 類 されます。<br />

次 に、 各 サブキューから 一 定 量 のリクエストを 順 に 処 理 していきます。これにより、 各 プロセスに 対 して 公 平 に I/O の 処 理<br />

が 実 行 されます。<br />

► deadline (Deadline)<br />

– 受 け 取 った bio は、 物 理 ディスク 上 のセクターの 位 置 に 応 じて、キュー 上 の 既 存 のリクエストの 中 の 最 適 な 位 置 (ディスク<br />

ヘッドの 動 きを 最 小 とする 位 置 )に 挿 入 されます。ただし、キューの 前 のリクエストに 新 しい bio が 挿 入 され 続 けて、 一 定 時<br />

間 、 処 理 されなかったリクエストは 優 先 的 に 処 理 が 行 われます。(この “Deadline” 時 間 は、Read リクエストで 500 msec、<br />

Write リクエストで 5 sec です。)<br />

► as (Anticipatory)<br />

– Deadline に 対 して、 次 に 受 け 取 る bio を『 予 想 する』 機 能 を 追 加 したものです。 例 えば、プロセス A からの Read 要 求 を<br />

受 け 取 った 直 後 に、プロセス B からの 要 求 を 受 け 取 った 場 合 、プロセス A からの Read 要 求 が 続 けて 送 られる 可 能 性 が<br />

高 いため、プロセス B の 要 求 を 処 理 する 前 に、 一 定 時 間 (7 msec 程 度 )、 次 のリクエストを 待 ちます。<br />

• これらのアルゴリズムは、ドライブヘッドが 1 つの、 単 純 なハードディスク 装 置 を 前 提 としています。<br />

► RAID コントローラーなどを 持 つディスクシステムの 場 合 は、ディスクシステム 自 身 がアクセス 処 理 の 最 適 化<br />

を 行 いますので、noop が 推 奨 される 場 合 もあります。<br />

31 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

I/O リクエストの 発 行<br />

32 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

bio の 組 み 立 てとリクエストの 発 行<br />

• 実 際 に bio を 作 成 し、make_request_fn を 呼 び 出 してリクエストキューに 登 録 する 処 理 は、 各 ファイ<br />

ルの inode オブジェクトの address_space_operations テーブルに 登 録 された readpage、<br />

readpages および、writepages 関 数 が 行 います。 (*)<br />

► ページキャッシュ 上 のデータが 物 理 ディスク 上 のどの 位 置 に 配 置 されるかは、 各 ファイルシステムのアルゴリ<br />

ズムで 決 まりますので、address_space_operations は、ファイルシステムごとに 定 義 されています。<br />

• これらの 関 数 は、 物 理 ディスク 上 の 連 続 領 域 ごとに 1 つの bio オブジェクトを 作 成 し、<br />

make_request_fn で 対 応 するリクエストキューに 登 録 します。<br />

• これらの 関 数 が 実 行 される、 主 なタイミングは 次 の 通 りです。<br />

► p.8 『ファイルの read 処 理 の 流 れ』の『リクエストキューに read 要 求 を 登 録 』の 部 分 で、 readpage 関 数 が 実<br />

行 されます。( 同 ページの 脚 注 に 記 載 の、『ファイルの 先 読 み 機 能 』でデータを 読 み 込 む 時 は、 複 数 のページを<br />

連 続 的 に 処 理 する readpages 関 数 が 実 行 されます。)<br />

► p.9 『ファイルの write 処 理 の 流 れ』の『カーネルスレッド pdflush が、リクエストキューに write 要 求 を 登 録 』<br />

の 部 分 で、writepages 関 数 が 実 行 されます。<br />

(*) readpage と readpages は 異 なる 関 数 ですので 注 意 してください。<br />

33 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

readpage の 実 装<br />

• readpage 関 数 の 実 装 は、ファイルシステムによって 異 なりますが、 多 くの 場 合 、mpage_readpage<br />

関 数 を 利 用 しています。<br />

► ファイルシステムに 固 有 となるのは、 主 には、ファイル 内 のデータの 位 置 (ファイルの 先 頭 から 何 ブロック 目<br />

か)を、 物 理 ディスク 上 の 位 置 (ディスクの 先 頭 から 何 ブロック 目 か)に 変 換 する 部 分 です。このブロック 位 置 変<br />

換 の 関 数 のみを 独 自 に 用 意 して、その 他 の 一 般 的 な 処 理 は 共 通 の mpage_readpage 関 数 で 行 います。<br />

• 例 えば、ext2 ファイルシステムでは、ブロック 位 置 変 換 の 関 数 を ext2_get_block として、readpage<br />

関 数 は、mpage_readpage(page, ext2_get_block) を 呼 び 出 します。<br />

► mapge_readpage は、ブロック 位 置 の 変 換 が 必 要 になると、 第 2 引 数 で 指 定 された ext2_get_block 関 数 を<br />

使 用 します。 第 1 引 数 の page は、データを 書 き 込 むべきページキャッシュのページディスクリプターです。<br />

► 同 様 に、readpages 関 数 は、 複 数 のページを 連 続 して 処 理 する mpage_readpages を 呼 び 出 します。( 本 質<br />

的 には、mpage_readpage と 同 じ 処 理 を 複 数 のページに 対 して 実 施 します。)<br />

• mpage_readpage および、mpage_readpages は、 読 み 込 み 対 象 のキャッシュページの 情 報 から、<br />

物 理 ディスク 上 のデータの 位 置 を 求 め、データセグメント(キャッシュページ 内 の 物 理 ディスク 上 で 連<br />

続 する 部 分 )ごとに bio を 構 成 し、リクエストキューの make_request_fn で、リクエストキューに 登<br />

録 します。<br />

34 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

writepages の 実 装<br />

• writepages 関 数 も、readpage と 同 様 に、 多 くのファイルシステムで、 共 通 の mpage_writepages<br />

関 数 を 利 用 しています。<br />

• 例 えば、ext2 ファイルシステムでは、ブロック 位 置 変 換 の 関 数 を ext2_get_block として、<br />

writepages 関 数 は、mpage_writepages(mapping, wbc, ext2_get_block) を 呼 び 出 します。<br />

► mapge_writepages は、ブロック 位 置 の 変 換 が 必 要 になると、 第 3 引 数 で 指 定 された ext2_get_block 関 数<br />

を 使 用 します。 第 1 引 数 および 第 2 引 数 は、 書 き 込 み 対 象 のページキャッシュを 指 定 する 情 報 を 与 えます。<br />

• mpage_writepages は、 書 き 込 み 対 象 のキャッシュページの 情 報 から、 物 理 ディスク 上 のデータの<br />

位 置 を 求 め、データセグメント(キャッシュページ 内 の 物 理 ディスク 上 で 連 続 する 部 分 )ごとに bio を<br />

構 成 し、リクエストキューの make_request_fn で、リクエストキューに 登 録 します。<br />

35 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

pdflush について (1)<br />

• ユーザープロセスから 見 た、ファイルの 書 き 込 み 処 理 は、キャッシュページ 上 にデータが 書 き 込 まれ<br />

た 時 点 で 終 了 します。キャッシュページから 物 理 デバイスへのデータの 書 き 出 しは、カーネルスレッ<br />

ド pdflush がバックグラウンドで 実 行 します。<br />

• pdflush は、 任 意 のジョブをバックグラウンドで 実 行 するためのカーネルスレッドです。 特 に、 物 理 デ<br />

バイスへのデータの 書 き 出 し 処 理 のために、background_writeout、および、wb_kupdate の 2 種<br />

類 のジョブを 実 行 します。<br />

• background_writeout は、キャッシュページへのデータの 書 き 込 み 処 理 が 行 われた 後 、Dirty フラ<br />

グのセットされたキャッシュページ( 物 理 デバイスにまだ 書 き 出 されていないページ)の 割 合 が<br />

dirty_background_ratio (%) 以 上 になった 場 合 に 起 動 されます。<br />

► Dirty フラグのセットされたキャッシュページを、 順 に、writepages で 物 理 デバイスに 書 き 出 します。<br />

► Dirty フラグのセットされたキャッシュページの 割 合 が dirty_background_ratio (%) 以 下 になると、 実 行 を 終<br />

了 します。dirty_backgrond_ratio の 値 (デフォルトは 10 %)は、proc ファイルシステムの<br />

/proc/sys/vm/dirty_backgrond_ratio から 確 認 、 変 更 が 可 能 です。<br />

► 実 際 には、 全 ての 書 き 込 み 処 理 の 後 に 起 動 されるわけではなく、ある 一 定 の 頻 度 で 起 動 されます。Dirty フラ<br />

グのセットされたキャッシュページの 割 合 が dirty_ratio (%) 以 上 になると、 起 動 頻 度 が 高 くなります。<br />

dirty_ratio の 値 (デフォルトは 40 %)は、proc ファイルシステムの /proc/sys/vm/dirty_ratio から 確 認 、 変 更 が<br />

可 能 です。<br />

36 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

pdflush について (2)<br />

• kw_kupdate は、タイマーによって 一 定 時 間 ごとに 起 動 されます。<br />

► 起 動 時 間 間 隔 は、proc ファイルシステムの /proc/sys/vm/dirty_writeback_centisecs ( 単 位 は 1/100 sec)<br />

から 確 認 、 変 更 が 可 能 です。デフォルト 値 は 500、つまり 5 secです。<br />

► dirty_expire_centisecs ( 単 位 は 1/100 sec)よりも 長 い 間 Dirty フラグがセットされているキャッシュページを<br />

全 て、 物 理 デバイスに 書 き 出 します。 dirty_expire_centisecs の 値 は、proc ファイルシステムの<br />

/proc/sys/vm/dirty_expire_centisecs ( 単 位 は 1/100 sec)から 確 認 、 変 更 が 可 能 です。デフォルト 値 は 3000、<br />

つまり 30 sec です。<br />

► 従 って、デフォルトでは、 書 き 込 まれてから 30 sec 以 上 経 過 したキャッシュページは、5 sec 以 内 に 物 理 デバ<br />

イスに 書 き 出 されることになります。(ただし、 書 き 出 すページが 多 く、kw_kupdate による 書 き 出 し 処 理 に 時 間<br />

がかかる 場 合 は、これよりも 遅 くなることはあります。)<br />

37 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

参 考 資 料<br />

38 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

参 考 資 料<br />

• Understanding the LINUX KERNEL (3 nd Edition)<br />

►http://www.oreilly.com/catalog/understandlk/<br />

• Linux Device Drivers (3 nd Edition)<br />

►http://www.oreilly.com/catalog/linuxdrive3/<br />

《 商 標 について》<br />

• Linux は、Linus Torvalds 氏 の 商 標 または 登 録 商 標 です。<br />

• その 他 、 表 示 されている 会 社 名 、 製 品 名 は 一 般 に 各 社 の 商 標 または 登 録 商 標 です。<br />

39 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation


Linux/OSS Support Center, IBM Japan<br />

変 更 履 歴<br />

• Version 1.0 2006/01/25 作 成<br />

• Version 1.1 2008/06/11 外 部 公 開<br />

• Version 1.2 2009/11/06 I/O スケジューラーの 動 作 概 要 を 追 加<br />

40 Linux カーネルのブロックデバイス・<br />

I/O サブシステム( 入 門 編 )<br />

© 2009 IBM Corporation

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!