Linux の EXT シリーズファイルシステムフォーマットの詳細な説明

Linux の EXT シリーズファイルシステムフォーマットの詳細な説明

Linux ファイルシステム

一般的なハードディスクは上図のとおりです。各ディスクは複数のトラックに分割され、各トラックは複数のセクターに分割され、各セクターは 512 バイトで、ハードディスクの最小のストレージ単位です。ただし、オペレーティングシステムレベルでは、複数のセクターがブロックに結合され、これがオペレーティングシステムのデータストレージの最小単位です。通常、8 つのセクターが 4K バイトのブロックを形成します。
Linux ファイル システムの場合、考慮すべき点がいくつかあります。

  • ファイルをブロック単位で保存できるように、ファイル システムは厳密な編成形式を持つ必要があります。
  • ファイル システムには、ファイルの複数のブロックが配置されている場所を見つけやすくするためのインデックス領域が必要です。
  • 最近頻繁に読み書きされるファイルがある場合は、キャッシュ層が必要です
  • ファイルは管理と検索を容易にするためにフォルダに整理する必要があります
  • Linux カーネルは、どのファイルがどのプロセスによって開かれ、使用されているかを追跡するために、独自のメモリ内に一連のデータ構造を保持します。

Linux 内のすべてはファイルであり、次の種類のファイルがあります (ls -l 結果の最初の識別子からわかるように)。

  • - 通常のファイルを示します
  • dはフォルダを示す
  • cはキャラクタデバイスファイルを表す
  • bはブロックデバイスファイルを示します
  • sはソケットファイルを示します
  • lはソフトリンクを示す

iノードとブロックストレージ

EXT シリーズ形式を例に、ハードディスク上でファイルがどのように存在するかを見てみましょう。まず、ファイルはブロックに分割され、ハードディスク上に分散されます。これらのブロックを見つけてファイルのメタデータを記録するには、インデックス構造が必要です。これが inode です。i はインデックスを表します。 inode データ構造は次のとおりです。

構造体ext4_inode{
 __le16 i_mode; /* ファイルモード */
 __le16 i_uid; /* 所有者UIDの下位16ビット */
 __le32 i_size_lo; /* バイト単位のサイズ */
 __le32 i_atime; /* アクセス時間 */
 __le32 i_ctime; /* iノードの変更時刻 */
 __le32 i_mtime; /* 変更時刻 */
 __le32 i_dtime; /* 削除時刻 */
 __le16 i_gid; /* グループ ID の下位 16 ビット */
 __le16 i_links_count; /* リンク数 */
 __le32 i_blocks_lo; /* ブロック数 */
 __le32 i_flags; /* ファイルフラグ */
 ユニオン {
  構造体{
   __le32 l_i_バージョン;
  }linux1;
  構造体{
   __u32 h_i_トランスレータ;
  } ハード1;
  構造体{
   __u32 m_i_reserved1;
  } マシックス1;
 } osd1; /* OS依存1 */
 __le32 i_block[EXT4_N_BLOCKS];/* ブロックへのポインタ */
 __le32 i_generation; /* ファイルバージョン(NFS用) */
 __le32 i_file_acl_lo; /* ファイル ACL */
 __le32 i_size_high;
 __le32 i_obso_faddr; /* 廃止されたフラグメントアドレス */
 ユニオン {
  構造体{
   __le16 l_i_blocks_high; /* l_i_reserved1 でした */
   __le16 l_i_file_acl_high;
   __le16 l_i_uid_high; /* これら 2 つのフィールド */
   __le16 l_i_gid_high; /* 予約済み2[0] */
   __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
   __le16 l_i_予約済み;
  }linux2;
  構造体{
   __le16 h_i_reserved1; /* ext4 で削除された廃止されたフラグメント番号/サイズ */
   __u16 h_i_mode_high;
   __u16 h_i_uid_high;
   __u16 h_i_gid_high;
   著者:
  } ハード2;
  構造体{
   __le16 h_i_reserved1; /* ext4 で削除された廃止されたフラグメント番号/サイズ */
   __le16 m_i_file_acl_high;
   __u32 m_i_reserved2[2];
  } マシックス2;
 } osd2; /* OS依存2 */
 __le16 i_extra_isize;
 __le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */
 __le32 i_ctime_extra; /* 追加変更時間 (nsec << 2 | エポック) */
 __le32 i_mtime_extra; /* 追加の変更時間(nsec << 2 | エポック) */
 __le32 i_atime_extra; /* 追加アクセス時間 (nsec << 2 | エポック) */
 __le32 i_crtime; /* ファイル作成時刻 */
 __le32 i_crtime_extra; /* 追加のファイル作成時間 (nsec << 2 | エポック) */
 __le32 i_version_hi; /* 64 ビット版の上位 32 ビット */
 __le32 i_projid; /* プロジェクトID */
};

