(57)【特許請求の範囲】
【請求項１】
ディレクトリに設定されたディレクトリシード情報を記憶する記憶部と、
前記ディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成するデータ生成部と、を備え、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
ストレージシステム。
【請求項２】
請求項１に記載のストレージシステムであって、
前記データ生成部は、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリに設定されるサブディレクトリシード情報を生成し、
前記サブディレクトリシード情報と、前記サブディレクトリ内のデータのエントリ番号と、に基づいて、当該サブディレクトリ内のデータであるファイルあるいはディレクトリを生成する、
ストレージシステム。
【請求項３】
請求項２に記載のストレージシステムであって、
前記データ生成部は、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリが最後に再作成された世代を表す再作成世代番号と、当該サブディレクトリが最後に更新された世代を表す更新世代番号と、を生成し、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記再作成世代番号と、前記更新世代番号と、に基づいて、前記サブディレクトリのデータを生成する、
ストレージシステム。
【請求項４】
請求項３に記載のストレージシステムであって、
前記記憶部は、世代の変化に伴う前記サブディレクトリ内のデータ数の変化を表すデータ数情報を記憶し、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記データ数情報と、に基づいて、前記再作成世代番号と前記更新世代番号とを生成する、
ストレージシステム。
【請求項５】
請求項４に記載のストレージシステムであって、
前記データ生成部は、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記再作成世代番号と、に基づいて、前記サブディレクトリの作成時に設定されるデータを生成し、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記更新世代番号と、に基づいて、前記サブディレクトリの更新時に設定されるデータを生成する、
ストレージシステム。
【請求項６】
請求項５に記載のストレージシステムであって、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記更新世代番号と、に基づいて、前記サブディレクトリシード情報を生成する、
ストレージシステム。
【請求項７】
請求項１乃至６のいずれかに記載のストレージシステムであって、
前記記憶部は、前記ディレクトリ内のデータをグループ分けしたグループ毎に、世代の変化におけるグループ内のデータ数の変化を表す情報を含むグループ情報を記憶しており、
前記データ生成部は、前記グループ情報と、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、前記サブディレクトリが属するグループを特定して、当該特定したグループの前記グループ情報を用いて、前記サブディレクトリのデータを生成する、
ストレージシステム。
【請求項８】
請求項１乃至７のいずれかに記載のストレージシステムであって、
前記記憶部は、前記ディレクトリの世代を表す世代番号を記憶すると共に、世代の変化に伴う前記サブディレクトリ内のデータ数の変化を表すデータ数情報を記憶しており、
前記データ生成部は、前記世代番号と、前記データ数情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリが存在するか否かを判定し、当該サブディレクトリが存在すると判定した場合に当該サブディレクトリのデータを生成する、
ストレージシステム。
【請求項９】
ストレージ装置に、
記憶部に記憶されているディレクトリに設定されたディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成するデータ生成部を実現させるプログラムであり、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
プログラム。
【請求項１０】
ストレージシステムが、記憶部に記憶されているディレクトリに設定されたディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成する際に、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
データ生成方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ストレージシステムにかかり、特に、仮想ファイルシステムを備えたストレージシステムに関する。
【背景技術】
【０００２】
ストレージシステムの高性能／高機能化に伴い、その評価手法が問題となっている。例えば、バックアップソフトウェアを用いて、稼働中のユーザシステムのデータのバックアップを行う場合、予めバックアップ時間やデータフローの傾向などを確認するために擬似データを用いて実際にバックアップを行い、評価することを考える。この場合、あらかじめユーザシステムを想定した擬似データ（テストデータ）を用意しておく必要があるが、ファイルやディレクトリ数、データ容量が多くなると、これらのテストデータを準備することに長大な時間がかかる、という問題が生じる。また、テストデータを格納するための高性能／大容量のストレージを準備する必要がある、という問題も生じる。
【０００３】
ここで、特許文献１では、ファイルの作成、削除等が行うことができ、データ保存用のストレージを必要としない評価用のファイルシステムを提供している。具体的に、特許文献１では、ファイルの実際のデータをストレージに格納せず、データを再現するときに必要なファイルの種だけをファイルのデータの代わりに保存している。このため、ファイルを作成する際には、ファイルの種のみを作成し、ファイルを読み込む際には、ファイルの種から計算してデータを再現している。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特許第５６６４３１８号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
しかしながら、上記特許文献１の技術では、ディレクトリ情報については、全てを記憶領域に記憶している。このため、ユーザストレージが非常に複雑なディレクトリ構造と膨大な数のファイルを記憶している場合、それを格納する領域が肥大化し、作成時間もファイル数に比例して大きくなるという問題が生じる。
【０００６】
また、ユーザシステムのデータを日次や週次バックアップしていく評価を行う場合、ユーザシステムの運用により更新されるデータ内容を考慮して、テストデータを更新して行く必要がある。すると、多数のファイル／ディレクトリ構造を保つシステムでは、上記特許文献１の技術を利用しても、更新に時間がかかってしまう。
【０００７】
また、リストアの評価を行う場合、最後にバックアップ元とデータに違いがないか比較を行うために、リストア先をバックアップ元とは別の場所にリストアする必要がある。このため、元のテストデータとリストア毎のテストデータ両方を格納できる大容量ストレージを用意する必要が生じる。
【０００８】
このように、上述した特許文献１の仮装ファイルシステムでは、階層化されたディレクトリ構造や多くのファイルを有するファイルシステムでは、必要となる記憶領域が増大し、処理時間も長くなる、という問題が生じる。
【０００９】
このため、本発明の目的は、上述した課題である、必要となる記憶領域が増大し、処理時間も長くなる、ということを解決することができるストレージシステムを提供することにある。
【課題を解決するための手段】
【００１０】
本発明の一形態であるストレージシステムは、
ディレクトリに設定されたディレクトリシード情報を記憶する記憶部と、
前記ディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成するデータ生成部と、を備え、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
という構成をとる。
【００１１】
また、本発明の一形態であるプログラムは、
ストレージ装置に、
記憶部に記憶されているディレクトリに設定されたディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成するデータ生成部を実現させるプログラムであり、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
という構成をとる。
【００１２】
また、本発明の一形態であるデータ生成方法は、
記憶部に記憶されているディレクトリに設定されたディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成する際に、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
という構成をとる。
【発明の効果】
【００１３】
本発明は、以上のように構成されることにより、仮想ファイル用の記憶領域の容量を低減し、処理時間の短縮を図ることができる。
【図面の簡単な説明】
【００１４】
【図１】本発明の実施形態１におけるストレージシステムの構成を示すブロック図である。
【図２】図１に開示したストレージシステムが記憶する仮想ディレクトリ情報の一例を示す図である。
【図３】図１に開示したストレージシステムにおけるデータ生成時の様子を説明するための図である。
【図４】図１に開示したストレージシステムにおけるデータ生成時の様子を説明するための図である。
【図５】図１に開示したストレージシステムにおけるデータ生成時の動作を示すフローチャートである。
【図６】本発明の実施形態２におけるストレージシステムの構成を示すブロック図である。
【発明を実施するための形態】
【００１５】
［実施形態１］
本発明の第１の実施形態を、図１乃至図５を参照して説明する。図１乃至図２は、ストレージシステムの構成を説明するための図である。図３乃至図５は、ストレージシステムにおいてデータを生成するときの様子を説明するための図である。
【００１６】
本実施形態におけるストレージシステムは、演算装置と記憶装置とを備えており、図１に示すように、演算装置がプログラムを実行することで構築された仮想ファイルシステム１０（データ生成部）を備えている。また、ストレージシステムは、記憶装置に形成された仮想ディレクトリ情報記憶部１３（記憶部）を備えており、仮想ファイルシステム１０で仮想ディレクトリ１１や仮想ファイル１２といったデータを生成するために用いる仮想ディレクトリ情報を記憶している。
【００１７】
また、ストレージシステムは、演算装置がプログラムを実行することで構築された、バックアップソフトウェア２０、仮想ディレクトリ作成ソフトウェア３０を備えている。さらに、ストレージシステムは、記憶装置に形成された、通常ディレクトリ構造記憶部１４、差分情報記憶部１５、評価対象ストレージ２１を備えている。
【００１８】
以下、ストレージシステムの構成を詳述する。まず、ストレージシステムは、ファイルのデータや複雑なディレクトリ構造を表すディレクトリ情報のデータを実ストレージ上に保持すること無く、仮想ファイルシステム１０にて、一定のルールに基づいてディレクトリ構造とファイルを再現する。このとき、仮想ファイルシステム１０は、ディレクトリやファイルへのアクセス時に、予め記憶された仮想ディレクトリ情報を用いて、かかる情報に基づく乱数からディレクトリ構造やファイルを瞬時に再現する。
【００１９】
なお、ストレージシステムは、仮想ディレクトリでない通常のディレクトリについては、その構造を記憶領域に保存している。ただし、仮想ディレクトリとしてマークされたディレクトリについては、そのサブディレクトリやファイルを含む全ての構造を記憶領域には保存せず、後述するように、「仮想ディレクトリ情報」のみを記憶している。つまり、ストレージシステムは、仮想ディレクトリ上のディレクトリ構造やファイルデータの内容を直接記憶領域に保存せず、それぞれ以下のように最低限の情報である仮想ディレクトリ情報を保存している。
【００２０】
そして、バックアップソフトウェアがアクセスに来た時など必要になった時、計算によって必要な情報を生成する。これらのディレクトリ構造やファイルのデータは完全にランダムで生成されるわけではなく、再現性のあるルールに従って生成される。なお、仮想ディレクトリ自身のi-node情報（作成日時や属性など）は、通常のディレクトリと同様に、親のディレクトリエントリに保存されている。ここでは、説明を簡素にするため、「i-node」はディレクトリエントリに含まれていることとする。但し、i-node情報は、ディレクトリエントリとは別に保存されていてもよい。
【００２１】
＜ディレクトリエントリの計算＞
次に、ストレージシステムの仮想ファイルシステム１０によるデータ生成の処理を説明する。
【００２２】
まず、仮想ディレクトリ情報記憶部１３には、図２に示すように、仮想ディレクトリや仮想ファイルを生成するための仮想ディレクトリ情報として、以下の情報が記憶されている。
【００２３】
「仮想ディレクトリが保存する情報」
・ディレクトリシード： 内容を乱数で作成するために使用するシード値（ディレクトリシード情報）
・世代番号：何世代目かを示す値（０＝最初の世代）
・グループ情報：ディレクトリ内に含まれるファイルやサブディレクトリを表す情報。後述の「ファイルグループ情報」または「サブディレクトリグループ情報」を複数保持できる。
【００２４】
「ファイルグループ情報」
・初期ファイル数：このグループのファイルの個数
・ファイルサイズの範囲：このグループのファイルサイズの範囲
・増加数：差分世代毎に作成される新しいファイルの数
・削除数：差分世代毎に削除されるファイルの数
・変更数：差分世代毎に変更されるファイルの数
【００２５】
「サブディレクトリグループ情報」
・初期サブディレクトリ数：このグループのサブディレクトリの数
・増加数：差分世代ごとに作成される新しいサブディレクトリの数
・削除数：差分世代ごとに削除されるサブディレクトリの数
・変更数：差分世代ごとに更新されるサブディレクトリの数
・グループ情報（複数）：サブディレクトリ内に含まれるファイルやサブディレクトリを表す情報。
【００２６】
このように、仮想ディレクトリ情報は、まず、ディレクトリに設定されたディレクトリシード（ディレクトリシード情報）と、そのディレクトリの世代を表す世代番号と、を含む。また、仮想ディレクトリ情報は、そのディレクトリ内のデータの情報として、当該データをグループ分けしたグループ毎に、世代の変化におけるグループ内のデータ数の変化を表す情報（データ数情報）を記憶している。
【００２７】
そして、仮想ファイルシステム１０は、ファイルシステムにアクセスがあった時に、上記仮想ディレクトリ情報を用いて、ディレクトリ構造内のそれぞれのディレクトリエントリ（簡便性のため、ファイルやディレクトリの名前だけでなく、属性や作成日付などの所謂i-node情報も含めて考える）を、以下の手順に従って作成する。このとき、ディレクトリエントリの作成のキーとして、ディレクトリ内のアクセスされたディレクトリやファイルのエントリ番号を指定する。
【００２８】
まず、エントリ番号がその仮想ディレクトリに存在する番号かを調べるため、仮想ディレクトリ内のエントリ数を計算する。エントリ数は、仮想ディレクトリ上のグループ上のエントリ（ファイルまたはサブディレクトリ）数の合計値となる。
以下の計算式で各世代でのエントリ数が求まる。
エントリ数＝初期エントリ数＋世代番号×（増加数−削除数）
【００２９】
ただし、「初期エントリ数」は各グループの初期エントリ数の合計値、「増加数」は各グループの増加数の合計値、「削除数」は各グループの削除数の合計値である。これは世代が進むに連れて各グループでエントリが削除／増加する分を計算している。求まったエントリ数よりエントリ番号が小さければ存在するエントリとなる。
【００３０】
また、以下の式で、エントリを最初に作成した世代（初期作成世代）が求まる。
初期作成世代番号＝エントリ番号−初期エントリ数÷（増加数−削除数）
（小数点以下切り上げ。ただし、エントリ番号＜初期エントリ数の場合は0とする）
【００３１】
次に、指定されたエントリ番号のディレクトリエントリが、どのグループ（仮想ディレクトリに保存されているグループ情報）に属するかを決定する。初期作成世代番号が0の場合、各グループの初期エントリ数の割合、0以外の場合は、各グループの（増加数−削除数）の割合から、乱数で属するグループが決まる。乱数は「ディレクトリシード」と「エントリ番号」を組み合わせて初期化した乱数アルゴリズムを使用して計算する。その世代で作成された各グループのファイル数から、エントリが各グループに所属する確率が固定的に決まるため、乱数から確率に従ってグループを決定する。なお、グループが1つしか存在しない場合は自明であるため上記の判定は省略できる。
【００３２】
次に、エントリの「再作成世代番号」、エントリの「更新世代番号」、エントリの「更新回数」を計算する。エントリの「再作成世代番号」は、当該ディレクトリエントリが最初に作られてから世代を重ねる間に削除及び再作成される中、最後に再作成された世代を示す値である。エントリの「更新世代番号」は、当該ディレクトリが最後に更新または再作成された世代を示す値である。エントリの「更新回数」は、エントリが最後に再作成されてから、何回更新されたかを示す値である。
【００３３】
「ディレクトリシード」と「エントリ番号」を乱数シードとして擬似乱数アルゴリズムを初期化し、ループして以下を計算する。確率で処理を決める箇所、乱数を用いる箇所は、共にこの擬似乱数を用いる。また、ループ変数とは、初期作成世代番号＋１から始まって、現在の世代番号まで、繰り返すたびに１ずつ加算されていく変数である。
【００３４】
・エントリの再作成世代番号：初期値はエントリの初期作成世代番号。１世代毎に「グループの削除数／グループのエントリ数」の確率で、ループ変数を設定する。
・エントリの更新世代番号：初期値はエントリの初期作成世代番号。１世代毎に「グループの変更数／グループのエントリ数」の確率で、ループ変数を設定する。ただし、上記の再作成世代番号が更新された時にもループ変数を設定する。
・エントリの更新回数：初期値は０。１世代毎に、再作成世代番号が変更されると０を設定、更新世代番号が変更されると、＋１する。
なお、ここでの「グループのエントリ数」は、各ループ変数の世代番号でのグループのエントリ数であり、初期のエントリ数＋世代番号×（増加数−減少数）で計算できる。
【００３５】
最後に、ディレクトリエントリの各情報を作成していく。このとき、エントリが作成される時に更新されるもの、エントリが変更される時に変更されるものの２種類の情報が存在するため、別々に作成する。
【００３６】
「エントリが作成されるときに設定される情報」
これにはファイル名や作成日時、パーミッション／ACL／拡張属性などディレクトリエントリの多くの情報が該当する。これらの情報は、擬似乱数アルゴリズムを「ディレクトリシード」、「エントリ番号」、エントリの「再作成世代番号」を用いて初期化して、乱数で決定する。
・エントリ名（ファイル名／ディレクトリ名）
以下の2つのパートから構成され、これらを連結した名前となる。
乱数部：乱数で文字列長を決定し、乱数で文字を選択して埋める。
番号部：エントリ番号を埋め込む。
・作成日時
作成日時はその特性にあわせ、世代を経る毎に昇順に増加している必要がある。
基準となる日付（仮想ディレクトリの作成日付）にエントリの作成世代分の日数を加算し、時刻は乱数で決定する。
・ファイルパーミッション／ACL／拡張属性など
乱数で決定する（いつくかのパターンから選択するなど）。
【００３７】
「エントリが更新されるときに設定される情報」
これにはエントリのシード（ファイルやサブディレクトリの内容を作成するために用いるシード値）や更新日時が該当する。擬似乱数アルゴリズムを「ディレクトリシード」、「エントリ番号」、エントリの「更新世代」を用いて初期化して、乱数で決定する。
・エントリのシード
乱数をそのまま使用する。
・更新日時
更新日時はその特性にあわせ、世代を経る毎に昇順に増加している必要がある。
基準となる日付(仮想ディレクトリの作成日付)にエントリの更新世代分の日数を加算し、時刻は乱数で決定する。
・ファイルサイズ（ファイルの場合）
当該ファイルが所属するファイルグループ情報のファイルサイズの範囲を元に、乱数でファイルサイズを決定する。
【００３８】
上記の一連の処理で、ディレクトリエントリの情報が生成できる。エントリの中身（ファイルのデータや、サブディレクトリ内のディレクトリ構造）は、以下のように作成する。
・ファイルの場合：生成したエントリのシードを「ファイルシード」として用いて、後述のファイルの読み込みで説明する手法で、乱数でデータを生成する（もしくは、既存技術と同様の手法でも良い）。
・サブディレクトリの場合：生成したエントリのシードを、仮想ディレクトリの「シード」として扱い、エントリの更新回数を、仮想ディレクトリの「世代番号」として扱う。当該サブディレクトリの仮想ディレクトリとしてのグループ情報は、親のディレクトリの当該サブディレクトリの所属するグループ情報内に保存しているグループ情報を用いる。当該サブディレクトリ以下のディレクトリエントリを計算する場合、上記の仮想ディレクトリ情報を用いて再帰的に処理する。また、計算したディレクトリエントリ情報を主記憶内にキャッシュとして一時的に保存することで、当該サブディレクトリ内の複数のディレクトリエントリの計算する場合、計算処理を高速化できる。
【００３９】
＜ディレクトリの読み込み／エントリの検索＞
上記のディレクトリエントリの情報の生成処理は、実際のファイルシステムの操作としては、READDIR（ディレクトリエントリの順次の見込み）、LOOKUP（エントリの検索）の２つで実行される。READDIRは、ディレクトリ内容の一覧を取得する場合に実施される操作で、ディレクトリの内容を先頭から順次読み取っていく操作である。LOOKUPは、ファイル名（ディレクトリ名）でディレクトリエントリを検索する操作である。特に後者のLOOKUPは、オープンやリネームなど、エントリに対する各種操作で間接的にも実施され、性能に注意する必要がある。
【００４０】
READDIRの場合、生成処理に与えるエントリ番号は１からエントリ数まで順次計算する。
LOOKUPの場合、エントリ番号はエントリ名から以下のように計算する。エントリ名は前述の通り、乱数部、番号部、から構成されており、番号部からエントリ番号を取り出すことができる。エントリ番号からエントリ名生成時と同じアルゴリズムで乱数部を生成して、実際の乱数部と比較し、異なる場合はエントリが存在しないとする。等しい場合は、エントリ名は正しいものとして、当該エントリ番号でエントリ情報を計算する。こうすることで、実際には存在しないはずの適当なエントリ名で検索されても、正しく存在しないとしてエラーにできる。
【００４１】
＜スナップショットの作成＞
一部のファイルシステムは、スナップショットの作成機能を持つ。これらはバックアップソフトウェアで、その瞬間の正確なファイルシステムのイメージをバックアップするために広く利用されている。本技術の仮想ファイルシステムではスナップショット作成の操作で、ディレクトリ構造上の仮想ディレクトリの世代番号を1進める処理を行う。
【００４２】
＜仮想ディレクトリの情報の設定／取得＞
仮想ディレクトリのシードやグループ情報は外部から与える必要があるが、代替ストリームや拡張属性を用いることとする。
多くのファイルシステムではファイル／ディレクトリには実際のデータ（ファイルの内容／ディレクトリ内のエントリ）以外に、代替ストリームや、拡張属性といった別の副次的なデータを持たせることができる。これらはOSの標準的なインターフェイスが提供されており、容易に利用できる。ディレクトリ作成時にこれらの方法で情報を埋め込むことができる。
【００４３】
本技術では、仮想ディレクトリ作成ソフトウェアが仮想ディレクトリ情報を設定するインターフェイスを提供する。当該ソフトウェアは上記の代替ストリーム／拡張属性を通してファイルシステムと仮想ディレクトリ情報をやりとりすることとする。
【００４４】
＜ファイルの読み込み＞
ファイルのデータを読み込む場合、ファイルのシード（ディレクトリエントリの生成時に計算される）を元に、乱数でデータを生成する。ランダムアクセスに対応するため、ファイルはブロックごとに分けて乱数を計算することとする。読み込みたいデータのオフセットから、ブロック番号を検索し（オフセットをブロックサイズで割って、小数点以下を切り捨てる）、ファイルシードと組み合わせて擬似乱数アルゴリズムを初期化して乱数を計算する。計算したブロックから実際に必要なデータを抜き出して用いる。読み込みたいデータが複数ブロックにまたがっている場合は、それらのブロックを全て計算する。
【００４５】
＜リストアの処理（ファイル作成/ディレクトリ作成）＞
リストア処理によってデータが仮想ファイルシステムに書き込まれるとき、そのデータがバックアップ元と等しいかを確認する。フルバックアップイメージをリストアする場合、単純にディレクトリ構造が仮想ファイルシステムに書き込まれる。差分バックアップのリストアをする場合、直前のフルバックアップイメージをリストアした後、差分を適用していく動作となる。
【００４６】
フルバックアップのリストアの場合は、以下のように容易に整合性を確認できる。ファイルのリストアの場合は、書き込まれるデータが、ファイルオープン時に計算したディレクトリエントリ情報のシードから計算されるデータと等しいか確認する。ディレクトリのリストアの場合は、書き込まれる仮想ディレクトリ情報が、エントリ名から計算されたディレクトリエントリ情報の仮想ディレクトリ情報と等しいか確認する。これらの処理で差異が認められると、差分情報を記憶しておき、別途確認できるようにする。
【００４７】
差分バックアップのデータをリストアする場合、まずその差分バックアップより昔の最も新しいフルバックアップイメージがまずリストアされ、その後各世代の差分が適用されていく。バックアップソフトウェアが代替ストリームや拡張属性をリストアするとき、対象のディレクトリエントリが仮想ディレクトリの場合、仮想ディレクトリ情報が設定される。このため、最初のフルバックアップイメージがリストアされるとき、バックアップされた時点の世代番号が仮想ディレクトリに設定され、その世代のデータとリストアデータに相違がないかが前述のようにチェックされる。
【００４８】
次に差分バックアップの情報がリストアされる際、その差分バックアップの世代番号が仮想ディレクトリに設定されることとなる。よって、仮想ディレクトリ内のデータは新しい（差分バックアップの）世代のデータで更新され、そのデータとリストアデータの整合性が確認されることとなる。これを繰り返すことで、最新の差分バックアップイメージまで順次世代番号が進みながら仮想ディレクトリへの書き込みが行われることとなり、正しくリストア処理の確認が行える。
【００４９】
［実施例］
次に、上述したストレージシステムによるデータ生成の一例を説明する。ここでは、図２に示す仮想ディレクトリ情報が記憶されていることとする。そして、ルートディレクトリ「(root)」は通常のディレクトリとして存在し、そのサブディレクトリとして、「dirA」が存在している。dirAは、仮想ディレクトリとしてマークされており、図２で示される情報を保持している。
【００５０】
図２に示すように、仮想ディレクトリdirAのディレクトシードは「12345」、世代番号は「10」であり、３つのグループ情報（サブディレクトリグループ１つ「A1」、ファイルグループ２つ「A2」、「A3」）を持っている。
【００５１】
そして、サブディレクトリグループＡ１は、図２に示されている情報（初期サブディレクトリ数／増加数／削除数／変更数）と、グループ情報を１つ（ファイルグループB1）を持っている。それぞれのファイルグループ（A2,A3,B1）は、図２に示されている情報を持っている。
【００５２】
＜ディレクトリエントリの検索＞
図２の構成で、「/dirA/ztwgu_11850/g4tapq_10」というパスのファイルが存在しているとして、それにアクセスする場合、つまり、「g4tapq_10」というファイルのパスを指定して、当該ファイルのディレクトリエントリを計算する場合の動作を説明する（図５のステップＳ１）。この場合のディレクトリ構造のイメージは図3のようになる。
【００５３】
まず、ルートディレクトリのdirAというディレクトリにアクセスする。ここでルートディレクトリは通常のディレクトリであるので、通常のファイルシステムと同様にディレクトリエントリを検索し、dirAというエントリを見つける。dirAは仮想ディレクトリであり、仮想ディレクトリ情報を持っているため、dirA以下のディレクトリ構造はこの情報から計算される（図５のステップＳ２）。
【００５４】
次に、「ztwgu_11850」というディレクトリエントリを以下のように計算していく。まず、ディレクトリエントリ名「ztwgu_11850」から、当該ディレクトリエントリのエントリ番号は「11850」と判断する。仮想ディレクトリdirAの世代番号は「10」であるため、dirAディレクトリのエントリ総数は、dirAの3つのグループの情報（A1,A2,A3）から、「初期エントリ数(1000+10000+300)＋世代数(10)×(増加数(50+1000+30)−削除数(30+500+10)」で計算でき、「11300+10*(1080-540)=16700」となる。「ztwgu_11850」のエントリ番号「11850」は、dirAのエントリ数「16700」より小さいため、このエントリ番号は有効であると判断する（図５のステップＳ３）。
【００５５】
次に、このディレクトリの属するグループを判定する（図５のステップＳ４）。エントリの初期作成世代番号は、「((エントリ番号(11850)−初期エントリ数(11300))÷(増加数(1080)-削除数(540))=1.018…」となり、切り上げて「2」である。ディレクトリシード「12345」と、エントリ番号「11850」を組み合わせ、擬似乱数アルゴリズムを初期化して、0以上１未満の乱数値を計算し、0.025746を得たとする。この世代(2)で作成された各グループのエントリ数（増加数−削除数）の割合は、A1:A2:A3=20:500:20であり、0.037…：0.925…：0.037…となる。このため、乱数値が0〜0.037…ならA1に所属、0.037…〜0.962…(0.037＋0.925…)ならA2、.0.962〜1であれば、A3に所属と判定する。乱数値は0.025746のためサブディレクトリグループA1に所属していると判定する。
【００５６】
次に、エントリの「再作成世代番号」、エントリの「更新世代番号」、エントリの「更新回数」を以下のようにループで計算する（図５のステップＳ５）。擬似乱数は、ディレクトリシード「12345」とエントリ番号「11850」で初期化しておく。再作成世代番号、更新世代番号共に、初期作成世代番号(2)で初期化し、更新回数は0で初期化しておく。初期作成世代番号+1(3)をループ変数に設定し、ループ処理の一回目を始める。ループ変数の世代(3)でのサブディレクトリグループA1のエントリ数は、初期サブディレクトリ数(1000)＋世代番号(3)×(増加数(50)−削除数(30))＝1060である。エントリの再作成世代番号が変更される確率は(グループA1の削除数(30)÷グループA1のエントリ数1060)＝0.0283…であり、計算した乱数(0.5432とする)はこの値より大きいため、変更しない。エントリの更新世代番号が更新される確率は、グループA1の変更数(100)÷エントリ数(1060)＝0.094であり、計算した乱数(0.08120とする)はこの値以下のため、エントリの更新世代番号をループ変数(3)の値に変更する。更新世代番号が変わったため、エントリの更新回数を+1して1とする。ループ変数を1増加し、世代番号(10)以下であるため、ループして処理を進める。
【００５７】
ループ変数が6のときに乱数と確率によってエントリの再作成世代番号が変更され、その値がループ変数の6となり、エントリの更新世代番号も6に設定され、エントリの更新回数は0となる。世代番号(10)まで進む間に、「再作成世代」は(6)、「更新世代」は(9)、「更新回数」は(2)になったとする。なお、ループする間の値の変遷を、図４（Ａ）に示す。
【００５８】
以上によりディレクトリエントリの各情報（仮想ディレクトリ情報とinode情報）を計算するための情報があつまったので、まずはエントリ作成時に設定される情報を計算する。ディレクトリシード「12345」、エントリ番号「11850」、エントリの再作成世代番号「6」を組み合わせて擬似乱数アルゴリズムを初期化する。エントリ名（サブディレクトリ名）の乱数部の文字列長を乱数から(5)と決定し、乱数を用いてアルファベットから文字を選択して「ztwgu」をエントリ名の乱数部とする。エントリ名の番号部はエントリ番号から「11850」とする。これらを組み合わせて、エントリ名を「ztwgu_11850」とする。エントリの作成日付は、仮想ディレクトリdirAの作成日付2015/8/1に、再作成世代番号(6)を加算した2015/8/7とし、作成時刻は乱数から12:45:06とする。ファイルパーミッションなど他のi-node情報も設定するが、本技術の説明では重要でないので説明を省略する。
【００５９】
次に、エントリが更新されるときに設定される情報を計算する。擬似乱数アルゴリズムを、ディレクトリシード「12345」、エントリ番号「11850」、エントリの更新世代番号「9」を組み合わせて初期化する。エントリのシードを乱数から「318532」とする。更新日時は仮想ディレクトリdirAの作成日付2015/8/1に、更新世代番号(9)を加えた2015/8/10とし、時刻は乱数で05:43:21とする。
【００６０】
当該エントリ「ztwgu_11850」はサブディレクトリであるので、仮想ディレクトリ「dirA」のグループ情報A1配下のグループ情報Bを、このディレクトリの仮想ディレクトリ情報とし、生成したエントリのシード「318532」を仮想ディレクトリの「シード」とする。また、算出したエントリの更新回数「2」をこの仮想ディレクトリの「世代」とする。これらの一連の処理で、サブディレクトリ「ztwgu_11850」の情報が求まったこととなる（図５のステップＳ６）。
【００６１】
次に、「ztwgu_11850」ディレクトリ内のファイル「g4tapq_10」の情報を計算する（図５のステップＳ７）。まず、仮想ディレクトリ「ztwgu_12390」内のエントリ数を、初期エントリ数(20)＋世代番号(2)×(増加数(5)-削除数(3))＝24と求める。エントリ名「g4tapq_10」の番号部からエントリ番号を「10」とし、エントリ数がエントリ番号より大きいので、このエントリ番号(10)は有効と判定される。そして、エントリ番号(10)は初期エントリ数(20)より小さいため、初期作成世代番号は0とする。仮想ディレクトリ「ztwgu_11850」はグループ情報を１つしか持たないため、「g4tapq_10」が属するグループはファイルグループB1となる。
【００６２】
次に、ディレクトリシード「318532」と、エントリ番号「10」で擬似乱数アルゴリズムを初期化し、初期世代番号(0)から世代番号(2)までループして、エントリ再作成世代番号、更新世代番号、更新回数を計算し、それぞれ0,2,1と求める（図４（Ｂ）のように変遷したとする）。
【００６３】
続いて、作成されるときに設定されるディレクトリエントリの情報を計算する。擬似乱数アルゴリズムをディレクトリシード「318532」、エントリ番号「10」、再作成世代番号「0」で初期化し、乱数でファイル名の乱数部を「g4tapq」と求め、番号部「10」と組み合わせて、ファイル名を「g4tapq_10」とする。作成日付は仮想ディレクトリ「ztwgu_11850」の作成日付2015/8/7と再作成世代番号(0)から2015/8/7とし、時刻は乱数から13:16:19とする。
【００６４】
続いて、更新されるときに設定されるディレクトリエントリの情報を計算する。擬似乱数アルゴリズムをディレクトリシード「318532」、エントリ番号「10」、更新世代番号「2」で初期化し、乱数でエントリのシード（ファイルシード）を「8572」とする。更新日時は仮想ディレクトリ「ztwgu_11850」の作成日付2015/8/7と更新世代番号(2)から2015/8/9とし、時刻は乱数から18:42:06とする。ファイルグループB1のファイルサイズの範囲は1MB-10MBであり、乱数から当該ファイルのサイズは4,125,673バイトとする。これらの一連の処理で。ファイル「g4tapq_10」の情報が求まったこととなる。
【００６５】
上記の処理で、「/dirA/ztwgu_11850/g4tapq_10」のディレクトリエントリが計算できたため、求まったファイルシード「8572」を用いてファイルの内容にアクセスすることができる。この処理は再現性が有り、条件が変わらない限り、何度繰り返しても同じファイルシード値「8572」を得られる。
【００６６】
＜ディレクトリエントリの検索：存在しないファイル＞
存在しないファイル「/dirA/grk75rew_65123」を検索する場合の動作を説明する。前述のように、仮想ディレクトリ「dirA」のエントリ数「16700」を求める。エントリ名「grk75rew_65123」の番号部から、エントリ番号「65123」は、「dirA」のエントリ数より大きいため、このエントリ番号のエントリは存在しないと判断できる。
【００６７】
存在しないサブディレクトリ「/dirA/abcdef_11850」を検索する場合の動作を説明する。前述の「/dirA/ztwgu_11850」の検索と同様、エントリ番号「11850」のディレクトリエントリの情報を作成するが、エントリ番号「11850」のエントリ名の乱数部は「ztwgu」と計算される。エントリ名「abcdef_11850」の乱数部は「abcdef」であり、計算した乱数部と異なるため、「abcdef_11850」という名前のエントリは存在しないと判断できる。
【００６８】
＜ディレクトリの読み込み＞
仮想ディレクトリ「dirA」のディレクトリ読み込み処理を簡潔に説明する。エントリ番号1のディレクトリエントリを計算し、「t4teit_1」というエントリ名とエントリ情報（ファイルグループA2、ファイルシード45678、等）を得る。次に、次のエントリ番号(2)のディレクトリエントリを計算し、「gqqsymznp_2」というエントリ名とエントリ情報を得る。これを繰り返し、dirAのエントリ数16700番までのエントリを得る。
【００６９】
＜スナップショットの作成＞
仮想ファイルシステムに対してスナップショット作成操作が行われると、通常のディレクトリ構造上に存在している仮想ディレクトリ「/dirA」の世代番号を1進め、世代番号を11とする。次回に当該仮想ディレクトリのエントリを計算する場合は、世代番号11が用いられ、一部のエントリ（世代番号11で削除/再作成された、もしくは、変更されたと判定されるエントリ）については世代番号10のときと異なる結果が計算されることとなる。
【００７０】
＜仮想ディレクトリの情報の設定/取得＞
仮想ディレクトリの「/dirA」の代替ストリーム「ramdomdir」（または、拡張属性「system.randomdir」）に対して以下の文字列を設定する。
{ "seed": 12345, "generation":10, "groups": [ { "type": "subdir", "name": "A1", "init": 1000, "inc": 50, "del": 30, "mod": 100, "groups" : [ { "type": "file", "name": "B1", "init": 20, "range": [ 1000000, 10000000 ], "inc": 5, "del": 3, "mod": 4 } ] }, { "type": "file", "name": "A2", "init": 10000, "range": [ 10000, 100000 ], "inc": 1000, "del": 500, "mod": 3000 }, { "type": "file", "name": "A3", "init": 300, "range": [ 1000000, 100000000 ], "inc": 30, "del": 10, "mod": 100 } ] }
【００７１】
これは、図２で示した仮想ディレクトリ「/dirA」の仮想ディレクトリ情報を、JSON形式で表現したものである。この文字列を代替ストリーム（または拡張属性）に設定したことで、仮想ファイルシステム上の「/dirA」は仮想ディレクトリとしてマークされ、設定された仮想ディレクトリ情報は記憶領域に保存される。なお、ここではJSON形式としているが、情報が正しく受け渡せれば形式はなんでも良い。
【００７２】
仮想ディレクトリ「/dirA/ztwgu_11850」の代替ストリーム「randomdir」（または拡張属性「system.ramdomdir」）からデータを取得する処理の流れを説明する。このディレクトリは通常のディレクトリ構造に存在しないため、「ztwgu_11850」に対応するエントリ情報を計算する。ディレクトリのシードは「318532」、世代番号は「1」、グループ情報はファイルグループ「B1」と計算される（計算処理は「ディレクトリエントリの検索」の実施例で前述しているため省略する）。その結果から、以下の文字列を得ることができる。
{ "seed": 318532, "generation": 1, "groups": [ { "type": "file", "name": "B1", "init": 20, "range": [ 1000000, 10000000 ], "inc": 5, "del": 3, "mod": 4 } ] }
【００７３】
通常のディレクトリ「/dirB」を作成し、上記の文字列を代替ストリーム「randomdir」（または拡張属性「system.randomdir」）に設定すると、「/dirB」を仮想ディレクトリとしてマークし、拡張ディレクトリ情報を記憶領域に保存する。作成日付等も「/dirA/ztwgu_11850」と同じに設定すれば、「/dirA/ztwgu_11850」と同じディレクトリ構造を「/dirB」下に再現することができる。
【００７４】
＜ファイルの読み込み＞
「/dirA/ztwgu_11850/g4tapq_10」のファイルを読み込む場合の処理を説明する。ディレクトリエントリを前述のとおりに計算し、ファイルシードは8572、ファイルサイズは4,125,673バイトと求まる。ここでブロックサイズは64KiBとすると、このファイルは4125673÷65536＝62.9より、切り上げて63個のブロックを持つ。先頭から100KB(100,000バイト)のデータを読み込みたいとすると先頭の2つのブロック（ブロック番号0と1）が必要となる。ブロック番号0のデータを生成するために、ファイルシード8572とブロック番号0で擬似乱数アルゴリズムを初期化し、65536バイト分の乱数を計算する。計算した乱数をこのブロックのデータとして扱う。次にブロック番号1のデータを生成するために、ファイルシード8572とブロック番号1で擬似乱数アルゴリズムを初期化し、必要なバイト数（100000−65536＝34464）分乱数を計算する。ブロック番号0のデータとして計算した65536バイトと、ブロック番号1のデータとして計算した34464バイトのデータを合わせて100KBのデータを、読み込みたいデータとして返却する。
【００７５】
同様に上記のファイルのオフセット200,000から32768バイト読み込む場合の処理を説明する。200000÷65536より、読み込みたいデータはブロック番号3から始まる。200000−(ブロック番号(3)*65536)＝3392より、読み込みたいデータはブロック番号3の3392バイト目から始まる。そして3392＋32768＝36160より、ブロック番号3の先頭から36160バイトまで計算すれば良い。ファイルシード8572とブロック番号3で擬似乱数アルゴリズムを初期化し、36160バイトのデータを計算し、3392バイト目から32768バイト分を読み込むデータとして返却する。
【００７６】
＜リストア＞
フルバックアップイメージのリストアの動作について説明する。世代番号5の仮想ディレクトリ「/dirA」がフルバックアップされているものとする。リストア開始時、まず「/dirA」がルートディレクトリ上に通常の（仮想ディレクトリでない）ディレクトリとして作成される。次に代替ストリーム（または拡張属性）が「/diA」に対してリストアされるが、ここで仮想ディレクトリ情報が設定され、「/dirA」が世代番号5、その他図2と同等の仮想ディレクトリ情報を持つ仮想ディレクトリとして設定される。
【００７７】
次に「/dirA/t4teit_1」というファイルが作成される。このとき、ファイル名（＝エントリ名）「t4teit_1」の番号部からエントリ番号1としてディレクトリエントリが計算され、存在するファイルであること、ファイルシードは45678、ファイルサイズ64321などの情報を得る。このファイルへの先頭からデータ「ABCDE…」が書き込まれる。ファイルシード45678とブロック番号0から計算したデータ「ABCDE…」と比較して等しいことを確認し、ファイルの終わり(64321バイト分)まで続ける。内容に相違がないため、差分情報を記録せず処理を続ける。その後、処理を繰り返す。
【００７８】
その後、「/dirA/mxgqhaz_100」としてディレクトリが作成される。この時もファイルの場合と同様に、エントリ名「mxgqhaz_100」からエントリ番号100としてディレクトリエントリを計算し、存在していること、仮想ディレクトリ情報（ディレクトシード、ファイルグループB1の情報など）を計算する。
【００７９】
次にディレクトリに対して、代替ストリーム（拡張属性）が書き込まれた際に、設定された仮想ディレクトリ情報が上記で計算した情報と等しいか確認し、相違が無いため、差分情報を記録せずに処理を進める。途中の「/dirA/kzrqg_10000」というファイルで内容に相違が見つかったため、そのファイル名が差分情報として記録される。最終的にリストアが終了した後、差分情報にはファイルに相違が見つかったファイル「/dirA/kzrqg_10000」が記録されており、バックアップ前とリストア後に相違点があることが検出できる。
【００８０】
差分バックアップイメージのリストアついて説明する。世代番号5でフルバックアップを取っており、世代番号7までの差分バックアップをとっているとする。最初のフルバックアップイメージ（世代番号5）のリストアは前述のとおりである。世代番号6のリストアでは、最初に「/dirA」の仮想ディレクトリ情報がリストアされ、「/dirA」の世代番号が6に更新される。
【００８１】
次に「/dirA/gfdyeln_123」のファイルが差分バックアップイメージに含まれていたため、リストアされる。エントリ名からエントリ番号123でディレクトリエントリが計算され、ファイルシード2445などのディレクトリエントリ情報を得る。ファイルへの書き込まれたデータと、ファイルシード2445から計算されるデータを比較し、相違がないため、差分データは書き込まない。同様に残りのファイル/ディレクトリのリストアに付いても処理され、差分バックアップイメージ内のデータのリストアが終わると、次の世代番号7の差分バックアップイメージのリストアが開始される。世代番号6と同様に「/dirA」の世代番号が7に更新され、内部のファイル/ディレクトリ関してリストア内容の確認が行われる。最終的に、差分情報がないことを確認して、バックアップ前とリストア後でデータが等しいことが確認できる。
【００８２】
以上のように、本実施形態におけるストレージシステムによると、実際のストレージや従来技術の仮想ファイルシステムに対して、
・ディレクトリ構造を保存する記憶域が不要である。
・ディレクトリ構造を作成する時間がかからない
という効果がある。
【００８３】
本技術では、ディレクトリ構造を下って復元する場合でも、ディレクトリエントリを計算する場合の計算量は、ディレクトリの深さ(D）および、世代数(G)にのみ影響を受け、O(D×G)である。ディレクトリエントリの個数(N)に対してD/Gは一般的に十分に小さいため、とても小さな計算量でディレクトリエントリを生成できる。（例えばN=1000万に対してD=5,G=100程度など。）対して、例えば、ディレクトリエントリを計算するために、同一ディレクトリ内のエントリを全て計算する必要がある場合、ディレクトリエントリ数にも影響され、非常に大きな計算量となり、とても実用的ではない。
【００８４】
また、上記で説明したように、計算したサブディレクトリのエントリ情報をキャッシュしておくことで、サブディレクトリ内のエントリ検索を高速化でき、キャッシュにヒットした場合の計算量は世代数にのみ比例するO(G)まで小さくすることができる。
【００８５】
差分バックアップの評価では、仮想ファイルシステムの世代を進めてバックアップ操作を行っていく。本技術ではバックアップソフトウェアがバックアップの際に行うスナップショット作成の操作で世代を進めるため、単純にバックアップジョブを繰り返すだけで世代を進めながらバックアップの評価を行うことができる。
【００８６】
リストアの評価では、仮想ディレクトリのリストア時に代替ストリームや拡張属性を通して、仮想ディレクトリ情報もリストアされるため、仮想ディレクトリ内の構造が復元でき、実際にリストアされるべき内容を計算可能となる。計算したデータと実際にリストアされたデータを比較することで、バックアップ前とリストア後でデータに相違がないことを一度のリストア操作で確認できる。このため、別ストレージにリストアして、内容のコンペアなどを行う必要がない。
【００８７】
仮想ファイルシステムのディレクトリ構造は再帰的に構成されており、仮想ディレクトリの情報（シード、世代番号、グループ情報）を正しく与えれば、巨大なディレクトリ構造の一部のみを再現することもできる。これは、リストアの評価で一部のディレクトリのみリストアする場合の評価ができることも意味する。
【００８８】
［他の実施例］
＜ファイルデータの一部更新＞
前述の手法では、世代の切り替わりで、仮想ディレクトリ上のファイルを変更する場合、ファイルシードを前の世代と別の値とすることで、ファイルのデータを変更するようにしていた。つまり、変更する場合は、ファイルの内部全体を変更する。しかし、ユーザシステムによっては、ファイルを更新する場合に一部のみ更新するパターンのシステムの場合もある。このようなシステムをシミュレーションするため、前述の手法にデータの一部を更新する機能を追加することを考える。
【００８９】
まず、ファイルグループ情報に「ファイルの更新率」を設定しておくこととする。仮想ディレクトリ上のファイルのディレクトリエントリが作成される場合、「ファイルの更新率」を仮想ディレクトリ情報からディレクトリエントリ情報にコピーしておく。また、ディレクトリエントリ計算時の「エントリの更新回数」を「ファイルの世代番号」として、ディレクトリエントリ情報に含める。
【００９０】
そして、実際にファイルのデータを計算する場合、各ブロックのデータ計算時に以下のように処理する。まず、ファイルのシード、ブロック番号で擬似乱数アルゴリズムを初期化し、乱数値を初期世代(0)での「ブロックのシード」とする。ループ変数を初期世代(0)とし、以降、ファイルの世代番号に達するまで、乱数を用いて「ファイルの更新率」の確率で、「ブロックのシード」を乱数で再計算する。ファイルの世代番号に達した時点でブロックのシードが確定する。後は、ファイルのシードとブロックのシードを組み合わせて擬似乱数アルゴリズムを初期化し、乱数でブロックのデータを生成する。
【００９１】
上記の実施例を以下に示す。図２に示すディレクトリ情報のファイルグループA3について、ファイル更新率を0.02とする。ファイルグループA3に属するファイル「/dirA/kgqitx_12375」からブロック番号5のデータを読み込む場合の動作を説明する。当該ファイルのディレクトリエントリを計算し、ファイルシード(25824)、ファイルの更新率(0.02)、ファイルの世代番号(3)を得る。
【００９２】
ファイルのシード(25824)とブロック番号(5)で擬似乱数アルゴリズムを初期化し、乱数値(1269)を得、それを初期世代のブロックのシードとする。乱数値を計算し0.013を得る。この値はファイルの更新率(0.02)より小さいため、このブロックは更新されたとして、ブロックのシードを新しい乱数値(35797)で上書きする。これを世代番号(3)回分繰り返し（1回分は今実行したので、後2回）、最終的にブロックのシード(35797)を得る(繰り返した2回では変更されなかった)。最後にファイルのシード(25824)とブロックシード(35797)で擬似乱数アルゴリズムを初期化し、乱数で64KiBのデータを作成し、ブロック番号5のデータとして返却する。
【００９３】
このような手法で、ファイル全体ではなく、一部を更新するというシステムのシミュレーションを行うことができる。重複排除機能を持つ高機能ストレージに対してバックアップを行う場合、重複率（つまりファイルのデータのどの程度が以前と同じであるか）は動作や性能を決める重要な要因であるため、ファイルの一部を更新するようなシステムの評価に有効である。また、本手法では、ファイルへのランダムアクセスの際、ブロックのシードを求める処理が世代番号にのみ依存するため、アクセスしたファイル内のオフセットやファイルサイズ等に影響されずに高速に計算可能である。
【００９４】
＜一部のディレクトリのみのリストア＞
本技術でリストア評価を行う際、バックアップしたイメージの内、一部のディレクトリのみをリストアする場合でも、差異の確認を正しく行える。リストアするディレクトリの代替ストリーム/拡張属性をリストアする際、当該ディレクトリの仮想ディレクトリ情報が再構築されるため、それを用いて、当該仮想ディレクトリ以下のファイル/サブディレクトリについても、ディレクトリエントリを計算可能で、それを用いて内容の再確認が可能である。
【００９５】
［その他の実施形態］
上記では、擬似乱数アルゴリズムは一様乱数を想定して記述しているが、それに限るものではない。乱数に偏りをもたせると、世代間の更新でファイルやディレクトリの更新を偏らせることもできる。例えば、正規乱数などの偏りのある乱数を利用してもよいし、一様乱数をある関数で写像して偏りをもたせた乱数でも良い。乱数でなく、一定のルールやサンプリング情報に従って、ユーザシステムの挙動をより正確に再現する数列を生成してもよい。
【００９６】
エントリ名（ファイル名／ディレクトリ名）は乱数で文字コードを決定することとしているが、これに限るものではない。たとえば、単語辞書データ等から乱数で単語を抽出して組み合わせても良いし、一定のルールでエントリ番号をファイル名に写像してもよい。
【００９７】
初期ファイル数、世代間での増加／削除／更新ファイル数は、固定値にしているが、これに限るものではない。グループにはファイル数の範囲を保存しておき、乱数等を用いてファイル数を決定してもよい。この場合、ディレクトリエントリ計算時のエントリの初期作成世代番号の計算、所属するグループ情報の判定が多少複雑になる。乱数を用いて各世代でのエントリ数を計算し、それとエントリ番号を比較することで、ディレクトリエントリの存在チェックや初期作成世代番号、所属グループを求める。
【００９８】
上記のファイルデータの一部更新の機能拡張例では、説明の簡便性のためファイルの更新率は固定としたが、仮想ディレクトリ情報には更新率の範囲を保存しておき、ファイルのディレクトリエントリ作成時に乱数で更新率を決定してもよい。
【００９９】
本技術ではデータを高速に生成することができるため、実際のユーザシステムのバックアップより高い性能でデータを読み込むことができる。そのため必要よってはユーザシステムでデータを保存しているストレージの性能をシミュレーションする必要があるかもしれない。この場合、仮想ファイルシステム全体で、ユーザシステムのストレージの性能に近づく様、帯域制限を実施することで高すぎる性能を抑制できる。（例えば、ユーザシステムのストレージが1GB/sのスループット持つとすると、1MBのデータを読み込むたびに1ミリ秒のsleepを行うなど。）
【０１００】
［実施形態２］
次に、本発明の第２の実施形態を、図６を参照して説明する。図６は、本実施形態におけるストレージシステムの構成を示すブロック図である。
【０１０１】
図６に示すように、ストレージシステム１００は、ディレクトリに設定されたディレクトリシード情報を記憶する記憶部１２０と、ディレクトリシード情報に基づいてディレクトリ内のデータを生成するデータ生成部１１０と、を備えている。そして、データ生成部１１０は、ディレクトリシード情報と、ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する。
【０１０２】
上記構成により、ストレージシステム１００は、仮想ディレクトリ上のディレクトリ構造やファイルデータの内容を直接記憶装置に保存せず、計算によって必要な仮想ディレクトリや仮想ファイルを生成する。このため、仮想ファイル用の記憶領域の容量を低減し、処理時間の短縮を図ることができる。
【０１０３】
＜付記＞
上記実施形態の一部又は全部は、以下の付記のようにも記載されうる。以下、本発明におけるストレージシステム、プログラム、データ生成方法の構成の概略を説明する。但し、本発明は、以下の構成に限定されない。
【０１０４】
（付記１）
ディレクトリに設定されたディレクトリシード情報を記憶する記憶部と、
前記ディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成するデータ生成部と、を備え、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
ストレージシステム。
【０１０５】
（付記２）
付記１に記載のストレージシステムであって、
前記データ生成部は、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリに設定されるサブディレクトリシード情報を生成し、
前記サブディレクトリシード情報と、前記サブディレクトリ内のデータのエントリ番号と、に基づいて、当該サブディレクトリ内のデータであるファイルあるいはディレクトリを生成する、
ストレージシステム。
【０１０６】
（付記３）
付記２に記載のストレージシステムであって、
前記データ生成部は、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリが最後に再作成された世代を表す再作成世代番号と、当該サブディレクトリが最後に更新された世代を表す更新世代番号と、を生成し、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記再作成世代番号と、前記更新世代番号と、に基づいて、前記サブディレクトリのデータを生成する、
ストレージシステム。
【０１０７】
（付記４）
付記３に記載のストレージシステムであって、
前記記憶部は、世代の変化に伴う前記サブディレクトリ内のデータ数の変化を表すデータ数情報を記憶し、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記データ数情報と、に基づいて、前記再作成世代番号と前記更新世代番号とを生成する、
ストレージシステム。
【０１０８】
（付記５）
付記４に記載のストレージシステムであって、
前記データ生成部は、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記再作成世代番号と、に基づいて、前記サブディレクトリの作成時に設定されるデータを生成し、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記更新世代番号と、に基づいて、前記サブディレクトリの更新時に設定されるデータを生成する、
ストレージシステム。
【０１０９】
（付記６）
付記５に記載のストレージシステムであって、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記更新世代番号と、に基づいて、前記サブディレクトリシード情報を生成する、
ストレージシステム。
【０１１０】
（付記７）
付記１乃至６のいずれかに記載のストレージシステムであって、
前記記憶部は、前記ディレクトリ内のデータをグループ分けしたグループ毎に、世代の変化におけるグループ内のデータ数の変化を表す情報を含むグループ情報を記憶しており、
前記データ生成部は、前記グループ情報と、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、前記サブディレクトリが属するグループを特定して、当該特定したグループの前記グループ情報を用いて、前記サブディレクトリのデータを生成する、
ストレージシステム。
【０１１１】
（付記８）
付記１乃至７のいずれかに記載のストレージシステムであって、
前記記憶部は、前記ディレクトリの世代を表す世代番号を記憶すると共に、世代の変化に伴う前記サブディレクトリ内のデータ数の変化を表すデータ数情報を記憶しており、
前記データ生成部は、前記世代番号と、前記データ数情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリが存在するか否かを判定し、当該サブディレクトリが存在すると判定した場合に当該サブディレクトリのデータを生成する、
ストレージシステム。
【０１１２】
（付記９）
ストレージ装置に、
記憶部に記憶されているディレクトリに設定されたディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成するデータ生成部を実現させるプログラムであり、
前記データ生成部は、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
プログラム。
【０１１３】
（付記１０）
記憶部に記憶されているディレクトリに設定されたディレクトリシード情報に基づいて、前記ディレクトリ内のデータを生成する際に、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリのデータを生成する、
データ生成方法。
【０１１４】
（付記１１）
付記１０に記載のデータ生成方法であって、
前記ディレクトリ内のデータを生成する際に、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリに設定されるサブディレクトリシード情報を生成し、
前記サブディレクトリシード情報と、前記サブディレクトリ内のデータのエントリ番号と、に基づいて、当該サブディレクトリ内のデータであるファイルあるいはディレクトリを生成する、
データ生成方法。
【０１１５】
（付記１２）
付記１１に記載のデータ生成方法であって、
前記ディレクトリ内のデータを生成する際に、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリが最後に再作成された世代を表す再作成世代番号と、当該サブディレクトリが最後に更新された世代を表す更新世代番号と、を生成し、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記再作成世代番号と、前記更新世代番号と、に基づいて、前記サブディレクトリのデータを生成する、
データ生成方法。
【０１１６】
（付記１３）
付記１２に記載のデータ生成方法であって、
前記記憶部は、世代の変化に伴う前記サブディレクトリ内のデータ数の変化を表すデータ数情報を記憶しており、
前記ディレクトリ内のデータを生成する際に、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記データ数情報と、に基づいて、前記再作成世代番号と前記更新世代番号とを生成する、
データ生成方法。
【０１１７】
（付記１４）
付記１３に記載のデータ生成方法であって、
前記ディレクトリ内のデータを生成する際に、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記再作成世代番号と、に基づいて、前記サブディレクトリの作成時に設定されるデータを生成し、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記更新世代番号と、に基づいて、前記サブディレクトリの更新時に設定されるデータを生成する、
データ生成方法。
【０１１８】
（付記１５）
付記１４に記載のデータ生成方法であって、
前記ディレクトリ内のデータを生成する際に、
前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、前記更新世代番号と、に基づいて、前記サブディレクトリシード情報を生成する、
データ生成方法。
【０１１９】
（付記１６）
付記１０乃至１５のいずれかに記載のデータ生成方法であって、
前記記憶部は、前記ディレクトリ内のデータをグループ分けしたグループ毎に、世代の変化におけるグループ内のデータ数の変化を表す情報を含むグループ情報を記憶しており、
前記ディレクトリ内のデータを生成する際に、
前記グループ情報と、前記ディレクトリシード情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、前記サブディレクトリが属するグループを特定して、当該特定したグループの前記グループ情報を用いて、前記サブディレクトリのデータを生成する、
データ生成方法。
【０１２０】
（付記１７）
付記１乃至１６のいずれかに記載のデータ生成方法であって、
前記記憶部は、前記ディレクトリの世代を表す世代番号を記憶すると共に、世代の変化に伴う前記サブディレクトリ内のデータ数の変化を表すデータ数情報を記憶しており、
前記ディレクトリ内のデータを生成する際に、
前記世代番号と、前記データ数情報と、前記ディレクトリ内のサブディレクトリのエントリ番号と、に基づいて、当該サブディレクトリが存在するか否かを判定し、当該サブディレクトリが存在すると判定した場合に当該サブディレクトリのデータを生成する、
データ生成方法。
【０１２１】
なお、上述したプログラムは、記憶装置に記憶されていたり、コンピュータが読み取り可能な記録媒体に記録されている。例えば、記録媒体は、フレキシブルディスク、光ディスク、光磁気ディスク、及び、半導体メモリ等の可搬性を有する媒体である。
【０１２２】
以上、上記実施形態等を参照して本願発明を説明したが、本願発明は、上述した実施形態に限定されるものではない。本願発明の構成や詳細には、本願発明の範囲内で当業者が理解しうる様々な変更をすることができる。
【符号の説明】
【０１２３】
１０  仮想ファイルシステム
１１  仮想ディレクトリ
１２  仮想ファイル
１３  仮想ディレクトリ情報記憶部
１４  通常ディレクトリ構造記憶部
１５  差分情報記憶部
２０  バックアップソフトウェア
２１  評価対象ストレージ
３０  仮想ディレクトリ作成ソフトウェア
１００  ストレージシステム
１１０  データ生成部
１２０  記憶部
【図１】
0006665616.tif 000002
【図２】
0006665616.tif 000003
【図３】
0006665616.tif 000004
【図４】
0006665616.tif 000005
【図５】
0006665616.tif 000006
【図６】
0006665616.tif 000007