这是我第二次在运行时收到此错误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 可能已经给了你我答案的核心(即4294967295
)-1
,unsigned int
但他并没有进一步解释为什么badblocks
不简单地“识别”它-1
(即为什么在 Windows 上使用 Cygwin 构建它会出现“奇怪的值”错误)。
我查看了badblocks
Cygwin 的代码:
https://github.com/tytso/e2fsprogs/blob/v1.45.4/misc/badblocks.c#L463
我想出了这个:
[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()
是int
类型(或任何有符号类型),则这种类型转换是多余的。如果我们假设_write()
是类型unsigned int
,那么它所需的类型转换应该是(int)
。(记录显示,它之所以需要,只是因为我们将其值“扩展”为 a _ssize_t
(即ret
)。(an_unsigned_int == -1)
据我所知,像这样的比较可以正常工作。)
虽然我不得不说这只是我的猜测,因为我不太了解_write()
Cygwin 的用途(比如,它是否与这,如果是,那么文档是否只是废话)。但我认为这是一个有效的案例错误报告,这可能会让你发现更多。
更新:这可能是引入“回归”的提交(如您所见,_ssize_t
将基于__SIZE_TYPE__
(本质上是size_t
根据提交消息)。它很可能最终是unsigned long
当 Cygwin 是 64 位时,基于这和这),所以我敢打赌你无法用 32 位 Cygwin 重现这个问题(即使在 64 位 Windows 上也是如此)。值得一提的是更早的提交可能曾经“修复”过它。这就是我称之为“回归”的原因。
更新2:是的,我是对的:
也许现在我应该得到 Visual Studio 并检查_write()
(也许write()
)一下...
PS:如果你正在对“最后一个块 + 1”进行只读测试,则不应该遇到“奇怪的值”错误,因为_read()
会返回0
,而不像_write()
会返回-1
并设置errno
为ENOSPC
,当它“尝试读取文件末尾的内容“(驱动器)。
答案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
as 错误代码。无法想象 Cygwin 尝试将 Windows API 错误代码转换为它想象的等效 Linux 错误代码会产生什么结果。
坦白说,我会忽略这个虚假错误,认为它毫无意义,可能只是因为误解了“没有更多空间”返回代码,无论是 badblocks 还是 Cygwin 都误解了它。SMART 固件返回的数据更切题。
在文中 相当于 Windows 或 DOS 上的坏块 提出了几条建议,它们都比坏块好得多,因为它们测试整个磁盘而不仅仅是可用空间。
一个很好的选择是chkdsk /r
使用 Windows 实用程序
校验
找到坏扇区并恢复可读信息,分析整个磁盘的物理磁盘错误。