このうち、__le32 i_block[EXT4_N_BLOCKS]はデータブロックへの参照を格納します。EXT4_N_BLOCKSは次のように定義されます。

#EXT4_NDIR_BLOCKS 12 を定義する
#定義 EXT4_IND_BLOCK EXT4_NDIR_BLOCKS
#定義 EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1)
#EXT4_TIND_BLOCK (EXT4_DIND_BLOCK + 1) を定義します
#EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1) を定義します

ext2 および ext3 では、i_block の最初の 12 項目にはデータ ブロックへの直接参照が格納され、13 番目の項目には間接ブロックへの参照が格納され、データ ブロックの位置は間接ブロックに格納されます。同様に、14 番目の項目には 2 次間接ブロックの位置が格納され、15 番目の項目には 3 次間接ブロックの位置が格納されます (次の図を参照)。

大きなファイルの場合、対応するブロックを見つけるためにハードディスクを複数回読み取る必要があることは容易に理解できます。この問題を解決するために、ext4 ではエクステント ツリーが提案されています。基本的な考え方は、各ブロックの位置を 1 つずつ記録するのではなく、連続するブロックを開始位置とブロック数で表すことで、ストレージ スペースを節約することです。まず、i_block 内の元の 415 = 60 バイトのスペースを、エクステント ヘッダー (ext4_extent_header) と 4 つのエクステント エントリ (ext4_extent) に置き換えます。これは、ext4_extent_header と ext4_extent の両方が 12 バイトを占めるためです。 ee_len の最初のビットは初期化されているかどうかを判断するために使用されるため、最大 32K の数値を保存することもできます。したがって、エクステント エントリには最大 32K4K=128M のデータが保存できます。ファイルが 4128M=512M より大きい場合、またはファイルが 4 つ以上の連続していないブロックに保存されている場合は、inode の i_block 構造を拡張する必要があります。そのエクステントエントリは、ext4_extent から 4K バイトのブロックを指す ext4_extent_idx 構造に変更する必要があります。ヘッダーが占める 12 バイトを除いて、340 個の ext4_extent を保存でき、保存できるデータの最大量は 340128M=42.5G です。このインデックス構造は、ファイルが連続したブロックに保存される場合に非常に効率的であることがわかります。

構造体 ext4_extent_header {
 __le16 eh_magic; /* ext4 エクステント識別子: 0xF30A */
 __le16 eh_entries; /* 現在のレベル内の有効なノードの数*/
 __le16 eh_max; /* 現在のレベルのノードの最大数*/
 __le16 eh_depth; /* ツリーの現在のレベルの深さ。0 はリーフ ノード、つまりデータ ノード、>0 はインデックス ノードを表します*/
 __le32 eh_世代; 
}
構造体ext4_extent{
 __le32 ee_block; /* エクステントの開始ブロック論理番号*/
 __le16 ee_len; /* エクステントに含まれるブロックの数*/
 __le16 ee_start_hi; /*エクステント開始ブロックの物理アドレスの上位16ビット*/
 __le32 ee_start_lo; /*エクステント開始ブロックの物理アドレスの下位32ビット*/
}; //データノードのextent_body形式 struct ext4_extent_idx {
 __le32 ei_block; /* インデックスがカバーするファイル範囲の開始ブロックの論理シーケンス番号*/
 __le32 ei_leaf_lo; /* 次のレベルエクステントのブロックの物理アドレスの下位 32 ビットを格納します */ 
 __le16 ei_leaf_hi; /* 次のレベルのエクステントを格納するブロックの物理アドレスの上位 16 ビット */
 __u16 ei_未使用;

}; //インデックスノードのextent_body形式

