Ext4

崩潰後,e2fsck 以異常高的塊數/大小失敗

  • November 20, 2013

在斷路器跳閘後,我的 Raspberry Pi 開始因核心恐慌而停止啟動(與此處的消息相同)。這是一個執行 Raspbian 的 Raspberry Pi,因此它從 SD 卡、主ext4分區執行,我嘗試在我的 PC 上修復它:

sudo e2fsck -f -y -v /dev/sdx2

然而,這最終以一些奇怪的輸出失敗:

Error writing block 137439060017 (Invalid argument) while getting next inode from scan.  Ignore error? yes
Error reading block 183472412950529 (Invalid argument).  Ignore error? yes
Force rewrite? yes
Error writing block 183472412950529 (Invalid argument) while getting next inode from scan.  Ignore error? yes
Inode 13329, i_size is 4096, should be 549755817984.  Fix? yes
Inode 13607, i_size is 69632, should be 137439023104.  Fix? yes
Error reading block 36983963385857 (Invalid argument).  Ignore error? yes
Force rewrite? yes
Error writing block 36983963385857 (Invalid argument) while getting next inode from scan.  Ignore error? yes
Error reading block 179632729097217 (Invalid argument).  Ignore error? yes
Force rewrite? yes
Error writing block 179632729097217 (Invalid argument) while getting next inode from scan.  Ignore error? yes
Error reading block 17592186080054 (Invalid argument) while reading directory block.  Ignore error? yes
Force rewrite? yes
Error writing block 17592186080054 (Invalid argument) while getting next inode from scan.  Ignore error? yes
Error storing directory block information (inode=17449, block=0, num=134507168): Memory allocation failed
/dev/sdx2: ***** FILE SYSTEM WAS MODIFIED *****
e2fsck: aborted
/dev/sdx2: ***** FILE SYSTEM WAS MODIFIED *****

這裡有兩件事令人擔憂:

  • inode 大小和塊大小,看起來高得離譜(我們說的是 16GB SD 卡),
  • e2fsck在具有 32 GB RAM 的 PC 上以 - 結尾Memory allocation failed,其中大部分是免費的。它確實在失敗之前佔用了空閒 RAM。

我嘗試配置一個具有相同結果的暫存文件目錄(e2fsck確實在那裡寫入了一些文件,並且目標目錄位於具有 +250GB 可用空間的掛載上 - 它佔用了可用的 RAM,但失敗了)。

受影響分區上的基本文件系統參數似乎有一些損壞。如何診斷和消除?

我快速瀏覽了e2fsck 原始碼,在我看來,有些地方可能會出現*“記憶體分配失敗”*錯誤,原因可能並不是真正的記憶體分配錯誤。

錯誤字元串是[src]/lib/ext2fs/ext2_err.et.in相對於常量定義的EXT2_ET_NO_MEMORY。這可以從[src]/e2fsck/. 下面是一個例子ea_refcount.c

errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
{
   struct ea_refcount_el   *el;

   el = get_refcount_el(refcount, blk, 1);
   if (!el)
       return EXT2_ET_NO_MEMORY; 

get_refcount_el()在同一個文件中:

static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
                         blk_t blk, int create)
{
   int low, high, mid;

   if (!refcount || !refcount->list)
       return 0;    

這不是它返回 null 的唯一原因,也不是看起來它與分配失敗沒有直接關係的唯一原因。

為了真正證明我必須做更多的探勘,但這確實符合您的斷言,即它並沒有真正耗盡系統記憶體。

在這種情況下,也許問題與混亂/損壞的 SD 卡控制器的模糊和不可預測的可能性有關,但它仍然相當於 e2fsck 中的一個錯誤,因為某種健全性檢查或應該採取一些措施來捕捉這個,即使只是說,“對不起,你的設備被搞砸了”(可能是真的)與“記憶體不足”(可能不是真的)。你可能想報告這個(“如果這些程序中有錯誤,請通過 tytso@mit.edutytso@alum.mit.edu 聯繫 Ted Ts’o” ——我相信 TT 是一個 linux 核心開發人員),並且你可以參考這個問答。

除此之外,IMO 你不妨忘記那張卡上的任何東西,並對其進行破壞性讀寫測試:

badblocks -v -w -b 1048576 -c 16 /dev/sdx

請記住,這是一項破壞性測試——您將失去所有數據。壞塊對於為 SD 卡創建實際的壞塊列表沒有用(由於磨損均衡,它們不會報告實際的物理地址),但如果卡被破壞,它可能會讓你知道。以這種方式測試 16 GB 卡只需不到一個小時。

當您執行 e2fsck -fy 時,您確實需要保存整個 e2fsck 腳本,而不僅僅是顯示最後幾條錯誤消息。可能是文件系統被嚴重損壞了,-y 選項意味著無論如何都要繼續執行。

看起來塊組描述符已嚴重損壞,因此 inode 表的位置很瘋狂。E2fsck 可能試圖修復它,但由於某種原因它無法修復它,“-y”表示儘管如此它仍會繼續執行。所以當人們發送錯誤報告時,我總是建議他們發送完整的 e2fsck 成績單,而不僅僅是最後幾個錯誤。

引用自:https://unix.stackexchange.com/questions/100767