第7回 HFS、HFS Plusの基本的概念【前編】Undocumented Mac OS X(3/4 ページ)

» 2007年07月24日 01時53分 公開
[白山貴之,ITmedia]

カタログノード

 UNIXでのiノードのエントリのように、どのエクステントがどのファイルに属するか、ファイル名やパーミッション、オーナー、グループといった属性をまとめたのがカタログノードだ。

 カタログノードには必ず、そのボリューム上で一意の32ビットの値がつけられる。これがカタログノードID(CNID)だ。iノード番号との大きな違いとして「CNIDは再利用されず*、そのファイルが削除されても2度と使われることがない」という点が挙げられる。このためCNIDはiノード番号以上に特定のファイルと強く結びついている。

 また、CNIDはファイルが作成されるごとに順に割り当てられるが、幾つかのCNIDは予約されており、最初から用途が決まっている(表1)

キーワード ID値 意味
kHFSRootParentID 1 ルートディレクトリの親ID
kHFSRootFolderID 2 ルートディレクトリのディレクトリID
kHFSExtentsFileID 3 エクステントオーバーフローファイルのファイルID
kHFSCatalogFileID 4 カタログファイルのファイルID
kHFSBadBlockFileID 5 不良ブロックファイルのファイルID
kHFSAllocationFileID 6 アロケーションファイルのファイルID
kHFSStartupFileID 7 スタートアップファイルのファイルID
kHFSAttributesFileID 8 アトリビュートファイルのファイルID
kHFSBogusExtentFileID 15 ExchangeFilesオペレーションの間に一時的に使用される
kHFSFirstUserCatalogNodeID 16 ユーザーファイルおよびユーザーディレクトリが使用できる最初のCNID
表1 予約済みのカタログノードID(CNID)

 図3はHFS Plusでのファイルに対するカタログノードの定義だ。データフォーク、リソースフォークにそれぞれ8つのエクステント領域*(HFSの場合は3つ)が割り当てられている。

図3 図3 HFS Plusでのファイルに対するカタログノードの定義。データフォークとリソースフォークはそれぞれHFSPlusForkData構造体が割り当てられ、そこにはHFSPlusExtentRecord型のextentsがある。HFSPlusExtentRecord型はHFSPlusExtentDescriptor構造体8つで構成される配列である。

 では、このカタログノードはどこに収められているのだろうか? iノードの場合はiノード領域に格納されているが、カタログノードはカタログファイルというファイルに格納されているのだ。カタログファイルはCNIDが4に固定されたデータフォークだけが存在するファイルで、ファイル数が増えてカタログノードが増えた場合、通常のファイルと同じくエクステントを伸ばすか、新しいエクステントを確保することで領域を確保する。この仕組みは通常のファイルとまったく変わりない。カタログファイルの中で、カタログノードは「親ディレクトリのCNIDと自身のファイル名」をキーにしたB-Tree*で管理されている(リスト2、図4)


/* HFS Plus catalog key */
struct HFSPlusCatalogKey {
        u_int16_t keyLength; /* key length (in bytes) */
        u_int32_t parentID; /* parent folder ID */
        HFSUniStr255 nodeName; /* catalog node name */
};

リスト2 HFS Plusにおけるカタログキーの構造。親ディレクトリのCNIDと自身のファイル名で構成されている
図4 図4 カタログファイルのB-Tree。ヘッダーノードには先頭と最後、そしてルートとなるノードへのポインタが格納されている。ルートノードを含む、中間の木構造を構成するノードはインデックスノードと呼ばれ、下位ノードへのポインタだけを格納している。下位ノードを持たないノードはリーフノードと呼ばれ、ここに先のカタログノードの情報が格納されている。ノードはキーによってソートされている

 この複合キーは一方をワイルドカードにして検索することもできる。つまり、親ディレクトリのCNIDだけ指定して、ファイル名をワイルドカードにすることで同じディレクトリに格納されているファイルだけを素早く引き出せる(図5)

図5 図5 カタログノードは「親ディレクトリのCNID」「自身のファイル名」というキーでソートされている。このため、同じ親ディレクトリに属するファイルに対するノードはB-Treeの特定領域に固まって現れやすくなる

 カタログファイルもエクステントで構成される、通常のファイルとまったく同じ構成を持つ「ファイル」であるが、カタログファイル自身のエクステントだけはカタログファイルで管理できない。こうした特殊なファイルのエクステントに関しては、HFS Plusボリュームの先頭第2セクタに存在するボリュームヘッダに記載されている。リスト3がHFS Plusのボリュームヘッダ情報だ。表2の5つのファイルがこのボリュームヘッダで管理されている。

編集部注:リスト3には多くの注釈線が含まれているため、画像として用意しました。上記アイコンをクリックいただくことでご覧いただけます
ファイル名 役割
カタログファイル ファイルやディレクトリに関する情報を管理
アロケーションファイル 各アロケーションブロックの使用状況を管理するビットマップを管理する
エクステントオーバーフローファイル ファイルが8つ以上のエクステントが必要になった場合、こちらにエントリを追加して管理する
アトリビュートファイル データフォーク、リソースフォーク以外のフォークに関する情報を管理する
スタートアップファイル OSのブートローダーを格納するための領域。Mac OS 9、Mac OS Xでは使用されていない
表2 ボリュームヘッダーで管理されているファイル

このページで出てきた専門用語

CNIDは再利用されず

つまり、ファイルを作って消すようなことを繰り返していると、いつか使えなくなるのがHFS Plusなのだ。最も、32ビットの数値を使い果たすにはかなりの時間(1秒に100ファイルを作成し即削除したとして約500日)が掛かるので、パーソナルユースではそう気にすることもないだろう。

8つのエクステント領域

ファイルの断片化が進み、データフォークまたはリソースフォークの確保に8つ以上のエクステントが必要になった場合は、エクステントオーバーフローファイルが利用される。また、データフォークとリソースフォーク以外のフォークでエクステントが不足した場合は、エクステントオーバーフローファイルではなくアトリビュートファイルに、追加のエクステントに関する情報が記録される。

B-Tree

FATのように単純なテーブル構造ではなく、B-Treeを用いたためHFS/HFS Plusは高速にファイルの探索を行えたのだが、一方でファイルの作成や削除時には、より複雑な構造を更新しなければならない。メモリ保護もなくOSの管理構造すらアプリケーションから上書きされ放題だった旧Mac OSではこうした複雑さゆえ、カタログファイルの破損とそれに伴うファイルの消失が極めて多かった。


関連キーワード

Apple | Mac | Mac OS X


Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