FS(5)

名称
fs, inode - ファイルシステムボリュームのフォーマット

書式
<sys/param.h> <ufs/ffs/fs.h>

<sys/types.h> <sys/lock.h> <ufs/ufs/quota.h> <ufs/ufs/inode.h>

解説
ファイル <fs.h> と <inode.h> は、ランダムアクセスデバイス (ディスク) 上のファイルシステムオブジェクト の基本フォーマットを作成、管理する際に使われるいくつかの構造体、 定義済み変数、マクロを宣言します。

ファイルシステムはブロックサイズとブロック数から構成されており、 これらはファイルシステムのパラメータになります。 BBLOCK から始まり 大きさ BBSIZE だけ続くセクタは、 ディスクラベルといくつかの一次、二次ハードウェアブートストラッププログラム のために使われます。

実際のファイルシステムは、 SBLOCK セクタから始まり、そこには 大きさが SBSIZE である スーパブロック があります。 ファイル <ufs/ffs/fs.h> にある以下の構造体は、スーパブロックを記述しています。

    /*
     * FFS ファイルシステムのスーパブロック
     */
    struct fs {
    	int32_t	 fs_firstfield;	/* 内部スーパブロック用に使われる、歴史的な */
    	int32_t	 fs_unused_1;	/*     ファイルシステムのリンク済みリスト */
    	ufs_daddr_t fs_sblkno;	/* ファイルシステム内のスーパブロックのアドレス */
    	ufs_daddr_t fs_cblkno;	/* ファイルシステム内のシリンダブロックのオフセット */
    	ufs_daddr_t fs_iblkno;	/* ファイルシステム内の inode ブロックのオフセット */
    	ufs_daddr_t fs_dblkno;	/* cg 後の最初のデータのオフセット */
    	int32_t	 fs_cgoffset;	/* シリンダ内のシリンダグループオフセット */
    	int32_t	 fs_cgmask;	/* mod fs_ntrak の計算に使われる */
    	time_t 	 fs_time;	/* 最後に書き込まれた時刻 */
    	int32_t	 fs_size;	/* fs 内のブロック数 */
    	int32_t	 fs_dsize;	/* fs 内のデータブロック数 */
    	int32_t	 fs_ncg;	/* シリンダグループの数 */
    	int32_t	 fs_bsize;	/* fs 内の基本ブロックサイズ */
    	int32_t	 fs_fsize;	/* fs 内のフラグメントブロックサイズ */
    	int32_t	 fs_frag;	/* fs の 1 ブロック中のフラグメント数 */
    /* 以下はコンフィギュレーションパラメータ */
    	int32_t	 fs_minfree;	/* フリーブロックの最小パーセンテージ */
    	int32_t	 fs_rotdelay;	/* 最適な次ブロックのための ms 数 */
    	int32_t	 fs_rps;	/* 1 秒あたりのディスク回転 */
    /* これらのフィールドは他のフィールドから計算できる */
    	int32_t	 fs_bmask;	/* ``blkoff'' ブロックオフセットの計算 */
    	int32_t	 fs_fmask;	/* ``fragoff'' フラグメントオフセットの計算 */
    	int32_t	 fs_bshift;	/* ``lblkno'' 論理ブロック番号の計算 */
    	int32_t	 fs_fshift;	/* ``numfrags'' フラグメント数の計算 */
    /* 以下はコンフィギュレーションパラメータ */
    	int32_t	 fs_maxcontig;	/* 連続したブロックの最大数 */
    	int32_t	 fs_maxbpg;	/* シリンダグループあたりの最大ブロック数 */
    /* これらのフィールドは他のフィールドから計算できる */
    	int32_t	 fs_fragshift;	/* フラグメントシフトするブロック */
    	int32_t	 fs_fsbtodb;	/* fsbtodb と dbtofsb シフト定数 */
    	int32_t	 fs_sbsize;	/* スーパブロックの実際の大きさ */
    	int32_t	 fs_csmask;	/* csum ブロックオフセット */
    	int32_t	 fs_csshift;	/* csum ブロック数 */
    	int32_t	 fs_nindir;	/* NINDIR の値 */
    	int32_t	 fs_inopb;	/* INOPB の値 */
    	int32_t	 fs_nspf;	/* NSPF の値 */
    /* 別のコンフィギュレーションパラメータ */
    	int32_t	 fs_optim;	/* 最適化の選択、以下を参照 */
    /* これらのフィールドはハードウェアから引き出される */
    	int32_t	 fs_npsect;	/* 予備を含むトラックあたりのセクタ数 */
    	int32_t	 fs_interleave;	/* ハードウェアセクタインタリーブ */
    	int32_t	 fs_trackskew;	/* トラックあたりのセクタ 0 ゆがみ */
    /* fs_id は未使用の fs_headswitch と fs_trkseek のフィールドの空間を保持 */
    	int32_t	 fs_id[2];	/* ユニークなファイルシステム ID */
    /* シリンダグループの数とサイズにより決められるサイズ */
    	ufs_daddr_t fs_csaddr;	/* シリンダグループ総括領域のブロックアドレス */
    	int32_t	 fs_cssize;	/* シリンダグループ総括領域のサイズ */
    	int32_t	 fs_cgsize;	/* シリンダグループサイズ */
    /* これらのフィールドはハードウェアから引き出される */
    	int32_t	 fs_ntrak;	/* シリンダあたりのトラック数 */
    	int32_t	 fs_nsect;	/* トラックあたりのセクタ数 */
    	int32_t	 fs_spc;   	/* シリンダあたりのセクタ数 */
    /* これはディスクドライバパーティション作成時のもの */
    	int32_t	 fs_ncyl;   	/* ファイルシステムのシリンダ数 */
    /* これらのフィールドは他のフィールドから計算できる */
    	int32_t	 fs_cpg;	/* グループあたりのシリンダ数 */
    	int32_t	 fs_ipg;	/* グループあたりの inode 数 */
    	int32_t	 fs_fpg;	/* グループあたりのブロック数 * fs_frag */
    /* このデータはクラッシュ後に再計算されなければならない */
    	struct	csum fs_cstotal;/* シリンダ総括情報 */
    /* 以下のフィールドはマウント時にクリアされる */
    	int8_t   fs_fmod;    	/* スーパブロック変更フラグ */
    	int8_t   fs_clean;    	/* ファイルシステムがクリーンであるフラグ */
    	int8_t   fs_ronly;   	/* 読み込み専用でマウントされたフラグ */
    	int8_t   fs_flags;   	/* 現在未使用のフラグ */
    	int8_t   fs_fsmnt[MAXMNTLEN];	/* マウントされている名前 */
    /* これらのフィールドは現在のブロックの配置情報を保持する */
    	int32_t	 fs_cgrotor;	/* 最後に検索された cg */
    	struct	csum *fs_csp[MAXCSBUFS]; /* fs_cs 情報バッファのリスト */
    	int32_t	 *fs_maxcluster;/* 各シリンダグループの最大クラスタ */
    	int32_t	 fs_cpc;	/* postbl 内のサイクルあたりのシリンダ */
    	int16_t	 fs_opostbl[16][8];	/* 旧回転ブロックリストヘッド */
    	int32_t	 fs_sparecon[50];	/* 将来のために予約された定数 */
    	int32_t	 fs_contigsumsize;	/* クラスタ総括配列の大きさ */
    	int32_t	 fs_maxsymlinklen;	/* 内部シンボリックリンクの最大長 */
    	int32_t	 fs_inodefmt;	/* ディスク上の inode のフォーマット */
    	u_int64_t fs_maxfilesize;/* 最大表示可能ファイルサイズ */
    	int64_t	 fs_qbmask;	/* ~fs_bmask - 64 ビットサイズで使う */
    	int64_t	 fs_qfmask;	/* ~fs_fmask - 64 ビットサイズで使う */
    	int32_t	 fs_state;	/* fs_clean フィールドが有効であることを示す */
    	int32_t	 fs_postblformat;/* 位置レイアウトテーブルのフォーマット */
    	int32_t	 fs_nrpos;	/* 回転位置の数 */
    	int32_t	 fs_postbloff;	/* (u_int16) 回転ブロックリストヘッド */
    	int32_t	 fs_rotbloff;	/* (u_int8) 各回転毎のブロック */
    	int32_t	 fs_magic;	/* マジックナンバ */
    	u_int8_t fs_space[1];	/* 各回転毎のブロックのリスト */
    /* 実際はもっと長い */
    };
    /*
     * ファイルシステム識別
     */
    #define	FS_MAGIC	0x011954   /* fast ファイルシステムのマジックナンバ */
    #define	FS_OKAY		0x7c269d38 /* スーパブロックチェックサム */
    #define FS_42INODEFMT	-1	   /* 4.2BSD inode フォーマット */
    #define FS_44INODEFMT	2	   /* 4.4BSD inode フォーット
     */
    /*
     * 最適化のための選択
     */
    #define FS_OPTTIME	0	/* 最小アロケーション時間 */
    #define FS_OPTSPACE	1	/* 最小ディスクフラグメンテーション */
    /*
     * 回転レイアウトテーブルフォーマットタイプ
     */
    #define FS_42POSTBLFMT		-1  /* 4.2BSD 回転テーブルフォーマット */
    #define FS_DYNAMICPOSTBLFMT	1   /* 動的回転テーブルフォーマット */