/var/log/messages ファイルの例を以下に示します。

Inode ビットマップとブロック ビットマップ

ハード ディスクには、ブロック データと inode を保存するための専用領域があります。ただし、新しいファイルを作成する場合は、どの inode 領域とどのブロックが空であるかを知る必要があります。これには、それぞれ inode ビットマップを保存するために 1 つのブロックを使用し、ブロック ビットマップを保存するために 1 つのブロックを使用する必要があります。各ビットは、占有されている場合は 1、占有されていない場合は 0 です。ただし、ブロックには最大 4K*8=32K ビットが含まれており、最大 32K ブロックのステータスを表すことができるため、大規模なシステムを構築するには、これらのブロックをブロック グループに編成する必要があります。

ハードリンクとソフトリンク

ハード リンクは元のファイルと同じ inode を共有しますが、inode はファイル システムをまたぐことができないため、ハード リンクもファイル システムをまたぐことはできません。

ソフト リンクには独自の inode がありますが、ファイルが開かれると別のファイルを指すため、ファイル システムをまたいで元のファイルが削除されても存在し続ける可能性があります。

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

以下もご興味があるかもしれません:
  • Linux環境でExt3ファイルシステムを使用する
  • Linux で lvm 論理ボリューム パーティションのサイズを調整するチュートリアル (xfs や ext4 などのさまざまなファイル システム用)
  • Linux ファイルシステムの説明: ext4 以降
  • Linux コマンドで mysqladmin Extended-status を使用して、Linux で MySQL の実行ステータスを表示します。

<<:  Vue プロジェクトで axios をカプセル化する方法 (http リクエストの統合管理)

>>:  Linuxターミナルでの一般的なMySQL操作コマンドの詳細な説明

推薦する

レム適応の一般的なパッケージ3つについて

序文以前、rem適応についての記事を書きましたが、具体的なパッケージは紹介しませんでした。今日は、よ...

Linux ファイル管理コマンド例の分析 [表示、閲覧、統計など]

この記事では、Linux ファイル管理コマンドについて例を挙げて説明します。ご参考までに、詳細は以下...

VMwareがモジュールディスクを早期に開けない場合の解決策の詳細な説明

VMWare (Virtual Machine ware) は、「仮想 PC」ソフトウェア会社です。...

Linuxでpyファイルを直接実行する方法

1. まずファイルを作成します(ファイルを配置するディレクトリにcdします) myTest.py を...

Vue はトークンを取得してトークン ログインのサンプル コードを実装します

ログイン認証にトークンを使用する考え方は次のとおりです。 1. 初めてログインする場合、フロントエン...

商品クエリ機能を実現するJavaScript

この記事の例では、商品検索機能を実現するためのJavaScriptの具体的なコードを参考までに共有し...

MySQLの高性能最適化スキルの概要

データベースコマンド仕様すべてのデータベース オブジェクト名には小文字を使用し、アンダースコアで区切...

MySQL 5.7 mysql コマンドラインクライアントの使用コマンドの詳細

MySQL 5.7コマンドを使用するMySQLコマンドラインクライアント1. パスワードを入力してく...

CSS導入方法4つのまとめ(共有)

1. インライン参照:ラベルに直接使用されるが、メンテナンスコストが高い スタイル='フォ...

JSで実施された機雷掃海プロジェクトの概要

この記事では、JS掃海プロジェクトの概要を参考までに紹介します。具体的な内容は次のとおりです。プロジ...

ウェブページ上の写真プレビューナビゲーションを設計するためのヒント

<br />ナビゲーションとは、ウェブサイトの上部にあることが多いナビゲーション バーの...

Alibaba Cloud に MySQL データベースをインストールするときに発生する 2002 エラーを解決する方法

データベースのインストール中に次のエラーが発生しました: 解決策は次のとおりです。 1. binディ...

iframeを透明にするパラメータ

<iframe src="./ads_top_tian.html" all...

Linux コマンドラインのクイックヒント: ファイルの検索方法

私たちのコンピューターには、ディレクトリ、写真、ソース コードなどのファイルが保存されています。たく...

3Dカルーセル効果を実現するjs

この記事では、3Dカルーセル効果をjsで実装するための具体的なコードを参考までに共有します。具体的な...