ext4 通用資訊

Ext4 是 ext3 檔案系統的高階版本,它包含可擴充套件性和可靠性增強功能,以支援大型檔案系統(64 位),以適應不斷增加的磁碟容量和最先進的功能要求。

郵件列表: linux-ext4@vger.kernel.org 網站: http://ext4.wiki.kernel.org

快速使用說明

注意:有關開始使用 ext4 的更廣泛資訊可以在 ext4 wiki 站點找到,網址為:http://ext4.wiki.kernel.org/index.php/Ext4_Howto

  • 使用 ext4 檔案系統型別建立一個新的檔案系統

    # mke2fs -t ext4 /dev/hda1

    或者配置現有的 ext3 檔案系統以支援 extent

    # tune2fs -O extents /dev/hda1

    如果檔案系統是使用 128 位元組的 inode 建立的,則可以透過以下方式將其轉換為使用 256 位元組以獲得更高的效率

    # tune2fs -I 256 /dev/hda1

  • 掛載

    # mount -t ext4 /dev/hda1 /wherever

  • 當與其他檔案系統比較效能時,始終嘗試多種工作負載非常重要;通常,工作負載引數的細微變化會完全改變檔案系統相比其他檔案系統的排名。 當與 ext3 進行比較時,請注意 ext4 預設啟用寫入屏障,而 ext3 預設不啟用寫入屏障。 因此,透過 `-o barriers=[0|1]` 掛載選項為 ext3 和 ext4 檔案系統顯式指定是否啟用屏障以進行公平比較非常有用。 在調整 ext3 以獲得最佳基準測試結果時,通常值得嘗試更改資料日誌模式; `-o data=writeback` 對於某些工作負載可能會更快。(但請注意,以 data=writeback 掛載執行時,在發生不乾淨的關機時,可能會在最近寫入的檔案中留下過時的資料,這在某些情況下可能是安全風險。)使用大型日誌配置檔案系統也有助於元資料密集型工作負載。

特點

當前可用

  • 能夠使用 > 16TB 的檔案系統(e2fsprogs 支援尚未可用)

  • extent 格式減少了元資料開銷(RAM、IO 用於訪問、事務)

  • extent 格式在磁碟損壞的情況下更健壯,因為使用了 magic,

  • 樹中的內部冗餘

  • 改進的檔案分配(多塊分配)

  • 取消 i_links_count 施加的 32000 個子目錄限制[1]

  • mtime、atime、ctime、建立時間的 nsec 時間戳

  • 磁碟上的 inode 版本欄位(NFSv4、Lustre)

  • 透過 uninit_bg 功能減少 e2fsck 時間

  • 用於穩健性和效能的日誌校驗和

  • 持久檔案預分配(例如,用於流媒體、資料庫)

  • 能夠透過 flex_bg 功能將點陣圖和 inode 表打包到更大的虛擬組中

  • 大檔案支援

  • 使用 flex_bg 透過大型虛擬塊組進行 inode 分配

  • 延遲分配

  • 大塊(高達頁面大小)支援

  • JBD2 和 ext4 中高效的新 ordered 模式(避免使用緩衝區頭來強制排序)

  • 不區分大小寫的檔名查詢

  • 基於檔案的加密支援 (fscrypt)

  • 基於檔案的完整性支援 (fsverity)

[1] 塊大小為 1k 的檔案系統可能會受到目錄雜湊樹的最大深度為 2 的限制。

不區分大小寫的檔名查詢

不區分大小寫的檔名查詢功能在每個目錄的基礎上都支援,允許使用者在同一檔案系統中混合使用不區分大小寫和區分大小寫的目錄。 它透過翻轉空目錄的 +F inode 屬性來啟用。 不區分大小寫的字串匹配操作僅在我們知道文字如何在位元組序列中編碼時才定義。 因此,為了啟用不區分大小寫的目錄,檔案系統必須具有 casefold 功能,該功能儲存使用的檔案系統範圍的編碼模型。 預設情況下,採用的字元集是最新版本的 Unicode(在撰寫本文時為 12.1.0),以 UTF-8 形式編碼。 比較演算法透過將字串規範化為 Unicode 定義的規範分解形式來實現,然後進行位元組與位元組的比較。

