這些錯誤實際上意味著什麼,以及可能導致這些錯誤的原因是什麼?

這些錯誤實際上意味著什麼,以及可能導致這些錯誤的原因是什麼?

這是我第二次收到此運行錯誤badblocks,距離上次大約相隔兩年,從硬體(電纜等)到軟體(作業系統本身的安裝)的絕大多數因素都發生了變化因為唯一相關的共同因素是Cygwin程序badblocks本身,因此問題很可能出在這些因素之間。


當以破壞性模式運作時badblocks(即使用開關-w),我收到錯誤:

do_writerrors 中的奇怪值 (4294967295)

...在將模式寫入磁碟機的每個階段。

據我所知,我似乎僅在使用報告的指定最後一個區塊運行命令時才會出現此錯誤fdisk -l

$ fdisk -l /dev/sda
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

$ badblocks -b 512 -vws /dev/sda 1953525168 1953525168
Checking for bad blocks in read-write mode
From block 1953525168 to 1953525168
Testing with pattern 0xaa: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: 1953525168ne, 0:00 elapsed. (0/0/0 errors)
done
Testing with pattern 0x55: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0xff: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0x00: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Pass completed, 1 bad blocks found. (1/0/0 errors)

$ badblocks -b 512 -vws /dev/sda 1953525168 1950000000
Checking for bad blocks in read-write mode
From block 1950000000 to 1953525168
Testing with pattern 0xaa: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: 1953525168ne, 0:49 elapsed. (0/0/0 errors)
done
Testing with pattern 0x55: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0xff: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0x00: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Pass completed, 1 bad blocks found. (1/0/0 errors)

可以看出,這也會導致誤報壞塊,而透過 CrystalDiskInfo 卻找不到這個假定的壞塊:

在此輸入影像描述

此時,驅動器已被多次歸零,並且已badblocks對其最後幾個區塊進行了數十次寫入,因此 SMART 值有很多機會在區塊中發現壞扇區(1953525168如果存在)。

這些錯誤實際上意味著什麼,以及可能導致這些錯誤的原因是什麼?

答案1

雖然 harrymc 可能已經給了你我答案的核心(即4294967295as -1unsigned int,但他沒有進一步解釋為什麼badblocks不簡單地將其“識別”為-1(即為什麼在 Windows 上使用 Cygwin 構建它會出現“奇怪的值”錯誤) )。

我看了一下badblocksCygwin的程式碼:

https://github.com/tytso/e2fsprogs/blob/v1.45.4/misc/badblocks.c#L463

https://github.com/cygwin/cygwin/tree/01c253a4c58b6c1da01615431bdc4c88fcba48ea/newlib/libc/syscalls/syswrite.c

https://github.com/cygwin/cygwin/tree/01c253a4c58b6c1da01615431bdc4c88fcba48ea/newlib/libc/reent/writer.c

我想出了這個:

[tom@archlinux ~]$ cat test.c 
#include <stdio.h>

unsigned int eh() {
  return -1;
}

int main() {
  long got;
  got = eh();
  printf("%ld\n", got);
  got = (long) eh();
  printf("%ld\n", got);
  got = (int) eh();
  printf("%ld\n", got);
}
[tom@archlinux ~]$ cc test.c 
[tom@archlinux ~]$ ./a.out 
4294967295
4294967295
-1
[tom@archlinux ~]$ 

基本上這就是說,如果您想將無符號變量(可能有意用於存儲有符號值)解釋為有符號變量,則應該使用其自己的大小進行解釋,而不是要使用的另一個變量的大小將其價值放入。

我對程式設計不太熟悉,但正如你所看到的,(_ssize_t)類型轉換reent/writer.c可能是錯誤的。如果我們假設_write()is 屬於該int類型(或任何有符號類型),則這種類型轉換是多餘的。如果我們假設_write()是 的unsigned int類型,那麼它需要的類型轉換應該是(int)。 (根據記錄,它是需要的,只是因為我們將其值「擴展」為 a _ssize_t(即ret)。類似的比較(an_unsigned_int == -1)可以很好地工作,AFAIK。)

