FS(5) | FreeBSD File Formats Manual | FS(5) |
名称
fs, inode — ファイルシステムボリュームの形式書式
#include < sys/param.h>#include < ufs/ffs/fs.h>
#include < sys/types.h>
#include < sys/lock.h>
#include < sys/extattr.h>
#include < sys/acl.h>
#include < ufs/ufs/quota.h>
#include < ufs/ufs/dinode.h>
#include < ufs/ufs/extattr.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]; /* ユニークな fs 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; /* fs のシリンダ数 */ 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; /* fs がクリーンであるフラグ */ int8_t fs_ronly; /* 読み込み専用でマウントされたフラグ */ int8_t fs_old_flags; /* 古い FS_ フラグ */ u_char fs_fsmnt[MAXMNTLEN]; /* マウント場所の名前 */ u_char fs_volname[MAXVOLLEN]; /* ボリューム名 */ uint64_t fs_swuid; /* システムワイドの UID */ int32_t fs_pad; /* fs_swuid のアラインメント用 */ /* これらのフィールドは、現在のブロックの配置情報を保持する */ int32_t fs_cgrotor; /* 最後に検索された cg */ void *fs_ocsp[NOCSPTRS]; /* 詰め物; fs_cs バッファのリスト だった */ uint8_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_unrefs; /* 参照されない inode の数 */ int64_t fs_sparecon64[16]; /* 古いローテーションブロックリスト ヘッド */ 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; /* fs_bsize の使用のための実 cg サイズ を格納 */ int32_t fs_sparecon32[26]; /* 将来の定数のための予約 */ int32_t fs_flags; /* 後述の FS_ フラグ参照 */ int32_t fs_contigsumsize; /* クラスタ総括配列の大きさ */ int32_t fs_maxsymlinklen; /* 内部シンボリックリンクの最大長 */ int32_t fs_old_inodefmt; /* ディスク上の inode の形式 */ uint64_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 ffs のマジックナンバ */ #define FS_UFS2_MAGIC 0x19540119 /* UFS2 ffs のマジックナンバ */ #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 は、シリンダグループブロックを保持するのに十分な大きさでなければなりません。したがって ( struct 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> を参照して下さい。
外部属性の形式は、次の extattr 構造体によって定義されています:
struct extattr { int32_t ea_length; /* この属性の長さ */ int8_t ea_namespace; /* この属性の名前空間 */ int8_t ea_contentpadlen; /* 属性の終りのパディング */ int8_t ea_namelength; /* 属性の名前の長さ */ char ea_name[1]; /* ヌル文字で終了して属性の名前 */ /* 拡張された属性の内容が続く */ };
いくつかのマクロが、これらの構造体を操作するために定義されています。各マクロは、extattr 構造体へのポインタを取ります。
- EXTATTR_NEXT(eap)
- eap に続き、次の拡張属性へのポインタを返します。
- EXTATTR_CONTENT(eap)
- eap によって参照される拡張属性の内容へのポインタを返します。
- EXTATTR_CONTENT_SIZE(eap)
- eap によって参照される拡張属性の内容のサイズを返します。
- EXTATTR_SET_LENGTHS(eap, size)
- 拡張属性の構造体の ea_length, ea_namelength と ea_contentpadlen を計算して、設定するために属性名を初期化した後の属性内容のサイズで呼び出します。
次のコードは、ACL を識別します:
if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM && !strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME) { aclp = EXTATTR_CONTENT(eap); acllen = EXTATTR_CONTENT_SIZE(eap); ... }
次のコードは、構造体 mygif: のコピーを含む拡張属性を作成します:
eap->ea_namespace = EXTATTR_NAMESPACE_USER; strcpy(eap->ea_name, "filepic.gif"); EXTATTR_SET_LENGTHS(eap, sizeof(struct mygif)); memcpy(EXTATTR_CONTENT(eap), &mygif, sizeof(struct mygif));
歴史
filsys と名付けられたスーパブロック構造は、 Version 6 AT&T UNIX で登場しました。このマニュアルで記述されているファイルシステムは、 4.2BSD で登場しました。October 31, 2006 | FreeBSD |