大小寫感知在磁碟上保留名稱,這意味著 userspace 提供的檔名與實際寫入磁碟的內容逐位元組匹配。 因此,核心使用的 Unicode 規範化格式是內部表示,不會暴露給使用者空間或磁碟,但具有 DX 功能的大型不區分大小寫的目錄上使用的磁碟雜湊除外。 在 DX 目錄上,必須使用檔名的大小寫摺疊版本計算雜湊值,這意味著使用的規範化格式實際上會影響目錄條目的儲存位置。

當我們從將檔名視為不透明的位元組序列更改為將其視為編碼的字串時,我們需要解決程式嘗試使用無效名稱建立檔案時會發生什麼情況。 核心中的 Unicode 子系統將如何處理這種情況的決定留給檔案系統,檔案系統透過啟用/停用嚴格模式來選擇其首選行為。 當 Ext4 遇到其中一個字串並且檔案系統不需要嚴格模式時,它會回退到將整個字串視為不透明的位元組序列,這仍然允許使用者對該檔案進行操作,但是不區分大小寫的查詢將無法工作。

選項

掛載 ext4 檔案系統時,接受以下選項:(*) == 預設值

ro

以只讀方式掛載檔案系統。 請注意,即使在以“只讀”方式掛載時,ext4 也會重放日誌(因此會寫入分割槽)。 可以使用掛載選項“ro,noload”來防止寫入檔案系統。

journal_checksum

啟用日誌事務的校驗和。 這將允許 e2fsck 和核心中的恢復程式碼檢測核心中的損壞。 這是一個相容的更改,將被舊核心忽略。

journal_async_commit

提交塊可以寫入磁碟,而無需等待描述符塊。 如果啟用,舊核心將無法掛載裝置。 這將在內部啟用“journal_checksum”。

journal_path=path, journal_dev=devnum

當外部日誌裝置的主/次裝置號已更改時,這些選項允許使用者指定新的日誌位置。 日誌裝置透過編碼在 devnum 中的新主/次裝置號,或者透過裝置的路徑來標識。

norecovery, noload

掛載時不要載入日誌。 請注意,如果檔案系統未乾淨地解除安裝,則跳過日誌重放將導致檔案系統包含可能導致任何問題的任何數量的不一致之處。

data=journal

所有資料都先提交到日誌中,然後再寫入主檔案系統。 啟用此模式將停用延遲分配和 O_DIRECT 支援。

data=ordered (*)

所有資料都被強制直接寫入主檔案系統,然後再將其元資料提交到日誌中。

data=writeback

不保留資料排序,資料可能在其元資料提交到日誌後寫入主檔案系統。

commit=nrsec (*)

此設定將執行中的事務的最大生存期限制為“nrsec”秒。 預設值為 5 秒。 這意味著如果您斷電,您將丟失最新的 5 秒元資料更改(但由於日誌記錄,您的檔案系統不會損壞)。 此預設值(或任何低值)都會損害效能,但它對資料安全有益。 將其設定為 0 將具有與將其保留為預設值(5 秒)相同的效果。 將其設定為非常大的值將提高效能。 請注意,由於延遲分配,即使是較舊的資料也可能在斷電時丟失,因為這些資料的回寫僅在 /proc/sys/vm/dirty_expire_centisecs 中設定的時間後開始。

barrier=<0|1(*)>, barrier(*), nobarrier

這啟用/停用在 jbd 程式碼中使用寫入屏障。 barrier=0 停用,barrier=1 啟用。 這還需要一個可以支援屏障的 IO 堆疊,如果 jbd 在屏障寫入時收到錯誤,它將再次停用併發出警告。 寫入屏障強制執行日誌提交的正確磁碟排序,使易失性磁碟寫入快取可以安全使用,但會降低一些效能。 如果您的磁碟以某種方式進行電池備份,則停用屏障可以安全地提高效能。 掛載選項“barrier”和“nobarrier”也可用於啟用或停用屏障,以與其他 ext4 掛載選項保持一致。

