这些错误实际上意味着什么?可能导致这些错误的原因是什么?

这些错误实际上意味着什么?可能导致这些错误的原因是什么?

这是我第二次在运行时收到此错误badblocks,距离上一次大约两年,并且从硬件(电缆等)到软件(操作系统本身的安装)的绝大多数因素都发生了变化,唯一相关的共同因素是Cygwinbadblocks程序本身,因此问题很可能出在它们之间。


在破坏性模式下运行时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-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()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并设置errnoENOSPC,当它“尝试读取文件末尾的内容“(驱动器)。

答案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 实用程序 校验 找到坏扇区并恢复可读信息,分析整个磁盘的物理磁盘错误。

相关内容