雖然我必須說這只是我的猜測,因為我並不真正了解_write()Cygwin 的用途(例如,它是否與,如果是這樣,文檔是否只是垃圾)。但我認為這是一個有效的案例錯誤報告,這可能會讓您了解更多。

更新:可能是引入「回歸」的提交(如您所見,_ssize_t將基於__SIZE_TYPE__(這本質上是根據提交訊息)。當 Cygwin 是 64 位元時,size_t它可能最終會基於unsigned long),所以我打賭您將無法使用 32 位元 Cygwin 重現該問題(即使在 64 位元 Windows 上)。可能值得一提的是更早的提交可能曾經「修復」過它。這就是為什麼我稱之為「回歸」。

更新2:是的,我是對的: 在此輸入影像描述 也許現在我應該獲取 Visual Studio 並檢查_write()(也許write())一點...

PS 如果您正在對「最後一個區塊+ 1」進行唯讀測試,那麼您不應該遇到「奇怪的值」錯誤,就像_read()返回一樣,這與返回並設定為「時」0不同。_write()-1errnoENOSPC嘗試讀取文件末尾「(驅動器)。

答案2

十進制值4294967295(十六進制FFFFFFFF)簡單地-1描述為無符號 32 位元整數。這是一個常見的API錯誤代碼,沒有其他意義。這個實用程式badblocks非常基本,由 Linus Torvalds 幾十年前編寫,僅寫出資料並將其讀回。

不可糾正的扇區計數 表示磁碟韌體已偵測到但由於無法讀取這些磁區而無法重新定位到好磁區的壞磁區數量。韌體已放棄嘗試重新定位這些磁區。

因此,韌體已偵測到 459 個不可覆蓋磁區,但無法重新對應。

盤面無疑處於末期。

如果您想挽救磁碟並且不關心其內容,您可以嘗試深度格式化它,重寫和更新所有好的磁區,同時將韌體無法觸及的磁區標記為壞磁區。這裡最好使用製造商提供的實用程式。應避免使用 Cygwin,因為它的 Linux 實用程式不能保證與 Windows 的良好整合。

DiamondMax 支援頁面 建議使用最新的磁碟實用程式 DiscWizard 版本:23.0.17160,也許可以進行深度格式化。這是一個 Windows 實用程式。

如果有問題的磁碟是 Windows 系統磁碟,您可能需要從 Windows PE 啟動磁碟或救援磁碟執行該實用程式 Bob.Omb 的修改版 Win10PEx64。您也可以使用 基於 Windows PE 的可啟動復原光碟 例如 Hiren 的 BootCD PE。在緊要關頭,您可以嘗試從 Linux Live 啟動來格式化磁碟。


(重寫後的貼文的補充)

上面的答案顯然在寫完並更換磁碟的兩年前就被發文者接受了。這部分是關於新磁碟的。

新磁碟形狀完美且零缺陷,但壞塊卻給了錯誤訊息。

Badblocks 是一個古老的實用程序,由 Linus Torvalds 編寫,甚至可能早於 Linux 出現。它所做的只是創建一個臨時文件,寫入它直到遇到空間結束,然後重新讀取資料。作為磁碟測試,它非常糟糕,並且僅“測試”磁碟上的可用空間。

此外,它是在 Cygwin 上運行的,甚至不在 Windows 上運行,因此它對 Windows 返回的錯誤代碼的理解非常值得懷疑。它甚至無法報告真正的錯誤代碼,而是始終報告-1 錯誤代碼。無法想像 Cygwin 嘗試將 Windows API 錯誤代碼轉換為它想像的等效 Linux 錯誤代碼會產生什麼結果。

坦白說,我會忽略這個毫無意義的虛假錯誤,可能只是來自對「無更多空間」回傳程式碼的誤解,被 badblocks 或 Cygwin 誤解。 SMART 韌體傳回的資料更重要。

在文中 相當於 Windows 或 DOS 上的壞塊 提供了一些建議,所有這些建議都比壞塊好得多,因為它們測試整個磁碟而不僅僅是可用空間。

一個不錯的選擇是chkdsk /r,它使用 Windows 實用程序 查克德斯克 定位壞磁區並恢復可讀訊息,分析整個磁碟上的實體磁碟錯誤。

相關內容