### chkdisk linux

sudo fdisk -l
sudo badblocks -v /dev/sda10 > badsectors.txt

or so

smartctl -l selftest /dev/hda > badblocks.txt

Fix badblocks

Step 1:

Locate the partition on which the bad block resides. The fdisk command can be used to view the sectors of the hard disk partitions.

root]# fdisk -lu /dev/hda

Disk /dev/hda: 123.5 GB, 123522416640 bytes
255 heads, 63 sectors/track, 15017 cylinders, total 241254720 sectors
Units = sectors of 1 * 512 = 512 bytes

Device Boot Start End Blocks Id System
/dev/hda1 * 63 4209029 2104483+ 83 Linux
/dev/hda2 4209030 5269319 530145 82 Linux swap
/dev/hda3 5269320 238227884 116479282+ 83 Linux
/dev/hda4 238227885 241248104 1510110 83 Linux

Here we can see that the LBA 23421417 lies in the third partition, i.e. /dev/hda3. The offset value of the sector is 23421417 — 5269320 = 18152097 sectors in the partition /dev/hda3.

Now we need to check the type of filesystem of the partition. This can be checked from /etc/fstab file.

root]# grep hda3 /etc/fstab
/dev/hda3 /data ext2 defaults 1 2

Step 2:

Now we need to find the block size of the filesystem using tune2fs command

root]# tune2fs -l /dev/hda3 | grep Block
Block count: 29119820
Block size: 4096

This reports the block size to be 4096 bytes.

Step 3:

Find the filesystem block that contains this problematic LBA. We use the following formula:

 

b = (int)((L-S)*512/B)

where:

b = File System block number
B = File system block size in bytes
L = LBA of bad sector
S = Starting sector of partition as shown by fdisk -lu
and (int) denotes the integer part.

For our example, L=23421417, S=5269320, and B=4096.

b = (int)18152097*512/4096 = (int)2269012.125

so b=2269012.

Step 4:

Use debugfs to locate the inode stored in this block, and hence the file that is stored at that location.

root]# debugfs
debugfs 1.32 (09-Nov-2002)
debugfs: open /dev/hda3
debugfs: testb 2269012
Block 2269012 not in use

Here, in this case, the block is not in use. So the rest of this step can be skipped and we can jump directly to next step. Otherwise, if the block is in use, as reported by the following output:

debugfs: testb 2269012
Block 2269012 marked in use
debugfs: icheck 2269012
Block Inode number
2269012 41032
debugfs: ncheck 41032
Inode Pathname
41032 /S1/R/H/714197568-714203359/H-R-714202192-16.gwf

In this case, the problematic file is: /data/S1/R/H/714197568-714203359/H-R-714202192-16.gwf

In case of ext3 filesystem, this block can be the part of journal itself. The inode will be very small and debugfs will not be able to report any filename.

debugfs: testb 2269012
Block 2269012 marked in use
debugfs: icheck 2269012
Block Inode number
2269012 8
debugfs: ncheck 8
Inode Pathname
debugfs:

In this case, we can remove the journal with tune2fs command:

tune2fs -O ^has_journal /dev/hda3

Now, we repeat the step 4, and if the problem is not reported anymore, we can rebuild the journal:

tune2fs -j /dev/hda3

Step 5:

This step will destroy the data on that block by writing zeroes on it. The bad block will be recovered but the data of the file will be lost. If you are sure, you can proceed with the following step:

root]# dd if=/dev/zero of=/dev/hda3 bs=4096 count=1 seek=2269012
root]# sync

Now we can again check the «smartctl -A» output to verify that everything is back to normal.

root]# smartctl -A /dev/hda
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 1
196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 1
197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 0
198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 1

Here you can see that the value of «Current_Pending_Sector» is zero.