我有一个驱动器,我想从中复制数据,但cp
每次都失败并打印:
cp: error reading 'path/to/always/same/file': Input/output error
的输出dmesg
包含:
[72481.869510] ata2.00: configured for UDMA/133
[72481.874133] ata2.01: configured for UDMA/133
[72481.874145] sd 1:0:1:0: [sdc] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[72481.874147] sd 1:0:1:0: [sdc] tag#0 Sense Key : Medium Error [current]
[72481.874149] sd 1:0:1:0: [sdc] tag#0 Add. Sense: Unrecovered read error - auto reallocate failed
[72481.874152] sd 1:0:1:0: [sdc] tag#0 CDB: Read(16) 88 00 00 00 00 00 f7 9f 4c 00 00 00 02 00 00 00
[72481.874154] print_req_error: I/O error, dev sdc, sector 4154412112
[72481.879316] ata2: EH complete
[72484.819205] ata2.01: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[72484.824273] ata2.01: failed command: READ DMA EXT
[72484.829346] ata2.01: cmd 25/00:08:50:4c:9f/00:00:f7:00:00/f0 tag 0 dma 4096 in
res 51/40:00:50:4c:9f/40:00:f7:00:00/10 Emask 0x9 (media error)
[72484.849742] ata2.01: status: { DRDY ERR }
[72484.854836] ata2.01: error: { UNC }
在网上阅读了这个问题后,我了解到这意味着我必须手动标记坏块。但发出读取命令不会返回“失败”:
$ sudo hdparm --read-sector 4154412112 /dev/sdc
/dev/sdc:
reading sector 4154412112: SG_IO: bad/missing sense data, sb[]: 70 00 03 00 00 00 00 0a 40 51 10 00 11 04 00 00 a0 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00
succeeded
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
这里发生了什么?
答案1
hdparm
成功了与驱动器交谈1.这就是“成功”所表明的一切。驱动器显示“SG_IO:检测数据错误/丢失”。我不知道这到底意味着什么,但这绝对不是一件好事。hdparm
未能成功读取该扇区。
hdparm
继续显示内存缓冲区,该缓冲区应该包含扇区内容,但全都是零。这显然不是从驱动器中读取的内容。
将该块标记为坏块可能有助于继续使用驱动器一段时间,尽管您当然应该尽快更换它。 (但是坏块应该被自动标记为这样。我不明白为什么你要手动这样做。)但它不会让你从该块读取数据。
1具体来说,这意味着HDIO_DRIVE_TASKFILE
读写控制返回 0。
²阅读 的源代码hdparm
可知,当 时会显示此特定消息sb[0] != 0x72 || sb[7] < 14 || desc[0] != 0x09 || desc[1] < 0x0c
。我不知道这些数字意味着什么。
答案2
参考
https://www.smartmontools.org/wiki/BadBlockHowto
和
https://wiki.archlinux.org/index.php/Identify_damaging_files
了解更多信息。
简而言之,在使用 debugfs 或 sleuthkit 等工具识别哪个文件损坏后,hdparm --read-sector
您可以尝试使用--repair-sector
(别名--write-sector
)“向指定扇区号写入零”和“强制驱动器修复坏扇区” (媒体错误)”有关详细信息,请参阅 hdparm 手册页。