(57)【特許請求の範囲】
【請求項１】
複数の記憶手段を備えるＲＡＩＤアレイにデータブロックを記憶するための方法であって、
割り当てられた記憶スペースを記録するための手段に、書き込みのために割り当てられる記憶スペースを記録することによって、前記ＲＡＩＤアレイに記憶されるべきデータブロックに対して、前記ＲＡＩＤアレイにおける記憶スペースを書き込みのために割り当てるステップを含み、前記記憶スペースは前記複数の記憶手段における複数の記憶ブロックを備え、
前記ＲＡＩＤアレイにおける記憶スペースを書き込みのために割り当てる前記ステップは、
前記ＲＡＩＤアレイに記憶されるべきデータブロックであって、記憶スペースがまだ割り当てられていないデータブロックを選択するステップと、
前記データブロックをチェックして、前記データブロックが、前記ＲＡＩＤアレイにおける前記複数の記憶手段のうちの第１の記憶手段内の記憶スペースが書き込みのために割り当てられている前のデータブロックとは異なったファイルあるいは異なった先読みセグメントにあるか否かを決定するステップと、
前記データブロックが前記異なったファイルあるいは前記異なった先読みセグメントにあるとき、前記ＲＡＩＤアレイにおける前記複数の記憶手段のうちの第２の記憶手段内の記憶スペースを選択し、前記データブロックが前記異なったファイルにあるのでも前記異なった先読みセグメントにあるのでもないとき、前記第１の記憶手段内の記憶スペースを選択するステップとを含み、前記記憶スペースが、前記データブロックの書き込みのために割り当てられた記憶ブロックを備え、
前記ＲＡＩＤアレイにおける記憶スペースを書き込みのために割り当てる前記ステップはさらに、
前記書き込みのために割り当てられた記憶ブロックの標識と前記データブロックとを関連づけることによって、前記データブロックの書き込みのために割り当てられた前記記憶ブロックを、前記データブロックに割り当て指定するステップと、
前記ＲＡＩＤアレイにおける複数の記憶手段のうちの前記記憶手段に対して書き込み可能なデータブロックのリストに、前記データブロックを追加するステップと、
前記ＲＡＩＤアレイに記憶されるべきデータブロックがすべて処理されたか否かを決定するステップと、
前記ＲＡＩＤアレイに記憶されるべき前記データブロックの処理がすべて完了しているのではないとき、記憶スペースがまだ割り当てられていないデータブロックを選択する前記ステップを繰り返し、前記データブロックのための記憶スペースを選択するステップと、
前記ＲＡＩＤアレイに記憶されるべき前記データブロックのすべてが処理されたとき、前記書き込み可能なデータブロックのリストにおける書き込まれていないすべてのデータブロックを、前記データブロックに割り当てられた記憶スペースに書き込むステップとを含む方法。
【発明の詳細な説明】
発明の背景
１．発明の分野
本発明は、情報を記憶するディスクアレイを用いたファイルシステムの分野に関する。
２．従来技術
一般に、コンピュータシステムにおいては、種々の情報（例えばデータおよび／またはアプリケーションプログラム等）を記憶するためのディスクドライブなどの多くの２次メモリを必要とする。従来のコンピュータシステムにおいては１つの“ウインチェスター”スタイルのハードディスクドライブを用い、大量のデータを永久記憶する構成がとられている。コンピュータやそれに付属のプロセッサのパーフォーマンスが高度化されるに伴い、大容量のディスクドライブの必要性やデータ伝送レートのスピード化が望まれるようになった。この要望に歩調を合わせるため、ディスクドライブパーフォーマンスにおける改良がなされてきた。例えば、データやトラック密度の増加や、メディアの改良や、１つのディスクドライブにおけるヘッドの数やディスクの数の増加等がデータ伝送レートのスピード化に寄与してきた。
１つのディスクドライブでもって２次記憶装置を構成することの欠点は、より多くの容量やパーフォーマンスが必要となったときにドライブの取り替えが必要となることによる出費がある。他の欠点としては、冗長性の無さであり、単一のディスクドライブにおいてバックアップをとるための容量不足がある。１つのディスクドライブが故障し、機能しなくなり、または置き換えることができなくなれば、そのシステムは使うことができなくなる。
単一のディスクドライブシステムにおける上述の欠点を無くしたり軽減するために試みられた一つの従来技術として、並列につながれた複数のドライブを使用するものがある。この場合、データはいくつかの大きな塊に分けられ、複数のドライブから平行に、かつ同時にアクセスすることもできるし、複数のドライブのうち１つのドライブだけからシーケンシャルにアクセスすることもできる。このようにディスクドライブを並列に組み合わせたシステムは、“安価なディスクによる余剰アレイ（redundant array of inexpensive disks）”略してＲＡＩＤ（レイド）アレイと呼ばれている。このＲＡＩＤシステムは、大きな１つのディスクドライブシステムと同じ記憶容量を低価格で提供するものである。更に、アレイの並列処理により、高速のデータ伝送レートを達成することができる。
ＲＡＩＤシステムにおいては、アレイに追加のディスクドライブを加えることにより、段階的に記憶容量を増やしていくことが可能となる。ディスクが故障してもＲＡＩＤシステムが備わっていれば、システム全体を止めることなくそのディスクを取り替えることが可能となる。また、故障したディスクに残っているデータは、エラー訂正技術を用いることによりリカバリーすることも可能である。
ＲＡＩＤには６種類のディスクアレイ構成が存在し、それらはＲＡＩＤレベル０からＲＡＩＤレベル５として呼ばれている。各ＲＡＩＤレベルには利点や欠点がある。以下の説明においては、単にＲＡＩＤレベル４および５について説明する。しかしながら、異なったＲＡＩＤレベルについての詳しい説明はパターソン（Patterson）他著の「安価なディスクを用いた余剰アレイの考察（A Case for Redundant Arrays of Inexpensive Disks（ＲＡＩＤ））」ＡＣＭ  ＳＩＧＭＯＤ会議，１９８８年６月に記載されている。この文献は本願の内容の一部を構成するものとしてここに引用する。
図１は従来技術のＲＡＩＤレベル４を有するシステムを示す。このシステムは、コンピュータシステムまたはホストコンピュータに通信チャンネル１３０を介して接続された１つのパリティディスク１１２とＮ個のディスク１１４〜１１８を有する。図示した例においては、データは、４キロバイトのブロックまたはセグメントごとに各ハードディスクに記憶される。ディスク１１２は、システムのためのパリティディスク、ディスク１１４〜１１８はデータディスク０〜Ｎ−１である。ＲＡＩＤレベル４は、図１に示すようにアレーにおけるすべてのディスクに亘ってデータブロックを配るディスクストライプ方式を用いる。このシステムにおいては、第一のブロックを第一のドライブに乗せ、残りのＮ−１個のドライブについても順番に巡回するよう構成されている。ＲＡＩＤレベル４はパリティ用に別のドライブを用い、パリティはストライプと呼ばれる複数のデータブロックからなるグループ毎にエラー訂正情報を有する。図１に示すディスクストライプ方式は、一度に大量のデータの読み書きを行うことが出来るシステムである。各ドライブの一つのセグメントは、同時に読むことができ、大きなファイルにより速くデータアクセスすることができる。
ＲＡＩＤレベル４のシステムにおいては、複数のブロックからなるファイルはＮ個のディスク１１２〜１１８に“ストライプ”として記憶される。すなわち、ストライプとは複数のデータブロックのグループであり、各ブロックはＮ個のディスクの１つに記憶されることになる。図１において、第１および第２ストライプ１４０，１４２はそれぞれ点線で示されている。第１ストライプ１４０はパリティ０ブロックおよびデータブロック０〜Ｎ−１から構成される。図に示す例においては、第１のデータブロック０はＮ個のディスクアレイのうちディスク１１４に記憶される。第２のデータブロック１はディスク１１６に記憶され、以下同様にして記憶が続く。そして、最後のデータブロックＮ−１はディスク１１８に記憶される。当業者によく知られた技術を用いて、ストライプ１４０に対しパリティが計算され、その結果がディスク１１２にパリティブロックとして記憶される。同様にストライプ１４２にはＮ−１個のデータブロックが含まれ、データブロックＮはディスク１１４に、データブロックＮ＋１はディスク１１６に、そしてデータブロック２Ｎ−１はディスク１１８に記憶される。４ストライプ１４２のパリティが計算され、その結果はディスク１１２にパリティブロック１として記憶される。
図１に示すように、ＲＡＩＤレベル４にはパリティディスクドライブが含まれ、そこにはシステムの各ストライプのエラー訂正情報が含まれている。もし、システムにおいてエラーが発生すれば、ＲＡＩＤアレイの全てのドライブを用いてシステムにおけるエラーを訂正する必要がある。通常は１つのドライブにのみアクセスされるので、ＲＡＩＤレベル４は少量のデータを読むのには適している。ＲＡＩＤレベル４のアレイはいつでもデータを読むことができるが、エラーがあるときはそのようにはいかない。一方、ＲＡＩＤレベル４のアレイは、アレイにデータを書き込む場合はいつもパリティドライブと協動する。
ＲＡＩＤレベル５アレイのシステムも、ＲＡＩＤレベル４のシステムと同様にパリティを利用する。しかしながら、パリティセクターを常に同じ１つのドライブに記憶するようなことはしない。ＲＡＩＤレベル５においては、パリティブロックの位置を順次ずらし、Ｎ＋１個からなるディスクアレイの全てのディスクに記憶されるようにする。したがって、ＲＡＩＤレベル５のシステムはＲＡＩＤレベル４のシステムに比べ、パリティデータのアクセスをＮ＋１個のディスクドライブに分散させ、１ブロック単位でアクセスできるようにした点において改良がなされている。第１の複数のブロックのセットに対しては、パリティブロックは最初のドライブに記憶されるようになっている。第２の複数のブロックのセットにおいては、パリティブロックは第２のディスクドライブに記憶されるようになっている。このような記憶形態が繰り返され、各セットにパリティブロックが設けられることになるが、パリティ情報は単一のディスクドライブに記憶されるということは起こらない。ＲＡＩＤレベル４のアレイと同様ＲＡＩＤレベル５のアレイも必要とされるデータのみを読み出すことができ、そこにエラーが含まれていることもあり得る。ＲＡＩＤレベル５のシステムにおいては、複数のブロックを含むグループに対するパリティ情報が１つのディスクに収集されることがないので、アレイの複数の異なったドライブに一度に書き込むことも可能となる。したがって、読み書き動作はＲＡＩＤ４アレイよりもＲＡＩＤ５アレイの方がより高速に行うことが可能である。
図２はＲＡＩＤレベル５のシステムを備えた従来例のブロック図である。このシステムは伝送チャンネル１３０によりコンピュータシステムまたはホストコンピュータ１２０に接続されるＮ＋１個のディスクで構成される。ストライプ２４０においては、パリティブロックは第１ディスク２１２に記憶される。データブロック０は第２ディスク２１４に記憶され、データブロック１は第３ディスク２１６に記憶され、以下同様に記憶が行われる。そして、最後にデータブロックＮ−１はディスク２１８に記憶される。ストライプ２１２においては、データブロックＮは第１ディスク２１２に記憶される。第２のパリティブロック１は第２ディスク２１４に記憶される。データブロックＮ＋１はディスク２１６に記憶され、以下同様な記憶が行われる。最後に、データブロック２Ｎ−１はディスク２１８に記憶される。Ｍ−１番目のストライプ２４４では、データブロックＭＮ−Ｎは第１ディスク２１２に記憶される。データブロックＭＮ−Ｎ＋１は第２ディスク２１４に記憶される。データブロックＭＮ−Ｎ＋２は第３ディスク２１６に記憶され、以下同様の記憶が行われる。最後に、パリティブロックＭ−１はＮ番目のディスク２１８に記憶される。したがって、図２に示すようにＲＡＩＤレベル５のシステムはＲＡＩＤレベル４のシステムと同様なパリティ情報を記憶するが、ＲＡＩＤレベル５のシステムにおいてはパリティブロックの位置が順次ずらされ、ディスク２１２〜２１８に行き亙るようになっている。
ＲＡＩＤレベル５においてはパリティはディスクのアレイにわたって分配される。この結果、全体のディスクに亙る多重検索を行う必要がある。これはＲＡＩＤアレイの大きさを段階的に増やしていくことを禁止する。何故なら、パリティの構成により所定量のディスクを一度に増やす必要があるからである。
ＲＡＩＤサブシステムの上に載る従来のファイルシステムは、ＲＡＩＤアレイを１つの大きな複数のブロックの集合体として認識し、それらブロックはＲＡＩＤアレイを横切る方向に順次番号付けが行われる。１つのファイルに含まれる複数のデータブロックは、複数のデータディスクに亙って分配して記憶され、各ストライプをできるだけ一杯にした形で記憶され、それぞれのデータブロックはストライプにおける異なったディスク上に記憶されることになる。第１のストライプにＮ−１個のデータブロックがＲＡＩＤアレイのＮ−１個のデータディスクの全てに割り当てられれば、残りのデータブロックは次のストライプに同様なやり方で割り当てられ、１つのファイルの全体が収まるまで以下同様にして、ＲＡＩＤアレイ上に記憶が続けられる。このようにして、１つのファイルはＲＡＩＤシステムの複数のデータディスクに亙って記憶され１本のストライプを構成し、同様なストライプを複数用いることにより記憶がなされる。なお、１本のストライプにはＮ−１個のデータブロックが含まれている。これでは、１つのファイルにアクセスするためにはＮ−１のディスクに亙ってアクセスする必要があり、Ｎ−１個のディスクに検索をかける必要があるという欠点を生ずる。したがって、別の従来例によるファイルシステムにあっては、１つのファイルの全てのブロックを単一のディスクに書き込むことを行うものがある。しかしこれでは、１つのファイルについて１つのデータディスクのみに対して検索が行われ、残りのＮ−２個のディスクが十分活用されていないという欠点が生ずる。
ファイルシステム自身には、それが記憶されるＲＡＩＤサブシステムについての情報は一切有しておらず、かかるＲＡＩＤサブシステムを単なる１つの大きなディスクとして受け止めている。このような状況の基では、単一のデータブロックのみが１つのストライプに書き込まれ、パリティを計算するためには４つのＩ／Ｏ（入出力）動作を必要とするので、大きなペナルティを生ずることになる。例えば、引き算によりパリティを行う場合、４回のＩ／Ｏ動作を必要とする。４つのディスクからなるＲＡＩＤアレイにおいて、１つのディスクがパリティディスクであれば、１つのストライプに対し３つのデータブロックを書き込み、そしてそのデータブロックに対するパリティを計算することは、７５％（４本のうち３本のディスクのみを利用しているから）の効率しか得られず、１本のストライプに１つのデータブロックにのみ書き込む操作においては２５％の効率しか得られない。
この割り当てアルゴリズムはストライプ全体をできる限り全て利用するものであり、ファイルの実質的な部分をディスク上に連続した位置に記憶しようとするものである。このシステムは、ファイルを複数のディスク上にランダムに分散させて記憶してしまい、このため複数のディスクの検索が必要となるようなことをことをできるだけ避けるようにしたものである。もし１２キロバイトのファイルが４キロバイトのブロック毎に３つの個別のディスク（１本のストライプ上）に亙って記憶されたならば、ファイルにアクセスするためには３つの個別のアクセスが必要となる。他のクライエントがファイルシステムからファイルを取り出そうと試みるためキューを発している間にこのことが行われる。
発明の要約
この発明はＲＡＩＤアレイ技術を伴うファイルシステムの改良に関する。本発明はＲＡＩＤシステムにおけるデータブロックの配列に関する情報をＲＡＩＤ層からファイルシステムへ情報を送る構成に関する。ファイルシステムはこの情報を検査し、更にＲＡＩＤシステムに書き込まれたブロックの位置の最適化を図るためにその情報を利用する。この発明は種々ある番号付け手順よりも優れた番号付け手順を採用するＲＡＩＤサブシステムを備えたものである。この発明は大きな一塊の情報を先読みすることにより、そしてストライプを一度に書き込むことにより、ＲＡＩＤシステムへの書き込みを最適なものにするものである。
より効率の良い動作を得るためにＲＡＩＤアレイにとっては効率の良くないアクセスパターンを避けるため、ここに改良されたＲＡＩＤ機能を有するファイルシステムの開発が、書き込みのための割り当て方法に照らして行われた。したがって、この発明においてはＲＡＩＤディスク配置の明白な知識が用いられ、ディスクの割り当ての計画がなされる。本発明においては、ディスクアレイの各ディスクに対し個別の現在書き込みが行われている位置を示すカレント書き込み位置ポインタが用いられる。これらのカレント書き込み位置ポインタは書き込みが行われる度にポイントされているディスクが移り変わっていく。この発明において用いられたアルゴリズムは、現在の書き込み位置ポインタをできる限り同じストライプに近い位置に保持するようにし、複数のブロックをストライプに同時に書き込むことができるよう、ＲＡＩＤの効率の改良を図るものである。本発明はまた、ファイルにおける隣接したブロックの配置を同じディスクになるように工夫され、データが読み出される際に効率の改善が図られるよう構成されている。
本発明においては、最下位のカレント書き込み位置ポインタを用いてディスクにデータを書き込む。本発明においてはまた、新しいファイルのためのスペースを割り当て始めるとき、または１つのファイルにつき同じディスクが十分に利用されたときにのみ新しいディスクを選ぶようになっている。ここで十分に利用されたときとは、ブロックの十分な数を言い、一塊のブロックの全てのブロックであり、一塊とはファイルにおける一連の複数のブロックのうちのある数Ｎ個に相当するものである。複数のブロックが集まった一塊は、ファイルにおいてＮ個ずつに区切られて並べられたものである。したがって、複数のカレント書き込み位置ポインタは異なったディスク上であってもＮブロック以上離散することはない。したがって、大きいファイルは同じディスク上にＮ個の連続したブロックを有することとなる。
【図面の簡単な説明】
図１は従来のＲＡＩＤレベル４サブシステムのブロック図、
図２は従来のＲＡＩＤレベル５サブシステムのブロック図、
図３は本発明に基づき、ＷＡＦＬファイルシステムと一体構成されるＲＡＩＤアレイを使用してファイルを割り当てるための動作を示すフローチャート、
図４は図３のステップ３３０の詳細を示すフローチャート、
図５は図４のステップ４９０の詳細を示すフローチャート、
図６はＷＡＦＬｉノードにより参照されるツリー構造のバッファを示す概略図、
図７はよごれｉノードのリストを示す概略図、
図８は図７に示したｉノード７２０によって参照されるバッファのツリー構造の割り当てを示す概略図、
図９Ａ−９Ｊは、図５に基づくディスクスペースの割り当てを示す概略図、および
図１０は本発明に係るシステムの概略図である。
本発明の詳細な説明
ＲＡＩＤアレイを用いたファイルシステムにおいて、ファイルを割り当てる方法について説明する。以下の説明において、種々の具体的データ、例えばポインタの数やその特性、ディスクブロックの大きさ等、を用いて説明がなされるが、これらは、本発明をより完全に理解するためのものである。言うまでもなく、本発明はこれらの具体的データに限定されるものではなく、これら以外の値であっても達成することができるものである。また、公知の内容等についてはその説明を簡単にし、発明の内容が不必要に不明瞭なものとならないよう配慮されている。
ネットワークシステムに用いられるコンピュータについては、各ハードディスクはそのネットワークの動作スピードより早いスピードで動作するものとする。したがって、ＲＡＩＤシステムにおいては独立した複数のヘッドを用いるのが好ましい。これによりＲＡＩＤアレイの個別の複数のディスクに記憶された異なったファイルに複数のクライエントが同時にアクセスすることが可能となる。これにより、ＲＡＩＤシステムにおいてデータの引き出しおよび記憶のためのアクセス時間が非常に短縮できる。
図１０は、ＲＡＩＤサブシステムを備えた本発明に係るシステムを示す図である。コンピュータ１０１０は中央演算装置（ＣＰＵ）１０１２およびメモリ１０１４を備えて構成される。ＣＰＵ１０１２はバス１０１６を介してメモリ１０１４に接続されている。バス１０１６によりコンピュータ１０１０はＲＡＩＤコントローラ１０５０に接続されている。バス１０１６はまた、コンピュータ１０１０をネットワークコントローラ１０４０に接続する。ＲＡＩＤコントローラ１０５０は、ＲＡＩＤアレイ１０３０を構成するパリティディスク１０２０とデータディスク１０２２〜１０２４にバス１０２６を介して接続される。コンピュータ１０１０はWrite Anywhere File-system Layout（“ＷＡＦＬ”）ファイルシステムにおけるファイルの位置割り当てを行うものであって、ＷＡＦＬファイルシステムはＲＡＩＤコントローラ１０５０とディスク１０２０−１０２４を備えたＲＡＩＤディスクサブシステムと一体構成される。
本発明はＲＡＩＤアレイ１０３０において改良されたブロックの割り当て方法を提供するものである。このシステムはパリティディスク１０２０を含むＲＡＩＤアレイであって、Ｎ個のディスク１０３０を備えたＲＡＩＤレベル４型のアレイ１０３０を利用するものである。残りのディスク１０２２〜１０２４は複数のデータブロックを記憶するデータディスクである。このＲＡＩＤシステムのストライプは複数の４キロバイトブロックを備え、各４キロバイトブロックはアレイの異なったディスクに記憶される。ストライプのそれぞれのブロックはそれぞれのディスクの同じ対応した位置に記憶される。広い意味では、ファイルは情報を記憶する構成であって、データは一定の大きさのブロックに分割されたものであると言える。例えば、本発明においてファイルシステムは４キロバイトのブロックを用いてデータをディスクに記憶する。なお、言うまでもなく、本発明においては種々のブロックサイズ（例えば５１２，１０２４，２０４８バイト等）のものを用いることができ、いずれも本発明に含まれるものである。したがって、例えば、１５キロバイトのファイルについては４キロバイトのデータブロックが４つ必要となり、１キロバイトのファイルについては４キロバイトのデータブロックが１つ必要となる。
本発明においては複数のデータブロックを備えたファイルは、１つのＲＡＩＤアレイにおける１つのディスク上の所定数のブロックからなる複数のグループに割り当てられる。これは１バイト毎、もしくはデータブロック（例えば４キロバイトのブロック）毎にＮ−１個のデータディスクに亙って書き込まれる従来のＲＡＩＤシステムとは異なるものである。本発明の好ましい実施形態においては、一つのデータディスクの上には最大８データブロック（３２キロバイト）からなる複数のグループが割り当てられる。ファイルが割り当てられ、個別のディスクへと送り込まれる。
本発明の重要なポイントは、最大数の異なったファイルに対し、各ディスクにおいて最大３２キロバイトの“チャンク（塊）”のデータブロックを同時に記憶することができる方法を提供することである。理想的には、複数のディスクに亙って形成される各ストライプは、Ｎ−１個の異なったファイルに関してＮ−１個のディスクにそれぞれデータブロックを同時に書き込むことによって、完全に充てんされる。
本発明におけるファイルシステムとＲＡＩＤを一体化する概念は、全てのディスクにおける全てのアーム（腕）がどこにあるかの知識をＲＡＩＤから与えるものであって、それにより書き込みの順番を制御することを提案するものである。したがって、いずれの時点においても、最大のグループの書き込みを行うことができ、パリティディスクを“ホット（活動化）”にする必要がなく、ＲＡＩＤアレイ全体を通してパリティディスクを見つけ出す必要がない。システムの障害となっていた“ホット”は問題とはならない。何故なら同じ数だけの書き込みを行うことができるからである。最も好ましい状況は書き込みを行う際、ストライプにおける全てのブロックが空きの状態であり、３つのデータディスクに対して行われる３つの書き込みについてパリティが計算される場合である。しかし、通常のケースにおいてはストライプにおける１つまたは複数のデータブロックが既にデータで満たされている。これは以前から存在する他のデータがＲＡＩＤサブシステムに記憶されているからである。したがって、通常のファイルシステムにおいては、例えば２つは第１ストライプに書き込まれ、第２および第３ストライプのそれぞれに１つが書き込まれ、第４ストライプに３つが書き込まれるという場合である。したがって、この場合４本のストライプに亙って書き込まれた７つのデータブロックについて４つのパリティ計算を行う必要がある。
本発明はストライプ全体を書き込もうとするとともに、１つのディスクに各ファイルを記憶するようにするものである。したがって、パリティディスクにあるヘッドはディスク全体を検索することは必要ない。もし、ヘッドを１つのシリンダに設ければ、データをディスクにより高速に書き込むことができ、ディスク毎に多数のトラックに亙って検索する必要がなくなる。これはまた、それぞれのディスクドライブに設けた１つのシリンダにより１／４メガバイトのデータまたはそれ以上のデータを記憶することができるという利点があり、１つのトラックにファイルの大きな“チャンク（塊）”を書き込むことが可能となる。例えば、９０％満たされたファイルシステムであっても、まだ更に２５０キロバイトのシリンダに２５ＫＢのデータを記憶することが可能である。この場合、隣のシリンダにおいてもディスクが１／４回転する間検索することができ、１つのディスクに更に２５ＫＢ書き込むことも可能である。したがって、９０％満たされたファイルシステムであっても、５０ＫＢより以下の容量を有するファイルはＲＡＩＤアレイにおける１つのディスクの隣接トラックに速やかに記憶することが可能となる。したがって、もしファイルをディスクに記憶することがわかっておれば、ディスクは検索のために“ホット”になる必要はない。システムにおける他のディスク以上により多くの書き込みや検索を経験する必要はない。ＲＡＩＤアレイの各ディスクには匹敵する程度の書き込みがある。更に、読み出しの際、割り当て要求であるファイルのキューは他のディスクのキューに順位が遅らされることはない。
ファイルシステムにはＲＡＩＤ層と通信することができるデータ構成がある。ＲＡＩＤ層からはファイルシステムに情報が送られ、ＲＡＩＤ層のシステムがどのような形態になっているかを知らせる。ファイルシステムのデータ構造はＲＡＩＤシステムにおける各ディスクについての情報のアレイを含む。同じストライプに複数のファイルブロックを書き込むことの重要性の理由は他にもある。すなわちＲＡＩＤにおいてブロックが更新された場合、１つのデータブロックに書き込みを行う場合４つのディスクのＩ／Ｏが必要となるからである。効率の点からすれば、１つのブロックを書き込みに、そして２つのブロックを読み取りに用いるよりも、ストライプに対し３つのブロックを書き込んだ方が好ましい。
ネットワークに係る要求事項が個別のディスクの帯域幅よりも高くなるにつれて、十分な先の情報を読み取ることが好ましくなり、１つのファイルにアクセスする場合でも、先に別のディスクにアクセスしておくのが好ましくなる。これはＦＤＤＩおよびＡＴＭ等の大きなファイルや高速のネットワークを利用する場合に特に有益である。
本発明では、各ディスクに対しディスクの現在の書き込み位置を指定するカレント書き込み位置ポインタを設けている。カレント書き込み位置ポインタはディスクの最終点に到達するまでディスク上で順次その位置がずれていくように構成され、最終点に到達した後はポインタはディスクの開始点にまで戻ってくる。ＲＡＩＤアレイの全てのディスクのカレント書き込み位置ポインタはできる限り互いに接近した位置に保たれるようになっている。したがって、各ディスクにおいてブロック位置の割り当てが順次下の方に移ってくると、ＲＡＩＤアレイの処理が行われるにしたがってストライプが満たされていくこととなる。同じ１つのディスクにファイルを連続して並べるためには、同じ１つのディスクに所定量のブロックを割り当てる必要がある。
各ディスクに複数のファイルブロックの連続したグループが書き込み可能となる一方で処理中には複数のストライプが同時に満たされるように複数のファイルをグループにまとめるためには、割り当てアルゴリズムはバッファを必要とする。したがって、ファイルはＲＡＩＤシステムに送られて来れば直ちに書き込みが行われるのではなく、まずバッファに一時的に溜められ、続いてディスクに割り当てられるようになる。最も簡単な形態においては、割り当てアルゴリズムはバッファから（ランダムにもしくはその他の手順で）ファイルを選出し、書き込み位置ポインタの位置が最も遅れた位置にあるディスクをＲＡＩＤアレイから選び出し、そのディスクから所定量の連続したブロック（４ＫＢを８ブロック）であって使用可能なものを探し、そのファイルを書き込むためにそれらブロックを割り当てる。ＮＦＳシステムにおいては、ファイルサーバに送られてくるファイル要求は通常８ＫＢのデータの単位で送られてくる。本発明においては３２ＫＢのセグメント分のデータを先んじて読み出し、そのデータ量は各ディスクに連続して書き込むことができるファイルデータ量と同等な量である。この方法の基本的概念によれば、各ディスクに連続して記憶可能なデータ量は、各ディスクにおいて先行して読むことができるデータ量に相当する。もしブロックがディスク上連続して並んでいなければ、中間にスペースが存在することとなり、書き込み位置ポインタを進めるにはそれをとばして進めなければならない。
カレント書き込み位置ポインタが現在の最下点を越えて移動したとき、ストライプにおけるファイルシステムによりブロックはＲＡＩＤサブシステムに送り込まれる。したがって、データブロックは互いに一体となってストライプとしてＲＡＩＤサブシステムに書き込まれ、より好ましいシステムの性能を得ることができる。これは、通常のファイルシステムの下にＲＡＩＤサブシステムを配置する従来のシステムとは異なるものである。従来のシステムにおいては最適な環境を得るため、ファイルシステムとＲＡＩＤサブシステムの層の間に大きなキャッシュ（cache）を用いることが試みられていた。そしてそのキャッシュはファイルサイズと同じ大きさのストライプを見つけるように設計されていた。したがって、従来のＲＡＩＤサブシステムにおいては、ファイルシステムのブロックをどこに配置するかの制御をすることができなかった。ほとんどのユニックス（ＵＮＩＸ）のファイルシステムにおいては、ファイルを望み通りの位置に並べることはできず、決められた位置に順番に並べるだけであった。したがって、１メガバイトのキャッシュを有する従来のシステムにおいては、１メガバイトの“チャンク”（キャッシュサイズ）のデータのグループが、例えば１０ギガバイトの大きなＲＡＩＤシステムにランダムに送り込まれたとき、連続して並べられるようなことはまずあり得なかった。
本発明においては８の単位（３２ＫＢ）の１つのファイルにアクセスする場合、ディスク間におけるスワッピング（データの行き来）をほとんど無くすことができる。
任意場所書き込みファイルシステムレイアウト（Write Anywhere File-system Layout）
本発明は任意場所書き込みファイルシステムレイアウト（Write Anywhere File-system Layout）（ＷＡＦＬ）と名付けられたファイルシステムを採用するものである。広い意味では、ＷＡＦＬはファイルシステムレイアウトの情報が記憶されているメタデータを記憶するファイルを利用するものである。このファイルシステムはフラグメントを一切用いない４キロバイトのブロックを用いるブロック単位で構成されるものである。ＷＡＦＬファイルシステムにおける複数のファイルは全てｉノードにより表され、ｉノードには各ファイルのサイズ、位置、制作者、その他ファイルに関する情報が含まれている。第３に、ディレクトリはこのシステムにおいては単なるファイルであり、それらファイルは特別にフォーマットがなされている。このＷＡＦＬにおいて２つの重要なインコア（コア内）のデータ構造はＷＡＦＬｉノードとＷＡＦＬバッファである。ＷＡＦＬｉノードはファイルシステムにおいて特別のファイルを示すものである。それにはディスク上のｉノードの全ての情報の外、他の情報が含まれる。ＷＡＦＬバッファは、メモリになるファイルの１つの４キロバイトデータブロックを記憶するものである。
ＷＡＦＬｉノード
図６はＷＡＦＬｉノード６１０の概略図を示す。ここにおいてファイルは間接ＷＡＦＬバッファ６２０〜６２４と、直接ＷＡＦＬバッファ６３０〜６３４から構成される。ＷＡＦＬのインコアのｉノード６１０は、標準的なｉノード情報６１０Ａ（ダーティバッファ（汚れたバッファ）のカウントを含む）、ＷＡＦＬバッファデータ構造６１０Ｂ、１６個のバッファポインタ６１０Ｃ、および標準的なオンディスクｉノード６１０Ｄを含むものである。インコアのＷＡＦＬｉノード６１０は約３００バイトの大きさを有する。オンディスクｉノードは１２８バイトの大きさを有する。ＷＡＦＬバッファデータ構造６１０Ｂは２つのポインタを有し、第１番目のポインタは１６個のバッファポインタ６１０Ｃを参照し、第２番目のポインタはオンディスクブロックナンバー６１０Ｄを参照する。
各ｉノード６１０にはダーティバッファのカウントを有し、それが参照される。ｉノード６１０は、ダーティｉノードのリストおよび／またはダーティバッファを有するｉノードのリストに加えられることができる。ｉノードによって参照される全てのダーティバッファは、ディスクに書き込まれることが予定されたものか、既にディスクに書き込まれたものである場合、ｉノード６１０に対するダーティバッファのカウントは０にセットされる。ｉノード６１０はそのフラッグ（すなわちダーティバッファを含まないことを示すフラッグ）により再キューされる。このｉノード６１０は次のｉノードが処理される前にクリアされる。
ＷＡＦＬバッファ構造は間接ＷＡＦＬバッファ６２０により説明される。ＷＡＦＬバッファ６２０は、ＷＡＦＬバッファデータ構造６２０Ａと、１０２４個のＷＡＦＬバッファポインタを有する４ＫＢバッファ６２０Ｂと、１０２４個のオンディスクブロックナンバーを有する４ＫＢバッファ６２０Ｃを備えて構成される。１０２４個のオンディスクブロックナンバーはディスクからブロックの正確な内容を参照する。バッファ６２０Ｃの１０２４個のポインタは子ブロックとして導入され、キャッシュにおいてバッファ６２０に記憶される。ＷＡＦＬバッファデータ構造は５６バイトの容量を有し、２つのポインタを備えている。ＷＡＦＬバッファデータ構造６２０Ａの１つのポインタは４ＫＢバッファ６２０Ｂを参照し、第２番目のポインタはバッファ６２０Ｃを参照する。図６において、ＷＡＦＬｉノード６１０の１６個のバッファポインタ６１０Ｃは、１６個の単一−間接ＷＡＦＬバッファ６２０〜６２４をポイントする。さらに、ＷＡＦＬバッファ６２０は１０２４個の直接ＷＡＦＬバッファ構造６３０〜６３４を参照する。ＷＡＦＬバッファ６３０は直接ＷＡＦＬバッファを表すものである。
ＷＡＦＬバッファ６３０はＷＡＦＬバッファデータ構造６３０Ａと、オンディスク４ＫＢデータブロックに対応するキャッシュメモリを含む４ＫＢ直接バッファ６３０Ｂを備えて構成される。直接ＷＡＦＬバッファ６３０は、間接ＷＡＦＬバッファ６２０にあるバッファ６２０Ｃのような４ＫＢバッファを含まない。ＷＡＦＬバッファデータ構造６３０Ａの第２バッファポインタは０にされ、第２の４ＫＢバッファをポイントすることはない。これによりメモリの非効率的な使用が避けられる。何故なら、メモリスペースはそうでなければ未使用バッファに対して割り当て指定されるからである。
図６に示すＷＡＦＬファイルシステムにおいては、ＷＡＦＬのインコアのｉノード構造６１０はＷＡＦＬバッファ構造６２０〜６２４および６３０〜６３４のツリー構造を参照する。これは、間接および／または直接ブロックをポイントしているブロックナンバーを備えた標準的なｉノードによって参照されるディスク上のツリー構造のブロックと同様なものである。したがって、ＷＡＦＬｉノード６１０は、１６個のボリュームブロックナンバーを備えたオンディスクｉノード６１０Ｄのみからなるのではなく、ＷＡＦＬバッファ構造６２０〜６２４および６３０〜６３４をポイントする１６個のバッファポインタ６１０Ｃをも含むものである。ＷＡＦＬバッファ６３０〜６３４はボリュームブロックナンバーにより参照されるブロックであって、キャッシュされた内容のものを含む。
ＷＡＦＬのインコアのｉノード６１０は１６個のバッファポインタ６１０Ｃを含む。そして、１６個のバッファポインタ６１０ＣはＷＡＦＬバッファ構造６１０Ｂにより参照され、このＷＡＦＬバッファ構造６１０ＢはＷＡＦＬバッファ６２０〜６２４および６３０〜６３４のツリー構造の根幹（ルート）を成すものである。したがって、各ＷＡＦＬｉノード６１０は、１つのＷＡＦＬバッファ構造６１０Ｂを含み、このＷＡＦＬバッファ構造６１０Ｂはｉノード６１０における１６個のバッファポインタ６１０Ｃをポイントするものである。これは、再帰的に実行される（後で説明）ツリー構造のバッファを扱うアルゴリズムを簡単なものにする。もし、ｉノード６１０における１６個のバッファポインタ６１０ＣがＷＡＦＬバッファコード６１０Ｂにより表されていなければ、バッファ６２０〜６２４および６３０〜６３４の全ツリーに対して動作する機能的アルゴリズムを実行することは難しくなる。
ダーティブロックを有するｉノードのリスト
ＷＡＦＬファイルシステムのＷＡＦＬのインコアのｉノード（すなわち図６に示すＷＡＦＬｉノード６１０）はそのステータスにより異なったリンクのリストで保全される。ダーティデータを含むｉノードは図７に示すように、ダーティｉノードリストに加えられる。従来から知られているように、ダーティではない有効なデータを含むｉノードは別のリストに加えられ、有効なデータを全くもたないｉノードはさらに別なリストに加えられる。本発明においてはダーティデータブロックを有するｉノードのリストを利用するので、書き込みのために割り当てを行う必要がある全てのｉノードを見つけ出す機能を容易にすることができる。
図７は本発明に係るダーティｉノードのリスト７１０の概略図である。ダーティｉノードのリスト７１０はＷＡＦＬのインコアのｉノード７２０〜７５０を備えて構成される。図７に示すように、各ＷＡＦＬのインコアのｉノード７２０〜７５０は、それぞれポインタ７２０Ａ〜７５０Ａを有し、それによりリスト中にリンクされた他のｉノードをポイントする。例えば、ＷＡＦＬｉノード７２０〜７５０はそれぞれ２０４８，２１５２，２８７８，３４４８，３７１２で示されるメモリ位置に記憶されている。したがってｉノード７２０のポインタ７２０Ａはアドレス２１５２を有する。これによりＷＡＦＬｉノード７２２がポイントされる。さらに、ＷＡＦＬｉノード７２２はそこに書かれたアドレス２８７８を用いてＷＡＦＬｉノード７３０をポイントする。続いてＷＡＦＬｉノード７３０はＷＡＦＬｉノード７４０をポイントし、ＷＡＦＬｉノード７４０はｉノード７５０をポイントする。ＷＡＦＬｉノード７５０のポインタ７５０Ａには何も記憶されていないので、これ以後はいずれのｉノードをもポイントすることはない。すなわちこれがダーティｉノードのリスト７１０に挙げられた最後のｉノードであることがわかる。
リスト７１０の各ｉノードは、図６で示したツリー構造のバッファを備えたファイルを表す。各ｉノード７２０〜７５０により参照される少なくとも１つのバッファはダーティバッファである。ダーティバッファは修正されたデータを含み、その修正されたデータはＷＡＦＬシステムにおける新しいディスクの位置に書き込まられなければならない。ＷＡＦＬは常にダーティバッファをディスク上の新たな位置に書き込む。図７に示すダーティｉノードのリスト７１０は単一にリンクされたリストとして示されているが、当業者には容易であるように二重にリンクされたリストや他の適切なデータ構造をとるようにしてもよい。
ＷＡＦＬシステムとは異なり、従来技術のBerkeley Fast File System（“ＦＦＳ”）においては、バッファは、バッファに記憶されたディスクブロックの物理的ブロック数に基づいてハッシュされたキャッシュに保持される。この方法は、新しいデータが書き込まれるや否や、ディスクスペースは常に割り当て可能な状態にあるディスクシステムについては良好に行うことができる。しかしながら、ＷＡＦＬのようにメガバイト級やそれ以上のデータがディスク上に書き込まれる前にキャッシュに集められるようなシステムについては全く機能しない。
ファイル割り当てアルゴリズム
図３は本発明に係るファイル割り当て方法を示すフローチャートである。このアルゴリズムはステップ３１０のスタートから始まる。ステップ３２０においてダーティブロックを有するｉノードのリストからダーティブロックを含むｉノードが選択される。ステップ３３０において、ｉノードで表されたツリー構造のバッファは、書き込みのためにディスクに割り当てられる。判定ブロック３４０においては、ダーティリストにある全てのｉノードが処理されたかどうかの判定が行われる。もし判定結果が偽（ＮＯ）であれば、ステップ３２０に戻る。しかし、判定ブロック３４０の結果が真（ＹＥＳ）であれば、ステップ３５０へ進む。ステップ３５０において、全ての書き込みが行われていないストライプはディスク上に書き出される。そしてステップ３６０でこのアルゴリズムは終了する。キャッシュにあるファイルが割り当てのために選択されれば、まずディレクトリの割り当てが行われる。次に、ファイルは、最後に使用されてから最も時間が経過したものを選択する基準（lest-recently-used（ＬＲＵ）basis）に基づいて割り当てが行われる。
図４は、ツリー構造のバッファにおける複数のバッファを書き込みのためにディスクに割り当てるための、図３のステップ３３０のフローチャートを示す。図３のステップ３３０では、ｉノードによって参照されるツリー構造のバッファについて、（ｉノードのルートバッファポインタに係る）書き込みのための割り当て（Write Allocate：ライトアロケート）と名付けられたアルゴリズムによって、書き込みのための割り当てが行われる。アルゴリズムには、１６個のバッファポインタ６１０Ｃを参照するＷＡＦＬｉノード６１０のバッファデータ構造６１０Ｂにあるポインタがわたされる。図４においてこのアルゴリズムはステップ４１０から開始される。ステップ４１０でバッファポインタが書き込みのための割り当てアルゴリズムにわたされる。判断ブロック４２０では、バッファポインタの子バッファのすべてが処理されたかどうかが判定される。判断ブロック４２０の結果が真（ＹＥＳ）であれば、ステップ４３０へ進む。ステップ４３０において再帰的アルゴリズムにより呼び出し処理に戻る。従って書き込みのための割り当てアルゴリズムは図３に示す判断ブロック３４０である呼び出し処理まで戻る。別の方法としては、図４に示す判断ブロック４８０に戻り、再帰的な呼び出し（後に説明）を行うことも可能である。
判断ブロック４２０の結果が偽（ＮＯ）であれば、ステップ４４０へ進む。ステップ４４０においてバッファポインタにより参照されるバッファの子バッファが取り込まれる。判断ブロック４５０ではこの取り込んだ子バッファが最下位のものかどうかの判定が行われる。判断ブロック４５０の結果が偽（ＮＯ）であれば、ステップ４６０へ進む。ステップ４６０では書き込みのための割り当てアルゴリズムが子バッファポインタを用いて再帰的に呼び出される。続いて、判断ブロック４８０が実行される。判断ブロック４５０の結果が真（ＹＥＳ）であれば、ステップ４８０へ進む。判断ブロック４８０では、子バッファがダーティであるか否かの判定が行われる。判断ブロック４８０の結果が真（ＹＥＳ）であれば、ステップ４９０へ進む。ステップ４９０では、（子バッファポインタに係る）スペース割り当てと呼ばれるアルゴリズムを呼び出し、子バッファのためのディスクスペースが割り当てられる。その後判断ブロック４２０に戻る。判断ブロック４８０の判断結果が偽（ＮＯ）であれば、判断ブロック４２０が続いて実行される。図４に示されるアルゴリズムについては、すべての子バッファに対して深さ優先−ポストビジト−トラバーサル（depth-first post-visit traversal）が実行され、ダーティであるものについては新しいディスクスペースが割り当てられる。ポストビジトトラバーサルが必要なのは、子バッファにスペースを割り当てることにより親バッファが変わるからである。
図５は、図４に示したステップ４９０であってディスク上にスペースを割り当てる工法を詳しく説明するフローチャートである。ステップ５１０において、スペースを割り当てるアルゴリズムには、すでにディスク上にスペースが割り当てられたバッファのバッファポインタがわたされる。判断ブロック５２０において、今回のバッファは、前回のバッファとは異なったファイルから作られたバッファか、または前回のバッファとも異なった先読みチャンクからのバッファかの判断が成される。判断ブロック５２０の結果が真（ＹＥＳ）であれば、ステップ５３０へ進む。ステップ５３０では書き込まれるべきディスクが選定される。ここで選ばれるディスクは、最下位のカレント書き込み位置ポインタ（current-write location（ＣＷＬ）pointer）を参照して行われる。優先的に書き込みが行われるデフォルトディスクは、ポインタの値が１番低い値のものである。その後ステップ５４０が実行される。判断ブロックの結果が偽（ＮＯ）であれば、ステップ５４０へ進む。
ステップ５４０で、バッファに対して割り当て指定された古いブロックはフリーにされる。バッファに使用される古いブロックがフリーにされるためには、ブロックマップ（blkmap）ファイルを更新し、特定されたブロックのエントリーにはそのブロックがアクティブファイルシステムによりもはや使用されていない旨が表示される。これはblkmapファイルの特定ブロックにおけるエントリーの部分をビット０（０）でクリアする（一掃する）ことにより達成される。ステップ５５０において、選ばれたディスク上にカレントブロックが割り当てられる。これは、blkmapファイルにおいて割り当てたように、書き込みが行われるべきデフォルトディスクのＣＷＬポインタをマークし、blkmapファイルを走査して次のＣＷＬポインタを見け出し、選ばれたディスクのブロックに達することにより行われる。ステップ５５０は、図５に示すアルゴリズムに、新しく割り当てられたブロックを返す。
ステップ５６０において、ディスク上において割り当てられたブロックはバッファに割り当て指定される。ステップ５７０において、そのバッファは選ばれたディスクにおける書き込み可能なバッファのリストの一つに加えられる。ステップ５８０において、可能な場合はストライプを書き込む。ストライプ５８０において、完全なストライプの一部を構成しているバッファがあるか否かをディスクバッファキューに基づいてチェックする。それらのバッファはグループとしてＲＡＩＤサブシステムに送られ、出来るだけ効率よく一体となった形で書き込まれる。ステップ５９０でアルゴリズムは呼び出しアルゴリズムに戻る。
ブロックがフリーにされたり割り当てられたりするに従って、ステップ５３０〜５５０では、フリーブロック管理機能（free block management functions）が用いられる。これらの機能により、現在書き込まれたディスクや各ディスクにおいてどれが次のフリーブロックになるか等の経過を保持するグローバルな変数等を保全する。またこれらは、blkmapファイルのエントリーを更新する。ファイルシステムが開始されれば、ＣＷＬポインタは初期化され、ディスク上の最初のフリーブロックをポイントする。フリーブロックが順次使われるの従って、ＣＷＬポインタは進められ、これはディスクの終端に到達するまで繰り返し行われる。この時点において、選択はディスクの最初のフリーブロックに戻る。
ステップ５６０〜５８０はディスク入力／出力（Ｉ／Ｏ）機能についての動作である。これらの機能は各ディスクにおけるＩ／Ｏ動作を管理する。各ディスクにはディスクへの書き込み待ちのバッファに対するキューがある。ストライプ上に完成されたデータが生成されれば、バッファはキュー状態から開放され、ディスクのＩ／Ｏサブシステムに書き込まれる。すべてのディスクのＣＷＬポインタの値がストライプにおける各ブロックを通過すれば、１本のストライプが完成される。すなわち、例えばＣＷＬポインタの値がそれぞれ２３１、２２８、２３５である３つのデータディスクがあった場合、最も低い値である２２８未満の値を有するストライプはすべて完成されたものであると言える。
図３および図４で説明したように、図５に示すスペース割り当てアルゴリズムは処理されるダーティバッファのいずれに対しても呼び出される。図３および図４に示すアルゴリズムは１ファイルずつ処理を行い、それらファイルは順次処理が行われる。従って、ダーティバッファのためのスペース割り当てアルゴリズムはランダムに呼び出されるのではなく、各ファイルに対して複数のダーティバッファについて呼び出されることとなる。
本願発明においては、ＲＡＩＤアレイのディスクに一群のブロックを割り当てる際、２つの制約条件を満たす必要がある。第１の制約条件は、先読み機能を改良するため、各個別のファイルに係る連続した一連のブロックを同じディスク上に割り当てることである。第２の制約条件は、ＲＡＩＤアレイの書き込み機能を改良するため、１つのストライプにおけるすべてのフリーブロックを同時に割り当てることである。
このアルゴリズムにおいては、割り当てのため特定のファイルを選択し、ＲＡＩＤアレイから、ファイルのダーティブロックの割り当て先にするためのディスクを選択し、ファイルの連続した一連のダーティブロック用に、ディスク上において連続した一連のフリーブロックを割り当てることにより第１の制約条件を満たしている。またこのアルゴリズムにおいては、０から始め、ブロック割り当てが起こるたびに現在の書き込みデータをインクリメントさせ、ディスクの終端までこのインクリメントを繰り返し、各ディスクにおいて現在の書き込み位置の情報を正しく保つことにより第２の制約条件が満たされる。ＲＡＩＤアレイにおけるすべてのディスクの現在の書き込み位置を互いに近い値になるようにすることにより、同じストライプにおけるブロックはほぼ同じ時に割り当てが行われる。現在の書き込み位置情報を互いに接近した値に保つための一つの方法として、ディスク上で割り当てるブロックを常に現在の書き込み情報が１番低い値のものを選ぶようにする方法がある。
同時に１つのストライプでブロックをＲＡＩＤに送るためには要求を遅延させる（バックログ処理する）必要がある。なぜなら、ディスク間において必ずしも同じ現在書き込み位置情報を有しているとは限らないからである。従って、各ディスク毎に書き込むべきバッファのキューが備わっている。ディスク上のブロックナンバーがすべてのディスクにおける現在の書き込み位置情報の最低値より小さい値を有するバッファは書き込みに最も適したバッファである。本願発明においては、ＲＡＩＤアレイにおけるすべてのディスクをスキャンし、同じ現在書き込み位置情報を有するブロック（すなわち同じストライプにあるバッファ）を見付け、ストライプ毎のバッファをＲＡＩＤサブシステムに送り込むことができるようにする。この点については以下にさらに詳述する。
ダーティバッファを有するｉノードの処理
図７に示すダーティｉノードのリスト７１０は、図３に示すフローチャートに基づき以下のように処理される。ステップ３２０において、ｉノード７２０はダーティｉノードのリスト７１０から選びだされる。ＷＡＦＬのインコアのｉノード７２０により参照されるツリー構造のバッファについては、ステップ３３０において書き込みのための割り当てが行われる。判断ブロック３４０においてダーティｉノードのリスト７２０にあるすべてのｉノードが処理されたか否かが判断される。判断ブロック３４０の結果が偽（ＮＯ）であれば、ステップ３２０へ進む。ステップ３２０では、ダーティバッファを有する次のｉノード７２２が選ばれる。ｉノード７２２はリスト７１０における前のｉノード７２０によって参照される。ステップ３３０において、ＷＡＦＬのインコアのｉノード７２２によって参照されるツリー構造のバッファについて、書き込みのための割り当てが行われる。判断ブロック３４０において、ダーティｉノードのリスト７１０にあるすべてのｉノードが処理されたか否かが判断される。判断ブロック３４０の結果が偽（ＮＯ）であったとする。この場合はｉノード７３０および７４０は同様な方法で処理される。ステップ３３０において、ｉノード７４０について、書き込みのための割り当てが行われた場合、判断ブロック３４０においてダーティリストにおけるすべてのｉノードが処理されたか否かがチェックされる。判断ブロック３４０の結果が偽（ＮＯ）であれば、ステップ３２０に進む。
ステップ３２０においてｉノード７４０によりポイントされるｉノード７５０がダーティｉノードのリスト７１０から選出される。ステップ３３０においてｉノード７５０は書き込みのためにディスクに割り当てられる。判断ブロック３４０において、ダーティｉノードのリスト７１０におけるすべてのｉノードが処理されたか否かが判定される。ここでポインタ７５０Ａは空である。従って、ｉノード７５０はリスト７１０においては次のｉノードの指定を行うことはない。従って、判断ブロック３４０の結果は真（ＹＥＳ）となり、続いてステップ３５０が実行される。ステップ３５０においては、書き込まれていないストライプはすべてディスクへ書き出される。従って、ステップ３５０においてダーティｉノードのリスト７１０におけるダーティｉノード７２０〜７５０のすべてについて書き込みのための割り当てが行われたとすれば、キュー状態にあるバッファや未完成のストライプは以下に説明するように、すべて強制的にディスクに送り出される。ステップ３６０においてこのアルゴリズムは終了する。
ツリー構造のバッファに係る書き込みのための割り当て
図８は、ｉノード８１０により参照されるバッファ８２０〜８５０，８６０Ａ〜８６０Ｆ，８７０Ａ〜８７０Ｄのツリー構造の割り当てを示すものである。ＷＡＦＬｉノード８１０は１６個のバッファポインタ８１０Ａと、１６個のバッファポインタ８１０Ａを参照するＷＡＦＬバッファデータ構造８１０Ｂで構成される。図８において、間接バッファ８２０および８３０はダーティであり、間接バッファ８４０〜８５０はクリーンである。同様に直接バッファ８６０Ａ〜８６０Ｂおよび８６０Ｄはダーティであり、直接８７０Ｂもダーティである。残りのすべてのバッファはクリーンである。ここでは、図６で示したＷＡＦＬバッファの簡単化されたものが示されている。この図８における簡単化されたブロック図は図５に示すアルゴリズムを説明するためのものである。
図８において、ＷＡＦＬｉノード８１０はＷＡＦＬバッファ８２０〜８５０，８６０Ａ〜８６０Ｆ，８７０Ａ〜８７０Ｄのツリー構造を参照する。ＷＡＦＬｉノード８１０の１６個のバッファポインタ８１０ＡはＷＡＦＬバッファ構造８１０により参照される。続いて、バッファポインタ８１０Ａは間接ＷＡＦＬバッファポインタ８２０〜８５０のそれぞれを参照する。図８において、バッファポインタ８１０ＡはダーティＷＡＦＬバッファ８２０、ダーティＷＡＦＬバッファ８３０、クリーンＷＡＦＬバッファ８４０、クリーンＷＡＦＬバッファ８５０を参照する。間接ＷＡＦＬバッファのそれぞれは、（図６に示すディスク上のボリュームブロックナンバー６２０Ｃと共に）１０２４個の直接ＷＡＦＬバッファを参照する１０２４個のバッファポインタを備えた構成される。直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｂおよび８６０Ｄはダーティである。間接ＷＡＦＬバッファ８２０により参照される直接ＷＡＦＬバッファ８６０Ｃおよび８６０Ｅ〜８６０Ｆはクリーンである。間接ＷＡＦＬバッファ８３０により参照される直接ＷＡＦＬバッファ８７０Ｂもダーティである。直接ＷＡＦＬバッファ８７０Ａおよび８７０Ｃ〜８７０Ｄはクリーンである。
すべての子バッファに対し深さ優先ポストビジトトラバーサルを行う一方、ダーティＷＡＦＬバッファを新しいブロックに割り当てる方法を図４を参照しながら以下に述べる。ステップ４１０において、書き込みのための割り当てアルゴリズムには、ＷＡＦＬｉノード８１０の１６個のバッファポインタ８１０Ａを参照するＷＡＦＬｉノード８１０のＷＡＦＬバッファ構造８１０Ｂのバッファポインタがわたされる。判断ブロック４２０において、ＷＡＦＬバッファ構造８１０Ｂに含まれるバッファポインタのすべての子バッファ（この場合間接ＷＡＦＬバッファ８２０〜８５０）のすべてが処理されたか否かが判断される。判断ブロック４２０の結果が偽（ＮＯ）であったとする。ステップ４４０において間接ＷＡＦＬバッファ８２０が８１０ＢにおけるＷＡＦＬバッファポインタの子バッファであるとして取り込まれる。判断ブロック４５０において、間接ＷＡＦＬバッファポインタ４５０がツリー構造における残っているものの中で最下位のものか否かが判断される。判断ブロック４５０の結果が偽（ＮＯ）であれば、ステップ４６０へ進む。ステップ４６０では、間接ＷＡＦＬバッファ８２０のバッファポインタをわたすことにより、書き込みのための割り当てアルゴリズムに対する呼び出しが行われる。従って、書き込みのための割り当てアルゴリズムが再帰的に呼び出される。
ステップ４１０において、間接ＷＡＦＬバッファ８２０に対するバッファポインタをわたすことにより、書き込みのための割り当てアルゴリズムが呼び出される。判断ブロック４２０において、間接ＷＡＦＬバッファポインタ８２０のすべての直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｆが処理されたか否かが判断される。判断ブロック４２０の結果が偽（ＮＯ）であったとする。ステップ４４０において、直接ＷＡＦＬバッファ８６０Ａが取得される。判断ブロック４５０において直接ＷＡＦＬバッファ８４０はツリー構造において残っているものの内の最下位のものであるか否かが判断される。判断ブロック４５０の結果が真（ＹＥＳ）であれば、判断ブロック４８０へ進む。判断ブロック４８０では、直接ＷＡＦＬバッファ８６０Ａはダーティであるか否かが判断される。ここでは判断ブロック４８０からは真（ＹＥＳ）の結果が得られる。なぜなら、直接ＷＡＦＬバッファ８６０Ａはダーティだからである。ステップ４９０において、ＷＡＦＬバッファ８６０Ａに対するバッファポインタを図５に示すスペース割り当てアルゴリズムへわたすことにより直接ＷＡＦＬバッファ８６０Ａのスペースが割り当てられる。直接ＷＡＦＬバッファ８６０Ａのスペースが割り当てられれば、判断ブロック４２０へと進む。
判断ブロック４２０では、直接ＷＡＦＬバッファ８２０の子バッファのすべてが処理されたか否かが判断される。判断ブロック４２０の結果が偽（ＮＯ）であったとする。ステップ４４０で直接ＷＡＦＬバッファ８６０Ｂが取り込まれる。判断ブロック４５０において、直接ＷＡＦＬバッファ８６０Ｂはツリー構造に残っているレベルの内の最下位のものであるか否かが判断される。判断ブロック４５０の結果が真（ＹＥＳ）であったとする。判断ブロック４８０において、直接ＷＡＦＬバッファ８６０Ｂはダーティであるか否かが判断される。判断ブロック４８０の結果が真（ＹＥＳ）であるので、ステップ４９０において直接ＷＡＦＬバッファ８６０Ｂにディスクスペースが割り当てられる。ステップ４９０においてスペースの割り当ての呼び出しが完了すれば、次に判断ブロック４２０へ進む。
判断ブロック４２０において、間接ＷＡＦＬバッファ８２０のすべての子バッファが処理されたか否かが判断される。判断ブロック４２０の結果はここでは偽（no）となる。ブロック４４０において、直接ＷＡＦＬバッファ８６０Ｃが取り込まれる。判断ブロック４５０において、直接ＷＡＦＬバッファ８６０Ｃがツリー構造において残っているレベルの内で最も低いレベルであるか否かが判断される。判断ブロック４５０の結果はここでは真（yes）である。判断ブロック４８０において、直接ＷＡＦＬバッファ８６０Ｃがダーティであるか否かが判断される。ここでは直接ＷＡＦＬバッファ８６０は修正されておらず、したがってクリーンであるので判断ブロック４８０の結果は偽（no）である。続いて判断ブロック４２０が実行される。図４に示すこの間接ＷＡＦＬバッファ８２０の子バッファに対するスペースの割り当てプロセスは、直接ＷＡＦＬバッファ８６０Ｆ（１０２４番目のバッファ）が処理されるまで続行される。直接ＷＡＦＬバッファ８６０Ｆ（間接ＷＡＦＬバッファ８２０の最後の子バッファ）はクリーンであるので、判断ブロック４８０の結果は偽（no）である。続いて判断ブロック４２０が実行される。判断ブロック４２０において、間接ＷＡＦＬバッファ８２０の子バッファ（直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｆ）のすべてが処理されたか否かが判断される。ここでは判断ブロック４２０の結果は真（yes）であるので、ステップ４３０において呼び出しアルゴリズムが実行される。
ステップ４３０において、再起的呼び出しにより判断ブロック４８０が実行される。判断ブロック４８０において、子バッファ（間接ＷＡＦＬ８２０）がダーティであるか否かが判断される。判断ブロック４８０の結果はここでは真（yes）であるので、続いてステップ４９０が実行される。ステップ４９０において、間接ＷＡＦＬバッファ８２０に対するバッファポインタをわたしてスペース割り当てアルゴリズムを呼び出すことにより、間接ＷＡＦＬバッファ８２０に対しディスクスペースが割り当てられる。ステップ４９０の処理が終わると、判断ブロック４２０が実行される。
判断ブロック４２０において、ＷＡＦＬｉノード８１０のＷＡＦＬバッファ構造８１０Ｂに含まれるバッファポインタのすべての子バッファ（間接ＷＡＦＬバッファ８２０〜８５０）について処理が終わったか否かが判断される。判断ブロック４２０の結果はここでは偽（no）である。ステップ４４０において、間接ＷＡＦＬバッファ８３０が取り込まれる。判断ブロック４５０において間接ＷＡＦＬバッファ８３０がツリー構造に残っているレベルの最も低いレベルであるか否かが判断される。判断ブロック４５０の結果が偽（no）であるので、続いてステップ４６０が実行される。ステップ４６０において、間接ＷＡＦＬバッファ８３０に対するバッファポインタをわたすことにより、書き込みのための割り当てアルゴリズムが再起的に呼び出される。その後図４に示すアルゴリズムを実行するステップ４１０が開始される。
ステップ４１０において、間接ＷＡＦＬバッファ８３０に対するバッファポインタは書き込みのための割り当てアルゴリズムにわたされる。判断ブロック４２０において、間接ＷＡＦＬバッファ８３０のすべての子バッファ（直接ＷＡＦＬバッファ８７０Ａ〜８７０Ｄ）が処理されたか否かが判断される。判断ブロック４２０の結果はここでは偽（no）であるので、続いてステップ４４０が実行される。ステップ４４０において、直接ＷＡＦＬバッファ８７０Ａ（間接ＷＡＦＬバッファ８３０の子バッファ）が取り込まれる。判断ブロック４５０において、直接ＷＡＦＬバッファ８７０Ａがツリー構造における残りのレベルにおける最下位のレベルであるか否かが判断される。判断ブロック４５０の結果は真（yes）であるので、続いて判断ブロック４８０が実行される。判断ブロック４８０において、直接ＷＡＦＬバッファ８７０Ａが修正され、したがってダーティな子バッファであるか否かが判断される。判断ブロック４８０の結果は偽（no）である。なぜなら直接ＷＡＦＬバッファ８７０Ａはクリーンであるからである。続いて判断ブロック４２０が実行される。
判断ブロック４２０において、間接ＷＡＦＬバッファ８３０の次の子バッファ（直接ＷＡＦＬバッファ８７０Ｂ）が処理されたか否かが判断される。判断ブロック４２０の結果が偽（no）であるので、続いてステップ４４０が実行される。ステップ４４０において、直接ＷＡＦＬバッファ８７０Ｂが取り込まれる。判断ブロック４５０において、直接ＷＡＦＬバッファ８７０Ｂがツリー構造に残っているレベルの最下位レベルであるか否かが判断される。判断ブロック４５０の結果は真（yes）であるので、続いて判断ブロック４８０が実行される。判断ブロック４８０において、直接ＷＡＦＬバッファ８７０Ｂがダーティバッファであるか否かが判断される。判断ブロック４８０の結果が真（yes）であるので、続いてステップ４９０が実行される。ステップ４９０において直接ＷＡＦＬバッファ８７０Ｂに対するバッファポインタを用いてスペース割り当てアルゴリズムを呼び出すことにより直接ＷＡＦＬバッファ８７０Ｂに対しディスクスペースが割り当てられる。その後判断ブロック４２０が実行される。
親の間接ＷＡＦＬバッファ８３０の残りのクリーンな直接ＷＡＦＬバッファ８７０Ｃ〜８７０Ｄは、図４に示すアルゴリズムにより処理される。間接ＷＡＦＬバッファ８３０の子である残りの直接ＷＡＦＬバッファ８７０Ｃ〜８７０Ｄはクリーンであるので、これらのバッファに対してはディスクスペースは割り当てられない。判断ブロック４８０において直接ＷＡＦＬバッファ８７０Ｃ−８７０Ｄがダーティであるか否かの判断がなされるが、その結果は偽（no）である。続いて判断ブロック４２０が実行される。判断ブロック４２０において間接ＷＡＦＬバッファ８３０のすべての子バッファ（直接ＷＡＦＬバッファ８７０Ａ〜８７０Ｄ）が処理されたか否かが判断される。判断ブロック４２０の結果が真（yes）であるので、続いてステップ４３０が実行される。ステップ４３０において、呼び出しアルゴリズムが実行される。続いて判断ブロック４８０が実行される。
判断ブロック４８０において間接ＷＡＦＬバッファ８３０がダーティであるか否かが判断される。判断ブロック４８０の結果は真（yes）であるので、続いて４９０が実行される。ステップ４９０において、スペース割り当てアルゴリズムを呼び出して、それに間接ＷＡＦＬバッファ８３０に対するバッファポインタをわたすことにより、間接ＷＡＦＬバッファ８３０に対しディスクスペースが割り当てられる。その後判断ブロック４２０が実行される。
判断ブロック４２０において、ＷＡＦＬｉノード８１０のＷＡＦＬバッファ構造８１０Ｂに含まれるバッファポインタの子バッファ（間接ＷＡＦＬバッファ８２０〜８５０）のすべてが処理されたか否かが判断される。したがって、間接ＷＡＦＬバッファ８４０〜８５０は、間接ＷＡＦＬバッファ８５０が処理されるまで、上述したように書き込みのための割り当てアルゴリズムにより再起的に処理される。
判断ブロック４８０において間接ＷＡＦＬバッファ８５０がダーティであるか否かが判断されれば、この判断ブロック４８０の結果は偽（no）となる。なぜなら間接ＷＡＦＬバッファ８５０はクリーンだからである。その後判断ブロック４２０は実行される。判断ブロック４２０においてＷＡＦＬｉノード８１０のＷＡＦＬバッファ構造８１０Ｂに含まれるバッファポインタのすべての子バッファ（間接ＷＡＦＬバッファ８２０〜８５０）が処理されたか否かが判断される。判断ブロック４２０の結果は真（yes）であるので、この場合は図３に示す主アルゴリズム、すなわち呼び出しアルゴリズムが実行される。したがって、ツリー構造におけるすべてのバッファ、すなわち間接ＷＡＦＬバッファ８２０〜８５０、およびＷＡＦＬｉノード８１０（ｉノード８１０は図７に示すダーティｉノードのリスト７１０のＷＡＦＬｉノード７２０に相当する）により参照される直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｆおよび８７０Ａ〜８７０Ｄが処理される。図８に示すようにＷＡＦＬｉノード８１０により参照されるツリー構造におけるすべてのバッファの深さ優先ポストビジテッドトラバーサルが実行される。このようにしてダーティな子バッファに対し新しいディスクスペースの割り当てが行なわれる。上述したごとく、間接ＷＡＦＬバッファ８２０が最初に訪問（visit）される。続いて間接ＷＡＦＬバッファ８２０の子バッファが順次処理される。間接ＷＡＦＬバッファ８２０の直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｆはツリー構造における残りのレベルの内の最下位レベルに相当するので、それらが順次処理される。直接ＷＡＦＬバッファ８６０Ａはダーティな子バッファであるので、それに対しディスクスペースの割り当てが行なわれる。これは、直接ＷＡＦＬバッファ８６０Ａ内に含まれた数字１によって示されるものである。続いて、直接ＷＡＦＬバッファ８６０Ｂ（数字２によって示される）に対しディスクスペースの割り当てが行なわれる。直接ＷＡＦＬバッファ８６０Ｃはクリーンであるので、図４のステップ４９０においてディスクスペースの割り当ては行なわれない。このようにして、直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｆは、もしそれらがダーティであれば、ディスクスペースの割り当てが行なわれる。
間接ＷＡＦＬバッファ８２０の直接ＷＡＦＬバッファ８６０Ａ〜８６０Ｆが、一旦処理されると、間接ＷＡＦＬバッファ８２０に対しディスクスペースの割り当てが行なわれる。これはダーティバッファであるのでディスクスペースの割り当てはステップ４９０において行なわれる。同様に、直接ＷＡＦＬバッファ８７０Ｂについてもディスクスペースの割り当てが行なわれる。続いて、直接ＷＡＦＬバッファ８７０Ｂの親バッファ（間接ＷＡＦＬバッファ８３０）に対しディスクスペースの割り当てが行なわれる。割り当てはこれで終了したわけだが、バッファをディスクに書き込む順番は次の通りである。直接ＷＡＦＬバッファ８６０Ａ，８６０Ｂ，８６０Ｄ；間接ＷＡＦＬバッファ８２０；直接ＷＡＦＬバッファ８７０Ｂ；および間接ＷＡＦＬバッファ８３０。
ダーティバッファに対するディスクスペースの割り当て
図９Ａはメモリに記憶されたキャシュ９２０と、パリティディスクとデータディスク０〜３で構成されるＲＡＩＤアレイのディスクスペース９１０が示されている。図５に示したスペース割り当てアルゴリズムについて、図９の４つのファイル９４０〜９４６を参照しながらさらに詳述する。最初、データディスク０〜３のＣＷＬポインタは同じブロックにセットされている。カレント書き込み位置ポインタ９３０Ａ〜９３０Ｄはそれぞれデータディスク０〜３のデータブロック９５０Ｂ〜９５０Ｅを参照する。図９に示すように４つのファイル９４０〜９４６はキャシュ９２０に含まれている。最初のファイル９４０は２つのダーティブロックＦ１−０、Ｆ１−１で構成される。第２のファイル９４２は１６個のダーティブロックＦ２−０からＦ２−１５で構成される。第３のファイル９４４は４つのダーティブロックＦ３−０からＦ３−３で構成される。第４のファイル９４６は２つのダーティブロックＦ４−０、Ｆ４−１で構成される。ディスクスペース９１０のデータディスク０〜３において×印は割り当てがなされたブロックを示す。さらに、キャシュ９２０にはデータディスク０〜３のそれぞれに対応する４つのディスクキュー９２０Ａ〜９２０Ｄが示されている。
図７に示すように、４つのファイル９４０〜９４６のそれぞれはダーティｉノードのリスト７１０にあるｉノードを参照する。たとえば、図７において、ｉノード７２０は第１のファイル９４０を参照する。ダーティｉノードのリスト７１０の他のｉノード７２２、７３０、７４０は、それぞれファイル９４２〜９４６を参照する。ダーティｉノードのリスト７１０にあるこれらのｉノードは、上述したごとく処理される。以下、ディスク上におけるブロックの割り当て、およびディスクへのストライプの書き込みについて図５を参照しながら説明する。
図９Ａに示すように、データディスク０〜３のカレント書き込み位置９３０Ａ〜９３０Ｄは、データブロック９５０Ｂ〜９５０Ｅをそれぞれ参照する。これはブロック９５０Ｂ〜９５０Ｅのそれぞれの左下コーナにある小さな箱により表される。同様に図９Ａに示すように、データディスク０〜３のキュー９２０Ａ〜９２０Ｄは空である。図９Ａにおいて、ディスクブロックに付された×印は、ディスクスペース９１０においてすでに割り当てが行なわれたブロックであることを示す。垂直に延びるコロムのそれぞれは、データディスク０〜３のそれぞれのディスクスペース９１０におけるシリンダに対応する。スペース割り当てアルゴリズムにより処理される最初のファイルは９４０である。
ステップ５１０において、アルゴリズムには、ファイル９４０のバッファＦ１−０に対するバッファポインタがわたされる。判断ブロック５２０において、バッファＦ１−０は前回のバッファとは異なったファイルにあるのかどうか、または前回のバッファとは異なった先読みチャンクにあるのかどうかについて判定される。判定ブロック５２０は、ここではバッファＦ１−０は異なったファイルにあるので真（yes）を出力する。ステップ５３０においてデータディスク０が書き込みのために選択される。ステップ５４０においてバッファＦ１−０で前回割り当てられたブロックはフリーにされる。ステップ５５０において、データディスク０のデータブロック９５２はバッファＦ１−０用に選ばれたディスク上に割り当てる。また、ＣＷＬ９３０Ａは進められ、ディスク上の次のフリーな位置を参照する。ステップ５６０において、ディスクブロック９５２Ｂは、ファイル９４０のバッファＦ１−０に対して割り当て指定される。ステップ５７０においてバッファＦ１−０は、データディスク０のための書き込み可能なバッファのリスト９２０Ａに対して割り当て指定される。ステップ５８０において、ＣＷＬに対しそれがファイルシステムの中における最下位のＣＷＬか否かが判断される。ここではこれは真ではないので、続いて５９０が実行される。
ファイル９４０において別のバッファＦ１−１はダーティであるので、スペース割り当てアルゴリズムは再び呼び出される。続いてステップ５１０が実行され、アルゴリズムには、バッファＦ１−１に対するポインタがわたされる。判断ブロック５２０において、バッファＦ１−１は、前回のバッファ（この場合は、バッファＦ１−０）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断ざれる。判断ブロック５２０の結果は偽（no）であるので、続いてステップ５４０が実行される。したがって、バッファＦ１−１はバッファＦ１−０が書かれたディスクと同じディスクに書き込みがなされる。図９Ｂに示すように、データブロック９５４Ｂが割り当てられるので、データディスク０において次に割り当てられることができるフリーなブロックはブロック９５６Ｂである。ステップ５４０において、バッファＦ１−１の前回割り当てられたブロックはフリーにされる。ステップ５５０において、データディスク上にあるブロック９５６Ｂは、バッファＦ１−１用として割り当てられる。ステップ５６０において、ブロック９５６Ｂは、バッファＦ１−１用として割り当てられる。ステップ５７０において、バッファＦ１−１は、データディスク０のキュー９２０Ａに当てられる。データディスク０のＣＷＬ９３０Ａは、データディスク０のブロック９５６Ｂを参照する。ステップ５８０において、ストライプが完成され、ディスクに送られるのに準備ができたかどうかが判断されるが、この時点ではストライプがまだ完成されていない。続いてステップ５９０が実行される。
図９Ｂに示すように、第１のファイル９４０にディスクスペースが割り当てられたが、バッファＦ１−０およびＦ１−１は、まだディスク上に書き込まれていない。それらはデータディスク０のキュー９２０Ａのメモリに記憶されたままである。
図９Ｃにおいて、次のファイル９４２がディスクスペース９１０に割り当てられる。第２のファイル９４２は、１６個のダーティブロックＦ２−０からＦ２−１５で構成される。ファイル９４２の最初のバッファＦ２−０は、ステップ５１０においてアルゴリズムへわたされる。判断ブロック５２０において、バッファＦ２−０は、前回のバッファ（この場合はバッファＦ１−１）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。ここではバッファＦ２−０は、異なったファイルにあるので、判断ブロック５２０の結果は真（yes）となる。ステップ５３０において、データディスク１が書き込み用として選択される。ステップ５４０において、前に割り当てられたブロックはフリーにされる。ステップ５５０において、ブロック９５２Ｃは、データディスク１の上に割り当てられる。ステップ５６０において、ブロック９５２Ｃは、ファイル９４２のバッファＦ２−０に対して割り当て指定される。ステップ５７０において、データディスク１のための書き込み可能バッファのリスト９２０Ｂに、バッファＦ２−０が加えられる。ステップ５８０において、ストライプがディスクに書き込み可能かどうかの判断がなされる。しかしながら、この時点においては書き込まれるべきブロックはＲＡＩＤアレイにおける最下位のＣＷＬよりも低いブロックではないので、ストライプは書き込み可能な状態ではないことがわかる。したがって、続いてステップ５１０のアルゴリズムが実行される。
図４に示すアルゴリズムは、ダーティファイルバッファＦ２−１に対するポインタを、図５に示すステップ５１０へわたす。判断ブロック５２０において、バッファＦ２−１は、前回のバッファ（Ｆ２−０）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。判断ブロック５２０の結果は偽（no）であるので、続いてステップ５４０が実行される。ステップ５４０において、バッファＦ２−１で前回割り当てられたブロックがフリーにされる。ステップ５５０において、データディスク１のブロック９５４Ｃが割り当てられる。ステップ５６０において、ブロック９５４ＣがバッファＦ２−１に割り当てられる。ステップ５７０において、バッファＦ２−１は、データディスク１のための書き込み可能なバッファのリスト９２０Ｂに加えられる。ステップ５８０において、データディスク１のＣＷＬ９３０Ｂは、ブロック９５４Ｃに進められる。次に、ストライプがディスクに書き込み可能かどうかの判断がなされる。しかしながら、ここではデータディスク１のＣＷＬ９３０Ｂはディスクスペース９１０におけるＣＷＬポインタの最下位のものではないので、ストライプの書き込みは可能でない。したがって、続いてステップ５９０が実行される。
図５に示すアルゴリズムに従い、バッファＦ２−２からＦ２−６は、ディスク上のスペースが割り当てられる。８番目のバッファＦ２−７のためにスペース割り当てアルゴリズムが呼びだされれば、判断ブロック５２０において、バッファＦ２−７は、前回のバッファ（Ｆ２−６）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。判断ブロック５２０の結果は偽（no）であるので、続いてステップ５４０が実行される。ステップ５４０ではバッファＦ２−７で前回割り当てられたブロックがフリーにされる。ステップ５５０で、ブロック９６８Ｃがデータディスク１に割り当てられる。ステップ５６０において、ブロック９６８ＣがバッファＦ２−７に割り当てられる。ステップ５７０において、バッファＦ２−７は、データディスク１のための書き込み可能バッファのリスト９２０Ｂに加えられる。ステップ５８０において、もし可能な場合はストライプの書き込みがなされる。ここでブロック９７０は、すでに割り当てられているので、データディスク１のＣＷＬ９３０Ｂは、ブロック９７０へ進められる。データディスク１のブロック９７０Ｃは、ディスクスペース９１０における最下位のＣＷＬではないので、ディスクにストライプは書き込みはまだなされない。
図５のステップ５１０において、ファイル９４２のバッファＦ２−８に対するバッファポインタをわたすことにより、スペース割り当てアルゴリズムが呼び出される。判断ブロック５２０においてバッファＦ２−８は前回のバッファ（Ｆ２−７）から異なったファイルにあるか否か、または前回のバッファ（Ｆ２−７）とは異なった先読みチャンクにあるか否かが判断される。ファイル９４２の８個のバッファＦ２−０からＦ２−７は、前回の先読みチャンクの１部であり、すでにスペースの割り当てが行なわれていたので、判断ブロック５２０の結果は真（yes）となる。ステップ５３０において、データディスク２が書き込み用として選択される。これは図９Ｄに示されている。
ステップ５３０において、最も低いカレント書き込み位置情報を有するディスクを見つけることにより、ディスクの選択がなされる。もし複数のディスクが最も低いカレント書き込み位置情報を有していたのであれば、最初に位置するものが選択される。
ステップ５４０において、バッファＦ２−８の前に割り当てられたブロックがフリーにされる。ステップ５５０においてブロック９５２Ｄは、データディスク２上に割り当てられる。ステップ５６０において、ブロック９５２Ｄは、バッファＦ２−８に割り当て指定される。ステップ５７０において、データディスク２のキュー９２０ＣにバッファＦ２−８が加えられる。ステップ５８０において、可能な場合はストライプの書き込みがなされる。しかしながら、ここではバッファＦ２−８のためのディスクにストライプを一気に書き出すための準備はできていない。したがってステップ５１０が実行される。
ステップ５１０において、ファイル９４２のバッファＦ２−９に対するポインタは、スペース割り当てアルゴリズムにわたされる。判断ブロック５２０において、バッファＦ２−９は、前回のバッファ（Ｆ２−８）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。ここでは、バッファＦ２−９は前回のバッファＦ２−８と同じファイルで同じ先読みチャンクにあるので、判断ブロック５２０の結果は偽（no）である。ステップ５４０において、バッファＦ２−９で前回割り当てられたブロックはフリーにされる。ステップ５５０において、ブロック９５４Ｄは、データディスク２上に割り当てられる。ステップ５６０において、データディスク２のブロック９５４Ｄは、バッファＦ２−９に対して割り当て指定される。ステップ５７０において、バッファＦ２−９は、データディスク２のための書き込み可能なバッファのリスト９２０Ｃに加えられる。ステップ５８０において、ディスクにストライプの書き込みが試みられるが、この時点ではまだストライプの書き込みは可能ではない。
図９Ｄに示すように、ディスクブロック９５２Ｄから９６８Ｄは、ファイル９４２のバッファＦ２−８からＦ２−１５のために割り当てられる。図５に示すアルゴリズムに基づき、ダーティバッファＦ２−８からＦ２−１５のためにブロックが割り当てられるので、バッファＦ２−８からＦ２−１５は、データディスク２のための書き込み可能なバッファのリスト９２０Ｃに加えられる。ステップ５８０において、システムは、ディスクにストライプの書き込みを試みる。しかしながら、この時点ではまだ完全なストライプを書き込みすることができない。ステップ５９０において呼び出しアルゴリズムが実行される。
ダーティｉノードのリスト７１０にあるｉノードを参照して得られる第３のファイルは、９４４である。ファイル９４４は、４つのダーティブロックＦ３−０からＦ３−３で構成される。ファイル９４４のダーティバッファＦ３−０からＦ３−３は、スペース割り当てアルゴリズムにより処理される。ファイル９４４のダーティバッファの割り当てを、図９Ｅから９Ｆを参照しながら説明する。ステップ５１０において、スペース割り当てアルゴリズムには、ファイル９４４のバッファＦ３−０に対するバッファポインタがわたされる。判断ブロック５２０において、ファイル９４４のバッファＦ３−０は、前回のバッファ（ファイル９４２のバッファＦ２−１５）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。判断ブロック５２０はここではバッファＦ３−０が異なったファイルにあるので、真（yes）を出力する。ステップ５３０において、１番低いＣＷＬ（データブロック９５０Ｅについて示された図９Ｄを参照）を有するデータディスク３が、書き込み用のディスクとして選択される。ステップ５４０において、バッファＦ３−０のために前回割り当てられたブロックは、フリーにされる。これは、ブロック９５２Ｅのためのblkmapファイルのすべてを更新して、ブロック９５２Ｅが、もはやアクティブファイルシステムによって利用されるものではないことを示すことにより達成される。ステップ５４０において、データディスク３の現在の（カレント）ブロック９５２Ｅが割り当てられる。これはデータディスク３のカレント書き込み位置（ＣＷＬ）９３０Ｄを、データブロック９５２Ｅに進めることにより達成される。ステップ５６０において、ブロック９５２Ｅは、ファイル９４４のバッファＦ３−０に対して割り当て指定される。ステップ５７０において、バッファＦ３−０は、データディスク３のための書き込み可能なバッファのリスト９２０Ｄに加えられる。
ステップ５８０において、可能な場合は、ストライプがディスクに書き込まれる。これはデータディスク０〜３のバッファ９２０Ａ〜９２０Ｄをチェックして、完成したストライプがあるか否かを見ることにより、達成される。図９Ｅにおいて、完成されたストライプは、バッファＦ１−０、Ｆ２−０、Ｆ２−８、Ｆ３−０を備えたディスクキュー９２０Ａ〜９２０Ｄに含まれる。これらのバッファは、１つのグループとしてＲＡＩＤサブシステムに送り出され、効率よく書き込みがなされる。この状態は図９Ｅに示されており、ストライプ９８０は、パリティブロック９５２Ａと、データディスク０〜３のデータブロック９５２Ｂ〜９５２Ｅに書き込まれる。ここでストライプは点線で囲まれて示されている。したがって、バッファＦ１−０は、データディスク０のブロック９５２Ｂに書き込まれる。同様に、バッファＦ２−０、Ｆ２−８、Ｆ３−０は、それぞれブロック９５２Ｃ、９５２Ｄ、９５２Ｅに書き込まれる。図９Ｅに示すように、データディスク３の最も低いカレント書き込み位置（ＣＷＬ）９３０Ｄは、ブロック９５２Ｅに位置している。ストライプ５８０がディスクに書き込まれることにより、バッファＦ１−０、Ｆ２−０、Ｆ２−８、Ｆ３−０は、キュー９２０Ａ〜９２０Ｄから削除される。これは図９Ｅに示されている。続いて呼び出しルーチンであるステップ５９０が実行される。
ファイル９４４のバッファＦ３−１のバッファポインタは、ステップ５１０で、スペース割り当てアルゴリズムにわたされる。判断ブロック５２０において、バッファＦ３−１は、前回のバッファから異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。判断ブロック５２０の結果は偽（no）であるので、続いてステップ５４０が実行される。ステップ５４０において、バッファＦ３−１に前回割り当てられたブロックは、フリーにされる。ステップ５５０において、ブロック９５４Ｅがデータディスク３に割り当てられる。データディスク３のカレント書き込み位置９３０Ｄは、図９Ｅに示すブロック９５２Ｅから、図９Ｆに示すブロック９５６Ｅに進められる。カレント書き込み位置９３０Ｄは、ブロック９５６Ｅに進められ、これは現在割り当てられたブロック９５４Ｅを下に越えることになる。なぜなら、ブロック９５６Ｅはすでに割り当て（ブロックにおいて×印で示されている部分）がなされているからである。ステップ５６０において、ブロック９５４Ｅは、ファイル９４４のバッファＦ３−１に対して割り当て指定される。ステップ５７０において、バッファＦ３−１はデータディスク３のための書き込み可能なバッファのリスト９２０Ｄに加えられる。ステップ５８０において、２つのストライプ９８２、９８４は、ディスクに書き込まれる。これはデータディスク０および３にある最も低いカレント書き込み位置９３０Ａ、９３０Ｄが、データブロック９５６Ｂ、９５６Ｅを参照することによりなされる。図９Ｆに示すように、バッファＦ２−１、Ｆ２−９、Ｆ３−１で構成されるストライプ９８２は、ブロック９５４Ｃから９５４Ｅに書き込まれる。同様にストライプ９８４もディスクに書き込まれる。ストライプ９８２および９８４がディスクに書き込まれれば、対応するバッファは、リスト９２０Ａ〜９２０Ｄから削除される。ステップ５９０において呼び出しアルゴリズムが次に実行される。
同様に、図５に示すアルゴリズムにより、ファイル９４４のバッファＦ３−２、Ｆ３−３には、ディスクブロック９５８Ｅ、９６０Ｅが割り当てられる。図９Ｇに示すように、ファイル９４４のバッファＦ３−２、Ｆ３−３は、データディスク３のリスト９２０Ｄに割り当てられる。ファイル９４４に対しカレント書き込み位置９３０Ｄは、データディスク３のブロック９６０Ｅに進められる。図９Ｇに示すように、最も低いカレント書き込み位置は、データブロック９５６Ｂを参照するデータディスク０のカレント書き込み位置９３０Ａである。他のカレント書き込み位置９３０Ｂ〜９３０Ｄは、データディスク１〜３のブロック９７０Ｃ、９６８Ｄ、９６０Ｅを参照する。さらに図９Ｇに示すように、データディスク０のキュー９２０Ａは空である。データディスク１のための書き込み可能なバッファのリスト９２０Ｂには、ファイル９４２のバッファＦ２−３からＦ２−７がある。データディスク２のリスト９２０Ｃは、ファイル９４２の残りのダーティバッファＦ２−１１からＦ２−１５がある。データディスク３のリスト９２０Ｄにはファイル９４４のダーティバッファＦ３−２からＦ３−３がある。
ダーティバッファＦ４−０からＦ４−１を備えた第４のファイル９４６は、図５に示すアルゴリズムを用いてディスクスペースの割り当てがなされる。ステップ５１０において、ファイル９４６のダーティバッファＦ４−０は、スペース割り当てアルゴリズムにわたされる。判断ブロック５２０において、バッファＦ４−０は前回のバッファ（Ｆ３−３）から異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。ここではバッファＦ４−０は異なったファイルにあるので、判断ブロック５２０の結果は真（yes）となる。ステップ５３０において、ディスクスペース９１０における最も低いカレント書き込み位置がどこにあるかの判断がなされる。図９Ｇに示すように、最も低いカレント書き込み位置は、データディスク０のブロック９５６Ｄを参照する、カレント書き込み位置９３０Ａであることがわかる。したがって、ステップ５３０において、データディスク０が書き込み用に選択される。ステップ５４０において、データディスク０のバッファＦ４−０に前回割り当てられたブロックは、フリーにされる。ステップ５５０において、ブロック９５８Ｂは、データディスク０に割り当てられる。これによりデータディスク０のカレント書き込み位置９３０Ａは、ブロック９５６Ｂから９５８Ｂへ進められる。これは図９Ｈにおいて、ブロック９５８Ｂの左下コーナにおける実線で示されている。ステップ５６０において、ブロック９５８Ｂは、バッファＦ４−０に割り当て指定される。ステップ５７０において、バッファＦ４−０は、データディスク０のための書き込み可能なバッファのリスト９２０Ａに加えられる。ステップ５８０において、バッファＦ４−０、Ｆ２−１１、Ｆ３−２で構成されるストライプ９８６は、ディスクに書き込まれ、これはバッファはキュー９２０Ａ、９２０Ｃ〜９２０Ｄから削除される。ステップ５９０において続いて呼び出しアルゴリズムが実行される。
図９Ｉを参照すると、ファイル９４６のダーティブロック４Ｆ−１は、ステップ５１０においてスペース割り当てアルゴリズムにわたされる。判断ブロック５２０において、今回のバッファは前回のバッファから異なったファイルにあるか否か、または前回のバッファとは異なった先読みチャンクにあるか否かが判断される。判断ブロック５２０の結果は偽（no）であるので、続いてステップ５４０が実行される。ステップ５４０で前回に割り当てられたブロックがフリーにされる。ステップ５５０においてデータディスク０のブロック９６０Ｂが割り当てられる。これにより、データディスクのカレント書き込み位置９３０Ａは、ブロック９５８Ｂから９６０Ｂへ進められる。ステップ５６０において、割り当てられたブロック９６０Ｂは、バッファＦ４−１に当てられる。ステップ５７０において、ファイル９４６のバッファＦ４−１は、データディスク０のための書き込み可能なバッファのリスト９２０Ａに加えられる。ステップ５８０において、ストライプ９８８がディスクに書き込まれる。これは、ストライプ９８８に、最も低いカレント書き込み位置９３０Ａを含むブロック９６０Ａ〜９６０Ｅが含まれるからである。バッファＦ４−１、Ｆ２−３、Ｆ２−１２、Ｆ３−３は、それぞれリスト９２０Λ〜９２０Ｄから削除される。ステップ５９０において続いて呼び出しアルゴリズムが実行される。
図９Ｉに示すように、データディスク０〜３のカレント書き込み位置９３０Ａ〜９３０Ｄは、ブロック９６０Ｂ、９７０Ｃ、９６８Ｄ、９６０Ｅを参照する。最も低い位置にあるカレント書き込み位置９３０Ａより、さらに低い位置に割り当てられたブロックは、図９Ｉに示すようにディスクに書き出される。しかしながら、データディスク１、２のリスト９２０Ｂ、９２０Ｃに加えられたファイル９４２のダーティバッファＦ２−４からＦ２−７、およびＦ２−１３からＦ２−１５は、ディスクには書き出されない。
図９Ｊは、すべてのダーティｉノードにブロック割り当てがなされた後、残された未書き込みのバッファ、すなわちファイル９４４のバッファＦ２−４からＦ２−７、およびＦ２−１３からＦ２−１５のディスクへの書き出しを示す。この例においては、すべてのデータディスク０〜３のカレント書き込み位置９３０Ａ〜９３０Ｄは、図９Ｉの最も高いカレント書き込み位置９３０Ｂにまで進められている。したがってキュー９２０Ａ〜９２０Ｄは空にされる。カレント書き込み位置９３０Ｂは、データディスク１のブロック９７０Ｃを参照する。この動作は、図３のステップ３５０が実行されることにより、すべての未書き込みのストライプがディスクに書き出される。ステップ３５０において、カレント書き込み位置９３０Ａ〜９３０Ｄをグループの内で最も大きな値を有するものに進めることにより、ディスクにまだ書き込まれていないバッファであってデータディスク０〜３のキュー９２０Ａ〜９２０Ｄにあるすべてのバッファは、強制的にディスクに書き込まれる。
上述したごとく、本発明はＲＡＩＤアレイのディスクレイアウトの手順を用いながら、ＲＡＩＤアレイへの書き込みのための割り当てを最適なものにするものである。ＲＡＩＤレイアウトの手順には、ディスクに書き込まれるべきバッファのディスクブロックや、ストライプに関する情報が含まれる。これは図９Ａ〜９Ｊに示されている。本発明は、ＲＡＩＤアレイ技術を有するファイルシステムを、より完全なものにするものである。ＲＡＩＤ層は、ＲＡＩＤサブシステムにおけるデータブロックの配列に関する、より詳しい情報をファイルシステムに送るものである。ファイルシステムはこの情報を審査し、それらがＲＡＩＤシステムに書き込まれるのに従い、ブロックの位置を最適なものにするのに用いられる。ＲＡＩＤシステムへの書き込みの最適化は先読みチャンクをより良いものにすると共に、ストライプ全体を書き込むことにより達成される。
ストライプの負荷感知式書き込み
上述したＷＡＦＬファイルシステムのためのＲＡＩＤアレイに対して書き込みのために割り当てる方法は、“循環書き込み”アルゴリズムを用いたものである。この方法は、ディスクを循環してバッファをＲＡＩＤアレイに書き込むもので、１本のストライプのすべてのディスクブロックに割り当てが行なわれるものである。ストライプへの順次書き込みは、少なくとも１つのブロックがフリーにされなければならないという点を除いて、ストライプにおいて割り当てられるフリーブロックの数に依存するものではない。このようにして、ストライプでの書き込みのための割り当ては、ＲＡＩＤアレイにおけるディスクの最後まで進められる。ディスクの最後に達すれば、書き込みのための割り当ては、ディスクの始めに戻り、そこから続けられる。
本発明の別の実施の形態においては、ディスクへのデータ書き込みへの速さが、通常のしきい値を越えれば、“負荷感知式書き込み”により、ディスクへの書き込みが行なわれるものである。データ書き込みの速さが通常のしきい値を越えれば、本発明では、ディスクの書き込みをストライプの書き込みの効率に依存するように、ディスク書き込みの処理を行う。ＲＡＩＤアレイにおける各ディスクのエリアに割り当てられたブロックのパターンによって、ディスクのある部分については、他の部分より、より容易に書き込みがなされることがある。たとえば、データディスク上のストライプに割り当てられたブロックがない場合は、ＲＡＩＤアレイにストライプを書き込むことは非常に効率的である。
図９Ｅに示すように、ストライプ９８０に対し４つのディスクブロック９５２Ｂ〜９５２Ｅを書き込むことは、ＲＡＩＤアレイおいて最も効率よく書き込みが行なわれる。具体例においては、４つのバッファＦ１−０、Ｆ２−０、Ｆ２−８、Ｆ３−０は、実質的に同じ時間ＴWRITEにディスクに書き込みが行なわれる。したがって、４ＫＢバッファを用いることにより、所定の時間ＴWRITEに１６ＫＢのデータをディスクに書き込むことが可能である。これは、図９Ｆで示すＲＡＩＤアレイの３つのブロック９５４Ｃ〜９５４Ｅに、バッファＦ２−１、Ｆ２−９、Ｆ３−１を備えたストライプ９８２を書き込むことと対照的である。この場合の書き込み速さは、所定時間ＴWRITEに１２ＫＢのデータを書き込むことができる。したがってストライプ９８２の書き込み速さは、ストライプ９８０の最大書き込み速さの７５％である。最悪の場合、ＲＡＩＤアレイのストライプには、単一の割り当てられていないディスクブロックのみが存在するだけである。この単一ブロックへの書き込みは、４つのディスクブロックに書き込む最大速さの２５％で書き込みをなすことが可能である。したがって、１つのフリーブロックのみでストライプに書き込みを行うことは非効率的である。
循環書き込みを行う負荷感知式書き込みにおいては、ＲＡＩＤサブシステムがビジーであれば、非効率的なストライプはスキップされる。すなわち、多くの書き込まれるべきフリーブロックを有するストライプが、割り当てのために選択される。システムの負荷が軽い場合にのみ非効率的なストライプの書き込みが許される。これは、システムの負荷が重たい場合に、より多くの効率のよいストライプを残しておくために行なわれるものである。したがって、同じシーケンスにおいて、ブロックとダーティファイルの特定のセットを書き込む循環式書き込み方法とは異なり、負荷感知式循環書き込み方法は、負荷の重さによってその動作を変えるものである。たとえば、５メガバイト／秒の最大書き込み速さを有するＲＡＩＤシステムにおいては、本発明においては、１０秒のインターバルに１秒当たり２．５メガバイトの平均速さで書き込みを行なうシステムであれば、３または４個のフリーブロックを有するストライプを書き込む。
本発明においては、ＲＡＩＤディスクシステムを備えたファイルシステムを、より効率よく動作させるためには、上述の負荷感知式循環書き込み方法により大きな規模のアルゴリズムを加えることも可能である。以上詳述したごとく、ＲＡＩＤアレイのレイアウトに関する情報を、ファイルシステムに与えることは、この利点を受ける規模の大きなアルゴリズムも可能とするものである。
以上のように、ＲＡＩＤアレイを用いたファイルシステムにおいてファイルを割り当てる方法が説明された。
【図１】
0003862274.tif 000002
【図２】
0003862274.tif 000003
【図３】
0003862274.tif 000004
【図４】
0003862274.tif 000005
【図５】
0003862274.tif 000006
【図６】
0003862274.tif 000007
【図７】
0003862274.tif 000008
【図８】
0003862274.tif 000009
【図９Ａ】
0003862274.tif 000010
【図９Ｂ】
0003862274.tif 000011
【図９Ｃ】
0003862274.tif 000012
【図９Ｄ】
0003862274.tif 000013
【図９Ｅ】
0003862274.tif 000014
【図９Ｆ】
0003862274.tif 000015
【図９Ｇ】
0003862274.tif 000016
【図９Ｈ】
0003862274.tif 000017
【図９Ｉ】
0003862274.tif 000018
【図９Ｊ】
0003862274.tif 000019
【図１０】
0003862274.tif 000020