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 セクタから始まり、そこには 大きさが SBLOCKSIZE である スーパブロック があります。 ファイル <ufs/ffs/fs.h> にある以下の構造体は、スーパブロックを記述しています。

    /*
     * FFS ファイルシステムのスーパブロック
     */
    struct fs {
    	int32_t	 fs_firstfield;	   /* 内部スーパブロック用に使われる、歴史的 */
    	int32_t	 fs_unused_1;      /*     FS リンクリスト */
    	int32_t	 fs_sblkno;        /* fs 内スーパブロックオフセット */
    	int32_t	 fs_cblkno;        /* fs 内シリンダブロックオフセット */
    	int32_t	 fs_iblkno;        /* fs 内 inode ブロックオフセット */
    	int32_t	 fs_dblkno;        /* cg 後の最初のデータのオフセット */
    	int32_t	 fs_old_cgoffset;  /* シリンダ内のシリンダグループオフセット */
    	int32_t	 fs_old_cgmask;    /* mod fs_ntrak の計算に使われる */
    	int32_t  fs_old_time;      /* 最後に書き込まれた時刻 */
    	int32_t	 fs_old_size;      /* fs 内のブロック数 */
    	int32_t	 fs_old_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_old_rotdelay;  /* 最適な次ブロックのための ms 数 */
    	int32_t	 fs_old_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_spare1[2];     /* 古い fs_csmask */
    	                           /* 古い fs_csshift */
    	int32_t	 fs_nindir;        /* NINDIR の値 */
    	int32_t	 fs_inopb;         /* INOPB の値 */
    	int32_t	 fs_old_nspf;      /* NSPF の値*/
    /* 別のコンフィギュレーションパラメータ */
    	int32_t	 fs_optim;         /* 最適化の選択、以下を参照 */
    	int32_t	 fs_old_npsect;    /* 予備を含む、トラックあたりセクタ数 */
    	int32_t	 fs_old_interleave; /* ハードウェアセクタインタリーブ */
    	int32_t	 fs_old_trackskew; /* トラックあたりのセクタ 0 スキュー */
    	int32_t	 fs_id[2];         /* ユニークなファイルシステム ID */
    /* シリンダグループの数とサイズにより決められるサイズ */
    	int32_t	 fs_old_csaddr;	   /* シリンダグループ総括領域のブロックアドレス */
    	int32_t	 fs_cssize;        /* シリンダグループ総括領域のサイズ */
    	int32_t	 fs_cgsize;        /* シリンダグループサイズ */
    	int32_t	 fs_spare2;        /* 古い fs_ntrak */
    	int32_t	 fs_old_nsect;     /* トラックあたりのセクタ数 */
    	int32_t  fs_old_spc;       /* シリンダあたりのセクタ数 */
    	int32_t	 fs_old_ncyl;      /* ファイルシステムのシリンダ数 */
    	int32_t	 fs_old_cpg;       /* グループあたりのシリンダ数 */
    	int32_t	 fs_ipg;           /* グループあたりの inode 数 */
    	int32_t	 fs_fpg;           /* グループあたりのブロック数 * fs_frag */
    /* このデータはクラッシュ後に再計算されなければならない */
    	struct	csum fs_old_cstotal; /* シリンダ総括情報 */
    /* 以下のフィールドはマウント時にクリアされる */
    	int8_t   fs_fmod;          /* スーパブロック変更フラグ */
    	int8_t   fs_clean;         /* ファイルシステムがクリーンであるフラグ */
    	int8_t 	 fs_ronly;         /* 読み込み専用でマウントされたフラグ */
    	int8_t   fs_old_flags;     /* 古い FS_ フラグ */
    	u_char	 fs_fsmnt[MAXMNTLEN]; /* マウント場所の名前 */
    	u_char	 fs_volname[MAXVOLLEN]; /* ボリューム名 */
    	u_int64_t fs_swuid;        /* システムワイドの UID  */
    	int32_t  fs_pad;           /* fs_swuid のアラインメント用 */
    /* これらのフィールドは現在のブロックの配置情報を保持する */
    	int32_t	 fs_cgrotor;       /* 最後に検索された cg */
    	void 	*fs_ocsp[NOCSPTRS]; /* パッド。fs_cs バッファのリストだった */
    	u_int8_t *fs_contigdirs;   /* 連続割り当てされた dir 数 */
    	struct	csum *fs_csp;      /* fs_cs 情報バッファのリスト */
    	int32_t	*fs_maxcluster;    /* 各シリンダグループの最大クラスタ */
    	u_int	*fs_active;        /* fs トラック用に、スナップショットが使用 */
    	int32_t	 fs_old_cpc;       /* postbl 内のサイクルあたりのシリンダ */
    	int32_t	 fs_maxbsize;      /* 最大のブロック化係数 */
    	int64_t	 fs_sparecon64[17]; /* 古いローテーションブロックリストヘッド */
    	int64_t	 fs_sblockloc;     /* 標準のスーパブロックのバイトオフセット */
    	struct	csum_total fs_cstotal;  /* シリンダ総括情報 */
    	ufs_time_t fs_time;        /* 最後に書き込まれた時刻 */
    	int64_t	 fs_size;          /* fs 中のブロック数 */
    	int64_t	 fs_dsize;         /* fs 中のデータブロック数 */
    	ufs2_daddr_t fs_csaddr;    /* シリンダグループ総括情報領域のブロックアドレス */
    	int64_t	 fs_pendingblocks; /* 現在開放途中のブロック数 */
    	int32_t	 fs_pendinginodes; /* 現在開放途中の inode 数 */
    	int32_t	 fs_snapinum[FSMAXSNAP]; /* スナップショット inode 数のリスト */
    	int32_t	 fs_avgfilesize;   /* ファイルサイズの平均の期待値 */
    	int32_t	 fs_avgfpdir;      /* ディレクトリあたりのファイル数の期待値 */
    	int32_t	 fs_save_cgsize;   /* 実 cg サイズを保存し、fs_bsize を使用 */
    	int32_t	 fs_sparecon32[26]; /* 将来の定数のための予約 */
    	int32_t  fs_flags;         /* 後述の FS_ フラグ参照 */
    	int32_t	 fs_contigsumsize; /* クラスタ総括配列の大きさ */
    	int32_t	 fs_maxsymlinklen; /* 内部シンボリックリンクの最大長 */
    	int32_t	 fs_old_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_old_postblformat; /* 位置レイアウトテーブルのフォーマット */
    	int32_t	 fs_old_nrpos;     /* 回転位置の数 */
    	int32_t	 fs_spare5[2];     /* 古い fs_postbloff */
    	                           /* 古い fs_rotbloff */
    	int32_t	 fs_magic;         /* マジックナンバ */
    };
    /*
     * ファイルシステム識別
     */
    #define	FS_UFS1_MAGIC	0x011954    /* UFS1 ファストファイルシステムのマジックナンバ */
    #define	FS_UFS2_MAGIC	0x19540119  /* UFS2 ファストファイルシステムのマジックナンバ */
    #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	/* 最小ディスクフラグメンテーション */

各ディスクドライブはいくつかのファイルシステムを含んでいます。 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_old_rotdelay は、同一シリンダ上で別のディスク転送を開始する 最小ミリ秒数を与えます。 これは、あるファイル中のディスクブロックの周回の中での最適な配置を 決定するのに使われます。 デフォルトの fs_old_rotdelay の値は 2ms です。

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

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

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

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

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

ファイルシステムのスーパブロック: 周回レイアウトテーブルの大きさは、スーパブロックが SBLOCKSIZE の大きさを持つことにより制限されています。 これらのテーブルの大きさは、ファイルシステムのブロックサイズに 逆比例 します。 セクタサイズが 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 から登場しました。