Fixing unreadable sectors

Quick reminder for myself on how to fix unreadable sectors on a disk. Doing this live is possible on a zfs pool for example (or probably other RAID setups that have redundancy) but otherwise it is safer to unmount the disk/partition first.

Here are the errors reported by SMART:

Device: /dev/sdb [SAT], 8 Currently unreadable (pending) sectors
Device: /dev/sdb [SAT], 8 Offline uncorrectable sectors

First run a full Extended offline test:

$ smartctl -t long /dev/sdb

Once the test is done, check the results:

$ smartctl -a /dev/sdb
Sector Sizes:     512 bytes logical, 4096 bytes physical
# 9  Extended offline    Completed: read failure       30%     19394         2776811256

The bad sector then need to be zeroed out (adapt the bs argument with the sector sizes and the seek with the first bad sector offset reported from the above command):

$ dd if=/dev/zero of=/dev/sdb bs=512 count=1 seek=2776811256 conv=noerror,sync
$ sync

Repeat the above procedure until all bad sectors have been fixed. At the end, make sure no more bad sectors are detected with:

$ smartctl -A /dev/sdb | grep Offline_Uncorrectable
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0



I experienced that sometimes dd is unable to write to a bad sector, resulting in a similar output

dd: error writing ‘/dev/sdb’: Input/output error

The workaround is to use hdparm in order to fix it

# read the bad sector to validate it is indeed bad
$ sudo hdparm --read-sector 2757742944 /dev/sdb
reading sector 2757742944: FAILED: Input/output error

# write to it
$ sudo hdparm --write-sector 2757742944 --yes-i-know-what-i-am-doing /dev/sdb
re-writing sector 2757742944: succeeded

# re-read to confirm it is fixed
$ sudo hdparm --read-sector 2757742944 /dev/sdb
reading sector 2757742944: succeeded

Smartctl then shows that one sector was reallocated:

$ sudo smartctl -a /dev/sdb | grep -i reallocated
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       1