真正重新映射磁盘上的坏块

真正重新映射磁盘上的坏块

我有一个 SATA 驱动器,程序总共识别出 8 个坏块badblocks。据说驱动器固件应该能够重新映射它们并替换备件。我已badblocks-n模式下运行以重写有问题的分区,并多次运行 e2fsck。没有任何变化,始终是相同的 8 个坏块。

当我运行时smartctl它显示Reallocated_Sector_Ctat 0

如何让固件真正重新映射 8 个坏块?

答案1

如果在整个扇区的写入请求中提供了新数据,则驱动器只能尝试重写或重新分配不可读扇区。badblocks不这样做,所以没有任何改变。

“非破坏性”读写模式的工作原理如下:

  1. 读取原始数据
  2. 编写测试模式
  3. 读取测试模式
  4. 写入原始数据

如果第一步已经失败,即无法读取数据,则也无法对该扇区执行写入操作,因为之后无法恢复原始数据。这将是破坏性写入,但您特别要求非破坏性变体,因此尚未完成。

“非破坏性”方法仍然可能因其他原因而无法恢复原始数据,因此无论如何,您都不应该在要保留数据的驱动器上运行坏块。


如果您想badblocks无论如何都执行此操作,那么您必须使用其-w写入模式 - 默认情况下会覆盖所有数据,因此您希望将范围缩小到应使用badblocks -w device [last_block [first_block]]可选参数覆盖的特定扇区范围形式。您可以通过首先运行只读坏块测试来确定这些扇区。

只读测试:

# badblocks /dev/foobar
1000

块 1000 有缺陷,因此专门覆盖该块:

# badblocks -w /dev/foobar 1000 1000

然而,这仍然会失败。为什么?因为badblocks使用默认的块大小 1024 字节。

对于扇区大小为 512 字节的设备来说这是错误的 — 坏块会覆盖两个扇区而不是一个扇区,从而造成额外的损坏 — 对于扇区大小为 4096 字节的设备来说也是错误的 — 坏块只会写入一个部分扇区,这对于重新分配不起作用因为您必须写入完整的数据块。


因此,对于上面的两个命令,您必须指定驱动器的正确块大小(物理扇区大小)(512 或 4096 或其他)。

随着块大小的改变,报告的块号也会相应改变:

# badblocks -b 512 /dev/foobar
2000
# badblocks -b 4096 /dev/foobar
250

您可以相应地调整写入命令:

# badblocks -b 512 -w /dev/foobar 2000 2000
# badblocks -b 4096 -w /dev/foobar 250 250

这应该使驱动器有机会重新分配有问题的扇区。


如果仍然失败,则还有另一种可能性:如果给定设备是分区或其他逻辑驱动器,并且它未与物理驱动器对齐,则所有写入都将是未对齐的,因此您最终会将 4096 字节写入两个部分 4096 字节扇区。

它不会重新定位目标扇区,而是部分损坏相邻扇区中的数据。

所以这种方法存在一定的导致数据进一步丢失的风险。

答案2

最简单的方法是完全有意地忽略这个问题。

固件将在下次写入时重新映射每个扇区,在此之前无需担心它。

留意其他 SMART 属性。确保您有良好的备份。考虑投资更换磁盘。

答案3

如何让固件真正重新映射 8 个坏块?

您写入损坏的扇区,例如

sudo hdparm --yes-i-know-what-i-am-doing --repair-sector SECTOR_NUMBER /dev/device

这是一种破坏性操作,它将用零 ( ) 替换损坏的扇区0x00

SMART 毕竟不是那么“聪明”,我经常看到它失败。即,在大多数情况下,它无法重新分配损坏的扇区,并且需要被告知要做什么。

相关内容