ロード トップ 参照元 逆検索 検索 ヘルプ

[logo] ジャーナリングファイルシステム/原理


ジャーナリングファイルシステム

原理を簡単に説明。ただし間違っているかも。


ジャーナリングファイルシステムの目的は、ファイルシステム 自体の保護である。なかのファイルの保護まではサポートしていない。

ファイルシステム を保護するというのはどういうことか ... 簡単にいうと、スーパーブロック、ディレクトリ、フリーリスト、inode および inode からリンクされているデータブロックのリスト といった メタデータの 整合性を取る ということになる。(ここでは、そういったデータすべてをメタデータ と表現する)

整合性を取るためには、トランザクションという考え方を導入する以外になく、 トランザクションを実現するためには、別のデータがディスク上に必要になる。

そのデータが ジャーナル というものであり、それを行うことがジャーナリング。

---

さて、トランザクションをどう実現するかを簡単に説明する。

基本的に、データ自身の更新は、ファイルシステムの整合性には関係ない。 もともとあるデータブロックをいくら更新しても ファイルシステムの整合性 には関係ないのは当然として、 新しい データをアロケートして、ディスクに書いたとしても ファイルシステムの整合性には関係ない。なぜなら、 単に使っていない領域に書き込むだけだから。

したがってメタデータをどのように更新するかということたけが重要である。

以上がジャーナリングのアイディアである。

さて、そのアイディアを実現するために どういうことが必要だろうか。

メモリ上のメタデータを Disk に書きたい場合、どのように更新したかを...

たとえば

憶えておく。

というのが、簡単で有効な方法だろう。

ジャーナルには、更新された内容と、どこから どこまで の内容か の情報を 書き出せば良い。

ただし、それだけでは不十分

必要がある。

ジャーナル上のデータが不要になったことを ジャーナルに書き出す。

ジャーナル上には、

       トランザクションN 
       [    更新データ   ] .... [トランザクションNの完了]  

といった、2 つのデータの組みが書かれることになる。

オリジナルデータは複数の領域をサポートしなければならない。

       データの数
       データ0 : ブロック番号  ブロック内の offset と size  内容がある位置
       データ1 : ブロック番号  ブロック内の offset と size  内容がある位置
       データ2 : ブロック番号  データブロックに使われたという情報
       データ3 : ブロック番号  ブロック内の offset と size  内容がある位置
       内容0
       内容1
       内容3
map を作って内容を順に書き出す ... こういったものでも良いかもしれない。

トランザクションの完了とは、関係するメモリ上のメタデータを Disk に書き終った ということだから、ずっと後になっても良い。

また、メモリ上のメタデータは、どんどん変更される。 かならずしも、トランザクションに残したデータと同じイメージが書かれるわけ ではない。なぜそれで良いかというと... そういう場合は、 実際にDiskにかかれるまでに、同一データに対して、 いくつかのスナップショットイメージが、ジャーナルに残る。
有効なスナップショットイメージを順に展開すると上書きすることになって、 最後のスナップショットイメージが残る。
そうやってできた Disk のデータは正しいもののはずである。
正しくないかもしれないデータであれば、ジャーナルで正しくでき。 有効なジャーナルになければ、ディスクのデータは正しい。

有効なジャーナルについて、更新を シミュレートしていく。

これはいったいどうやるのであろうか。

有効なジャーナルについて、その通りにすれば、データブロックを壊すかもしれない。 たとえば、有効なジャーナルが ある block について

      o block が free された
      o それは free リストのための block として使われた。
      o 結局また 使用されて データブロックになった。

これを、buf を使ってシミュレートすれば、データブロックの情報を壊してしまう。 たぶん、シミュレートした有効な最終結果 のみを Disk に反映しないといけない。

有効なジャーナルというのは、完了していない 最初のトランザクションの位置 から、最後に書き込んだ ところまで の範囲で、 完了していない トランザクションすべて ということになる。

さて.. 有効なジャーナルをどうやって見つけ出すか。

少なくとも

という構造はしている必要があると思う。

そのためには、ジャーナルの領域の先頭は、かならず トランザクションデータの 先頭でないといけない。--- ようするに、リングバッファとして使うが、 最後のエリアを越えて先頭にまたがるデータは書かない。

  • あるデータは、前のデータのサイズも知っている。

    そういった構造にしておけば、どこでも良いから データの先頭をつかまえられれば すべてのデータを辿れる という性質を与えられる。

    ただし、それだけでは、循環しているようなデータになったとき、 先頭も最後もわからない。 データの順序関係を知るためには、タイムスタンプをいれておくのが単純で 効果的な方法だろう。ただし、先頭にいれれば、書き出したことは わかるが 書き終ったかどうかがわからない。md5 ダイジェストで、 データを確認するという手順が 必要になる。( 他には、データの最後にもタイムスタンプをいれておく ... といったやりかたが考えられる。しかし、md5 の方が確実だと思う。)

    というわけで ... ジャーナルにかかれる1つのデータはつぎのような情報を含んで いるとよさそうだ。

    ところで、タイムスタンプはどういう情報が良いのだろうか。

    という性質だけを持っていれば良い。

    XFS では、時間を使わずに、

    この2つの組みを使っているようだ。


    どうだろう。実際のファイルシステムで使われているのは非常に複雑だが、 こうやって 書いてみると 意外と簡単なもの .. という気がしなくはない。

    いちど、V7 のファイルシステムを ジャーナリングファイルシステムにする とか、やってみたいものだ。


    (最終更新 Thu Mar 30 19:19:58 2006)