Unable to Write Zeros to Bad Sectors/Hard Disk Not Counting Reallocated Sectors

bad-sectorshard drivesectorssmart

I have a drive that is reporting that the current pending sectors is "45". I have used badblocks to identify the sectors and I have been trying to write zeros to them with dd.

From what I understand, when I attempt writing data directly to the bad sectors, it should trigger a reallocation, reducing current pending sectors by one and increasing the reallocated sector count.

However, on this disk both Reallocated_Sector_Ct and Reallocated_Event_Count raw values are 0, and dd fails with I/O errors when I attempt to write zeros to the bad sectors. dd works fine, however, when I write to a good sector.

# dd if=/dev/zero of=/dev/sdb bs=512 count=1 seek=217152
dd: error writing ‘/dev/sdb’: Input/output error

Does this mean that my drive, in some way, has no spare sectors to be used for reallocation? Is my drive just in general a terrible person? (The drive isn't actually mine, I'm helping a friend out. They might have just gotten a cheap drive or something.)

In case it is relevant, here is the output of smartctl -i :

Model Family:     Western Digital Caviar Green (AF)
Device Model:     WDC WD15EARS-00Z5B1
Serial Number:    WD-WMAVU3027748
LU WWN Device Id: 5 0014ee 25998d213
Firmware Version: 80.00A80
User Capacity:    1,500,301,910,016 bytes [1.50 TB]
Sector Size:      512 bytes logical/physical
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ATA8-ACS (minor revision not indicated)
SATA Version is:  SATA 2.6, 3.0 Gb/s
Local Time is:    Fri Oct 18 17:47:29 2013 CDT
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

UPDATE:
I have run shred on the disk, which has caused Current_Pending_Sector to go to zero. However, Reallocated_Sector_Ct and Reallocated_Event_Count are still zero, and dd is now able to write data to the sectors it was previously unable to. This leads me with several other questions:

  • Why aren't the reallocations being recored by the disk? I'm assuming the reallocation took place as I can now write data directly to the sector and couldn't before.

  • Why did shred cause reallocation and not dd? Does the fact that shred writes random data instead of just zeros make a difference?

Best Answer

The WD15EARS drive (and most other recently produced drives) uses Advanced Format, which means that the real physical sector size of this drive is 4 KiB, and the traditional 512-byte sector size is just emulated. Because of this, if a single 4 KiB physical sector goes bad, all 8 corresponding emulated 512-byte sectors become unreadable at once.

(The Sector Size: 512 bytes logical/physical output from smartctl is not correct, because some WD15EARS drives report wrong physical sector size — apparently your drive has a firmware version which is broken in that respect.)

Moreover, when a single emulated 512-byte sector is written, the Advanced Format drive actually needs to read the whole 4 KiB physical sector, change the corresponding 512-byte part of it, then write the whole physical sector to the media. If the media is good, this read-modify-write operation just causes a significant slowdown compared to a drive with real 512-byte physical sectors. However, if the 4 KiB physical sector is bad and cannot be read, any write operation which does not rewrite the sector completely will fail. Because of this, you cannot force sector reallocation on such drives using dd with bs=512 count=1 — you must use at least bs=512 count=8 and make sure that the sector number in the seek= option is a multiple of 8. (This assumes that the “Windows XP Compatible” jumper is not installed, otherwise the alignment offset added by this jumper must also be taken into account.)

Another reason why forcing the reallocation with dd might fail is that by default Linux uses a cache in the block layer to access block devices, and this may cause read-modify-write operations in software, which would also fail when an unreadable sector is encountered. You can add the oflag=direct option to bypass this cache for the device specified by of=... (there is also the iflag=direct option, which applies to the input device).