inode_readahead_blks=n

此調整引數控制 ext4 的 inode 表預讀演算法將預讀到緩衝區快取中的最大 inode 表塊數。 預設值為 32 個塊。

bsddf (*)

使“df”的行為類似於 BSD。

minixdf

使“df”的行為類似於 Minix。

debug

額外的除錯資訊將傳送到 syslog。

abort

模擬呼叫 ext4_abort() 的效果以進行除錯。 這通常用於重新掛載已掛載的檔案系統時。

errors=remount-ro

在發生錯誤時以只讀方式重新掛載檔案系統。

errors=continue

在檔案系統錯誤時繼續。

errors=panic

如果發生錯誤,則發生恐慌並停止機器。(這些掛載選項會覆蓋超級塊中指定的錯誤行為,可以使用 tune2fs 進行配置)

data_err=ignore(*)

如果檔案資料緩衝區中發生錯誤,則只打印錯誤訊息。

data_err=abort

如果檔案資料緩衝區中發生錯誤,則中止日誌。

grpid | bsdgroups

新物件的組 ID 為其父物件的組 ID。

nogrpid (*) | sysvgroups

新物件的組 ID 為其建立者的組 ID。

resgid=n

可以使用保留塊的組 ID。

resuid=n

可以使用保留塊的使用者 ID。

sb=

在此位置使用備用超級塊。

quota, noquota, grpquota, usrquota

