MacOS – How to identify and fix files with corrupted / inaccessible disk blocks

disk-utilityhard drivemacbook promacos

I have a late 2011 Macbook Pro, running Mavericks 10.9.2. Its sole HDD is a 750GB drive, formatted with Bootcamp. It's still running reasonably well, but in running a defragment pass on it, I've identified that there are a bunch of files which are refusing to be moved by the defragmenter (iDefrag).

iDefrag reports a POSIX error code of 5 when accessing the files. Picking one at random and trying to copy the file to another location in the shell also reports an error, which makes me think the problem is real and with the disk / FS. Output of cp is:

cp: unity_nophysx.nexe: Input/output error

Error code 5 is 'access denied' as far as I'm aware, but the defrag process is running as administrator and running cp using sudo on the suspect file makes no difference.

Disk Utility, fsck and the Apple Hardware Test all claim the disk is fine. No SMART errors reported, and while there were some permissions errors, they weren't with the files iDefrag is complaining about, and Disk Utility claims to have fixed them without complaint.

There are maybe a hundred or more corrupted files, but still a very small fraction of the drive. As far as I can tell, no system files or crucial data are affected. While it would be nice to retrieve the data, I don't mind reinstalling or going to backups. At this point I don't know if it's really the drive dying, just some bad sectors due to the drive being moved while writing, or some other minor corruption that can be worked around. I'm assuming the worst case, and that most likely I'll have to get a slightly larger HDD and clone the existing drive to avoid having to rebuild the system.

My question is really how I go about marking those broken files as properly broken and fixing or purging them, so that a clone of the disk will succeed and not get hung up on files / blocks it can't access. Disk Utility isn't seeing the problem, and I don't know of any command line or third party tools which will do the job. I don't want to write off the entire disk and start from scratch, as the drive seems otherwise healthy, so I'm looking for repair / diagnostic tools.

Best Answer

If you are facing a healthy file system at the level of its structure and want to find files which have disk faulty blocks, here is how I would proceed:

  1. Make a full backup of your disk with Time Machine or Carbon Copy Cloner

    Check this backup.

  2. Run the following heavy and risky (in case you do have bad blocks outside of your filesystem structure) command (make sure the {} is quoted so filenames containing spaces work):

    find / -type f -print -exec dd if="{}" of=/dev/null bs=1m \;
    

This heavy find command will print for any plain file its name (thus not reading it, but just its directory entry) and then continue making a full and fast read of all its data blocks.

Upon hiting the first file containing bad blocks, this find will cause the kernel to log read error on /var/log/system.log, and it will either slow down or bring your system to a total halt. This will mostly depend on the hard drive capacity to relocate the bad blocks found on its internal pool dedicated to this usual fix task. This file containing bad blocks will be the last name printed by find.

Write down this file name on a piece of paper! Let's say that this file name is:

/.DocumentRevisions-V100/.cs/ChunkStorage/0/0/0/9

At this point you may have the possibility to kill find quickly by hiting ctrl+C. If killing it nicely is failing, just crash your Mac.

Upon rebooting your Mac, directly check the file containing bad blocks:

dd if='/.DocumentRevisions-V100/.cs/ChunkStorage/0/0/0/9' of=/dev/null bs=1m

If the command terminate correctly, then the error was light enough for your disk to be able to read this file and reallocate the bad blocks.

  • If the command doesn't terminate, you won't be able to kill it normally, your data is totally lost, and you will have to crash your Mac once more.

In this last case, you have to consider replacing your disk and to work from your last backups. Some other files might also contain bad blocks and may have stayed undetected since a long time as long as you didn't read them.

The kernel won't fire a read error on a block you never read.