各ディスクドライブはいくつかのファイルシステムを含んでいます。 1 つのファイルシステムは、いくつかのシリンダグループから成ります。 各シリンダグループには inode とデータがあります。

ファイルシステムは、シリンダグループを順番に記述するスーパブロックに よって記述されています。 スーパブロックは重要なデータであり、壊滅的な損失から守るために 各シリンダグループに複製されています。 これはファイルシステム作成時に行なわれ、重要なスーパブロックデータは 変更されないので、特に惨事がふりかからなければ、複製が参照される 必要はありません。

inode に保存されたアドレスによって、`ブロック' のフラグメントの 位置を決めることができます。 ファイルシステムブロックのほとんどは MAXBSIZE ですが、2, 4, 8 個に分けることが自由にでき、 それぞれを位置指定できます。 これらの断片は DEV_BSIZE または DEV_BSIZE 単位の倍数であれば良いのです。

大きなファイルは、非常に大きなデータブロックからなります。 ディスクスペースの過度の浪費を避けるために、小さなファイルの 最後のデータブロックは、 大きなブロックのフラグメントが必要な数だけ配置されます。 ファイルシステムフォーマットは、そのようなフラグメント (大きなブロックを 分割した一片) の 1 つへのポインタだけを保持します。 そのようなフラグメントの大きさは、 inode にある情報から決定することができ、 blksize(fs, ip, lbn) マクロが使っています。

ファイルシステムは、提供可能な空きをフラグメントレベルで記録します。 つまり、ブロックの空きを決定するために、フラグメントを並べて調べます。

root inode は、ファイルシステムのおおもとです。 inode 0 は、通常の目的では使われず、歴史的に バッドブロックは inode 1 にリンクされます。 したがって root inode は、2 です (inode 1 は、もはやこの目的では使われませんが、 多くのダンプテープがこの仮定をしているので、それについては変更できません)。

fs_minfree 要素は、空いているファイルシステムブロックの最低許容割合を与えます。 空きリストがこのレベル以下になった場合、スーパユーザ だけがブロックの確保を続けることができます。 fs_minfree 要素は、空きブロックの予備が必要ないと思われたら 0 にセットしても かまいませんが、ファイルシステムが 90% 以上詰まった状態で動いているときには、 かなり性能が低下するでしょう。 そのためデフォルトの fs_minfree の値は 10% になっています。

経験上、ブロックフラグメンテーションと 90% 使用中のディスク全体の利用 の兼ね合いが最も良いのは、フラグメンテーション 8 のときです。 そのためデフォルトのフラグメントサイズはブロックサイズの 8 倍になっています。

要素 fs_optim はファイルシステムがブロックを確保するのに要する時間を最小に しようとするか、それともディスク上の領域のフラグメンテーションを最小に しようとするかを指定します。 fs_minfree (上記参照) の値が 10% より小さい場合は、ファイルシステム は空間の最適化をデフォルトとし、 完全な大きさのブロックがなくならないようにします。 minfree の値が 10% と等しいかそれ以上の場合には、フラグメンテーション が問題とはなりにくく、ファイルシステムは時間の最適化をデフォルトに します。

シリンダグループに関連した制限: 連続したブロックを最小の回転遅れで配置することができるよう、 各シリンダは異なる回転位置での利用可能なブロック数を保持し続けます。 デフォルトでは回転位置を 8 分割で表し、このときの総括情報の分解能は 典型的な 3600 rpm のドライブで 2ms になります。

要素 fs_rotdelay は、同一シリンダ上で別のディスク転送を開始する 最小ミリ秒数を与えます。 これは、あるファイル中のディスクブロックの周回の中での最適な配置を 決定するのに使われます。 デフォルトの fs_rotdelay の値は 2ms です。

各ファイルシステムは、静的に割り当てられた数の inode を持っています。 inode は、ディスク空間あたり NBPI バイト確保されます。 inode を配置する戦略は、極端に保守的です。

MINBSIZE が許される最小のブロックサイズです。 MINBSIZE が 4096 では、2 段までの(ブロック)間接参照を使って 2^32 の大きさのファイルを作ることができます。 MINBSIZE は、シリンダグループブロックを保持するのに十分な大きさでなければ なりません。 したがって (構造体 cg) への変更は大きさを MINBSIZE 以内にしておかなければなりません。 スーパブロックは決して SBSIZE の大きさ以上ではないということに注意して下さい。

ファイルシステムがマウントされているパス名は、 fs_fsmnt に保持されます。 MAXMNTLEN は、この名前のためにスーパブロックに割り当てられた領域の量を定義します。 ファイルシステム毎の総括情報の量の上限は、 MAXCSBUFS により定義されています。 4096 バイトブロックサイズの場合では、これは現在最大 200 万シリンダ分 用意されています。

それぞれのシリンダグループ情報は、先頭のシリンダグループ データブロックから確保されたブロックに要約されます。 これらのブロックはスーパブロックに加えて fs_csaddr ( fs_cssize の大きさ) から読み込まれます。

注意: sizeof(struct csum) は fs_cs() マクロを動かすために 2 のべき乗でなければなりません。

ファイルシステムのスーパブロック: 周回レイアウトテーブルの大きさは、スーパブロックが SBSIZE の大きさを持つことにより制限されています。 これらのテーブルの大きさは、ファイルシステムのブロックサイズに 逆比例 します。 セクタサイズが 2 のべき乗でないときには、周回パターンを (fs_cpc) だけ繰り返すまでに含まれるシリンダ数が増加するので、 同様にテーブルの大きさも増加します。 周回レイアウトテーブルの大きさは、 (struct fs) に残っているバイト数から割り出されます。

シリンダグループあたりのデータブロック数は、シリンダグループが たかだか 1 ブロックであるので、制限されています。 inode と空きブロックテーブルは、単一ブロックから シリンダグループ構造体 (struct cg) のための領域を除いた残りにぴったり合っていなければなりません。

Inode: inode は、 UNIX ファイルシステム内のすべてのファイルに関する動作の中心です。 各アクティブなファイル、カレントディレクトリ、マウントされたファイル、 テキストファイル、root には、それぞれユニークな inode が割り当てられます。 inode はそのデバイス / i 番号によって `名前付け' されています。 詳しくはインクルードファイル <ufs/ufs/inode.h> を参照して下さい。

歴史
filsys と名付けられたスーパブロック構造は AT&T UNIX から登場しました。このマニュアルで記述されているファイルシステムは 4.2BSD から登場しました。