檔案系統忽略這些選項。 它們僅由配額工具用於識別應啟用配額的卷。 有關更多詳細資訊,請參閱配額工具包中的文件 (http://sourceforge.net/projects/linuxquota)。

jqfmt=<quota type>, usrjquota=<file>, grpjquota=<file>

這些選項告訴檔案系統有關配額的詳細資訊,以便在日誌重放期間可以正確更新配額資訊。 它們取代了上面的配額選項。 有關更多詳細資訊,請參閱配額工具包中的文件 (http://sourceforge.net/projects/linuxquota)。

stripe=n

mballoc 將嘗試用於分配大小和對齊的檔案系統塊數。 對於 RAID5/6 系統,這應該是資料磁碟的數量 * 檔案系統塊中的 RAID 塊大小。

delalloc (*)

將塊分配推遲到 ext4 寫入有問題的塊之前。 這允許 ext4 更有效地做出更好的分配決策。

nodelalloc

停用延遲分配。 當資料從使用者空間複製到頁面快取時(透過 write(2) 系統呼叫),或者當第一次寫入先前未分配的 mmap 頁面時,會分配塊。

max_batch_time=usec

ext4 應等待與同步寫入操作一起批次處理其他檔案系統操作的最長時間。 由於同步寫入操作將強制提交,然後等待 I/O 完成,因此成本不高,並且可以實現巨大的吞吐量,因此我們等待一小段時間,看看是否可以有其他事務可以利用同步寫入。 使用的演算法旨在透過測量完成事務提交所花費的時間(平均)來自動調整磁碟的速度。 將此時間稱為“提交時間”。 如果事務執行的時間小於提交時間,ext4 將嘗試休眠提交時間,看看是否有其他操作會加入事務。 提交時間受 max_batch_time 的限制,預設為 15000us (15ms)。 可以透過將 max_batch_time 設定為 0 來完全關閉此最佳化。

min_batch_time=usec

此引數將提交時間(如上所述)設定為至少 min_batch_time。 它預設為零微秒。 增加此引數可能會提高非常快的磁碟上多執行緒同步工作負載的吞吐量,但會增加延遲。

journal_ioprio=prio

在提交操作期間,kjournald2 提交的 I/O 操作應使用的 I/O 優先順序(從 0 到 7,其中 0 是最高優先順序)。 這預設為 3,這是一個略高於預設 I/O 優先順序的優先順序。

auto_da_alloc(*), noauto_da_alloc

許多損壞的應用程式在使用 fd = open(“foo.new”)/write(fd,..)/close(fd)/ rename(“foo.new”, “foo”) 或更糟糕的模式(fd = open(“foo”, O_TRUNC)/write(fd,..)/close(fd))替換現有檔案時不使用 fsync()。 如果啟用了 auto_da_alloc,ext4 將檢測到透過重新命名和透過截斷模式進行的替換,並強制分配任何延遲分配的塊,以便在下一個日誌提交時,在預設 data=ordered 模式下,新檔案的資料塊將被強制在 rename() 操作提交之前寫入磁碟。 這提供了與 ext3 大致相同的保證級別,並避免了在系統崩潰之前延遲分配的塊被強制寫入磁碟時可能發生的“零長度”問題。

noinit_itable

不要在後臺初始化任何未初始化的 inode 表塊。 安裝 CD 可以使用此功能,以便安裝過程可以儘快完成; 然後,inode 表初始化過程將被推遲到下次解除安裝檔案系統時。

init_itable=n

延遲 itable 初始化程式碼將等待 n 倍於清零上一個塊組的 inode 表所花費的毫秒數。 這最大限度地減少了檔案系統的 inode 表初始化時對系統性能的影響。

discard, nodiscard(*)

控制 ext4 在釋放塊時是否應向底層塊裝置發出 discard/TRIM 命令。 這對於 SSD 裝置和稀疏/精簡配置的 LUN 非常有用,但在進行足夠的測試之前,預設情況下它是關閉的。

nouid32

停用 32 位 UID 和 GID。 這是為了與僅儲存和期望 16 位值的舊核心互操作。

block_validity(*), noblock_validity

這些選項啟用或停用核心內工具,以跟蹤內部資料結構中的檔案系統元資料塊。 這允許多塊分配器和其他例程注意到錯誤或損壞的分配點陣圖,這些錯誤或損壞的分配點陣圖會導致分配與檔案系統元資料塊重疊的塊。

dioread_lock, dioread_nolock

控制 ext4 是否應使用 DIO 讀取鎖定。 如果指定了 dioread_nolock 選項,ext4 將在緩衝區寫入之前分配未初始化的 extent,並在 IO 完成後將 extent 轉換為已初始化。 這種方法允許 ext4 程式碼避免使用 inode 互斥鎖,從而提高了高速儲存上的可擴充套件性。 但是,這不適用於資料日誌記錄,並且 dioread_nolock 選項將被忽略併發出核心警告。 請注意,dioread_nolock 程式碼路徑僅用於基於 extent 的檔案。 由於此選項的限制,預設情況下它是關閉的(例如 dioread_lock)。

max_dir_size_kb=n

這限制了目錄的大小,以便任何嘗試將其擴充套件到超出指定限制(以千位元組為單位)的操作都會導致 ENOSPC 錯誤。 這在記憶體受限的環境中非常有用,在這些環境中,非常大的目錄會導致嚴重的效能問題,甚至會引發記憶體不足殺手。(例如,如果只有 512mb 的記憶體可用,則 176mb 的目錄可能會嚴重限制系統的風格。)

i_version

啟用 64 位 inode 版本支援。 預設情況下,此選項處於關閉狀態。

dax

使用直接訪問(無頁面快取)。 請參閱 檔案的直接訪問。 請注意,此選項與 data=journal 不相容。

inlinecrypt

如果可能,使用 blk-crypto 框架而不是檔案系統層加密來加密/解密加密檔案的內容。 這允許使用內聯加密硬體。 磁碟格式不受影響。 有關更多詳細資訊,請參閱 內聯加密

資料模式

有 3 種不同的資料模式

  • writeback 模式

    在 data=writeback 模式下,ext4 根本不記錄資料。 此模式提供與 XFS、JFS 和 ReiserFS 在其預設模式下(元資料日誌記錄)相似級別的日誌記錄。 崩潰 + 恢復可能會導致崩潰前不久寫入的檔案中出現錯誤資料。 此模式通常會提供最佳的 ext4 效能。

  • ordered 模式

    在 data=ordered 模式下,ext4 僅正式記錄元資料,但它在邏輯上將與資料更改相關的元資料資訊與資料塊分組到一個稱為事務的單元中。 當需要將新元資料寫入磁碟時,首先寫入關聯的資料塊。 通常,此模式的效能略低於 writeback,但明顯快於 journal 模式。

  • journal 模式

    data=journal 模式提供完整的資料和元資料日誌記錄。 所有新資料首先寫入日誌,然後寫入其最終位置。 如果發生崩潰,可以重放日誌,使資料和元資料都處於一致狀態。 除了需要同時從磁碟讀取和寫入資料時,此模式是最慢的,在這種情況下,它優於所有其他模式。 啟用此模式將停用延遲分配和 O_DIRECT 支援。

/proc 條目

有關已掛載的 ext4 檔案系統的資訊可以在 /proc/fs/ext4 中找到。 每個已掛載的檔案系統在 /proc/fs/ext4 中都有一個基於其裝置名稱的目錄(即,/proc/fs/ext4/hdc 或 /proc/fs/ext4/dm-0)。 每個按裝置目錄中的檔案如下表所示。

/proc/fs/ext4/<devname> 中的檔案

mb_groups

空閒塊的多塊分配器夥伴快取的詳細資訊

/sys 條目

有關已掛載的 ext4 檔案系統的資訊可以在 /sys/fs/ext4 中找到。 每個已掛載的檔案系統在 /sys/fs/ext4 中都有一個基於其裝置名稱的目錄(即,/sys/fs/ext4/hdc 或 /sys/fs/ext4/dm-0)。 每個按裝置目錄中的檔案如下表所示。

/sys/fs/ext4/<devname> 中的檔案

(另請參見 ABI 檔案測試/sysfs-fs-ext4

delayed_allocation_blocks

此檔案是隻讀的,顯示了頁面快取中已損壞的塊數,但尚未分配其在檔案系統中的位置。

inode_goal

調整引數(如果非零)控制 inode 分配器使用的目標 inode,優先於所有其他分配啟發式。 這僅用於除錯,在生產系統上應為 0。

inode_readahead_blks

調整引數,用於控制 ext4 的 inode 表預讀演算法將預讀到緩衝區快取中的最大 inode 表塊數。

lifetime_write_kbytes

此檔案是隻讀的,顯示了自建立此檔案系統以來已寫入該檔案系統的資料千位元組數。

max_writeback_mb_bump

回寫程式碼在移動到另一個 inode 之前嘗試寫入的最大兆位元組數。

mb_group_prealloc

如果在 ext4 超級塊中未設定條帶大小,則多塊分配器將分配請求向上舍入為此調整引數的倍數

mb_max_to_scan

多塊分配器將搜尋以找到最佳 extent 的最大 extent 數。

mb_min_to_scan

多塊分配器將搜尋以找到最佳 extent 的最小 extent 數。

mb_order2_req

調整引數,用於控制使用夥伴快取的請求的最小大小(作為 2 的冪)。

mb_stats

控制多塊分配器是否應收集統計資訊,這些統計資訊在解除安裝期間顯示。 1 表示收集統計資訊,0 表示不收集統計資訊。

mb_stream_req

塊數少於此可調引數的檔案將從特定於塊組的預分配池中分配其塊,以便將小檔案緊密地打包在一起。 每個大檔案將從其自己唯一的預分配池中分配其塊。

session_write_kbytes

此檔案是隻讀的,顯示了自掛載此檔案系統以來已寫入該檔案系統的資料千位元組數。

reserved_clusters

這是一個 RW 檔案,包含檔案系統中保留的叢集數,這些叢集將在特定情況下使用,以避免代價高昂的清零、意外的 ENOSPC 或可能的資料丟失。 預設值為 2% 或 4096 個叢集,以較小者為準,並且可以更改,但是它永遠不會超過檔案系統中的叢集數。 如果在掛載檔案時沒有足夠的空間用於保留空間,則掛載將_不會_失敗。

Ioctls

Ext4 實現了各種 ioctl,應用程式可以使用它們來訪問 ext4 特定的功能。 下表顯示了這些 ioctl 的不完整列表。 此列表包括真正的 ext4 特定的 ioctl (EXT4_IOC_*) 以及最初可能是 ext4 特定的,但現在也受某些其他檔案系統支援的 ioctl (FS_IOC_*)。

Ext4 ioctl 表

FS_IOC_GETFLAGS

獲取與 inode 關聯的其他屬性。 ioctl 引數是一個整數位欄位,位值在 ext4.h 中描述。

FS_IOC_SETFLAGS

設定與 inode 關聯的其他屬性。 ioctl 引數是一個整數位欄位,位值在 ext4.h 中描述。

EXT4_IOC_GETVERSION, EXT4_IOC_GETVERSION_OLD

獲取為每個 inode 儲存的 inode i_generation 編號。 i_generation 編號通常僅在新 inode 建立時更改,它對於網路檔案系統特別有用。 此 ioctl 的 ‘_OLD’ 版本是 FS_IOC_GETVERSION 的別名。

EXT4_IOC_SETVERSION, EXT4_IOC_SETVERSION_OLD

設定為每個 inode 儲存的 inode i_generation 編號。 此 ioctl 的 ‘_OLD’ 版本是 FS_IOC_SETVERSION 的別名。

EXT4_IOC_GROUP_EXTEND

此ioctl與調整掛載選項的作用相同。 它允許將檔案系統調整到最後一個現有塊組的末尾,進一步的調整必須使用resize2fs進行,可以是線上或離線。 引數指向表示檔案系統新塊計數的無符號長整型數。

EXT4_IOC_MOVE_EXT

將塊區段從 orig_fd (此 ioctl 指向的) 移動到 donor_fd (在作為此 ioctl 引數傳遞的 move_extent 結構中指定的)。 然後,交換 orig_fd 和 donor_fd 之間的 inode 元資料。 這對於線上碎片整理特別有用,因為分配器有機會更好地分配移動的塊,理想情況下分配到一個連續的區段中。

EXT4_IOC_GROUP_ADD

向現有或新的組描述符塊新增新的組描述符。 新的組描述符由 ext4_new_group_input 結構描述,該結構作為引數傳遞給此 ioctl。 這與 EXT4_IOC_GROUP_EXTEND 結合使用特別有用,它允許將檔案系統線上調整到最後一個現有塊組的末尾。 這兩個 ioctl 組合在一起用於使用者空間的線上調整大小工具(例如,resize2fs)。

EXT4_IOC_MIGRATE

此 ioctl 在檔案系統本身上執行。 它透過遍歷原始 inode 的間接塊對映並將連續的塊範圍轉換為臨時 inode 的 ext4 區段,將 ext3 間接塊對映的 inode 轉換為 ext4 區段對映的 inode。 然後,交換 inode。 從 ext3 遷移到 ext4 檔案系統時,此 ioctl 可能會有所幫助,但是建議建立新的 ext4 檔案系統並從備份複製資料。 請注意,檔案系統必須支援區段才能使此 ioctl 工作。

EXT4_IOC_ALLOC_DA_BLKS

強制分配所有延遲分配的塊,以保留應用程式預期的 ext3 行為。 請注意,這也會開始觸發資料塊的寫入,但此行為將來可能會更改,因為它不是必需的,並且僅為了簡單起見而這樣做。

EXT4_IOC_RESIZE_FS

將檔案系統調整為新的大小。 調整大小的檔案系統的塊數透過 64 位整數引數傳遞。 核心分配點陣圖和 inode 表,因此使用者空間工具只需傳遞新的塊數。

EXT4_IOC_SWAP_BOOT

將指定 inode 的 i_blocks 和關聯屬性(例如 i_blocks、i_size、i_flags 等)與 inode EXT4_BOOT_LOADER_INO (#5) 交換。 這通常用於將引導載入程式儲存在檔案系統的安全部分中,普通使用者不會意外更改它。 先前引導載入程式的資料塊將與給定的 inode 關聯。

參考

核心原始碼: <file:fs/ext4/>

<file:fs/jbd2/>

程式: http://e2fsprogs.sourceforge.net/

有用的連結: https://fedoraproject.org/wiki/ext3-devel

http://www.bullopensource.org/ext4/ http://ext4.wiki.kernel.org/index.php/Main_Page https://fedoraproject.org/wiki/Features/Ext4