How likely is the last block of a drive to be a bad sector?

All we need is an easy explanation of the problem, so here it is.

This is a follow-up question to this one, where zeroing the disk with dd would give me an error towards the very end of the drive.

I then set about trying to determine whether this was a bad sector, as was suggested it might be, as opposed to some sort of issue with the hard drive or with the environment I was running.

Running:

badblocks -o ~/.badblocks_in_X_full -vws /dev/sda 976762584 950000000

…gives the output:

Checking for bad blocks in read-write mode
From block 950000000 to 976762584
Testing with pattern 0xaa: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0x55: Weird value (4294967295) in do_writeerrors)
done
Reading and comparing: done
Testing with pattern 0xff: Weird value (4294967295) in do_writeerrors)
done
Reading and comparing: done
Testing with pattern 0x00: Weird value (4294967295) in do_writeerrors)
done
Reading and comparing: done
Pass completed, 1 bad blocks found. (1/0/0 errors)

The resulting output file lists the bad block as block 976762584.

Doing cat /proc/partitions shows that dev/sda has 976762584 blocks.

In other words, badblocks is reporting that the very last block of the drive is bad.

I know it’s possible that the very last block/sector of a drive could be the only bad sector on the drive, but it seemed to me such an unlikely occurrence that it would be more likely to be something else.

Is this bad sector reported by badblocks real, or more likely to be just a sign of hardware or environment issues?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Although this is not a direct answer to your question, but it may give you some insight.

First of all for some reason badblocks seem to report a bad block for “last block + 1” anyway (while for “last block + 2” or higher, it correctly return a seek error):

[[email protected] ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116287 31116287
Checking blocks 31116287 to 31116287
Checking for bad blocks (read-only test): done                                   

Pass completed, 0 bad blocks found. (0/0/0 errors)
[[email protected] ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116288 31116288
Checking blocks 31116288 to 31116288
Checking for bad blocks (read-only test): 31116288
done
Pass completed, 1 bad blocks found. (1/0/0 errors)
[[email protected] ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116289 31116289
Checking blocks 31116289 to 31116289
Checking for bad blocks (read-only test): badblocks: Invalid argument during seek
done
Pass completed, 0 bad blocks found. (0/0/0 errors)
[[email protected] ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116290 31116290
Checking blocks 31116290 to 31116290
Checking for bad blocks (read-only test): badblocks: Invalid argument during seek
done
Pass completed, 0 bad blocks found. (0/0/0 errors)
[[email protected] ~]$

But dd has no such problem:

[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116287
1+0 records in
1+0 records out                                                                  
512 bytes copied, 0.0254859 s, 20.1 kB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116288
0+0 records in
0+0 records out
0 bytes copied, 0.000534631 s, 0.0 kB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116289
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000737962 s, 0.0 kB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116290
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000694995 s, 0.0 kB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes 
count=1M skip=15192M
2048+0 records in
2048+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.0612828 s, 17.1 MB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes 
count=1M skip=15193M
1024+0 records in
1024+0 records out
524288 bytes (524 kB, 512 KiB) copied, 0.029878 s, 17.5 MB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes 
count=1M skip=15194M
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000814785 s, 0.0 kB/s
[[email protected] ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes 
count=1M skip=15195M
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000700151 s, 0.0 kB/s
[[email protected] ~]$

In any case, if you want to check whether a particular block is bad and/or compare the result of badblocks and dd, it’s best that you test with the logical block size (usually 512 bytes) and do not use values that exceeds the actual size of the drive. Both pieces of information can be obtained with fdisk -l:

[[email protected] ~]$ sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 14.86 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
[[email protected] ~]$

Also make sure you count from 0 when you are specifying a specific block, and do not count one less when you are specifying numbers of blocks (like for count/skip/seek in dd)

EDIT: It’s actually natural that “last block + 1” is a special case as it is valid to seek an entire drive (last block inclusive). It’s just that there’s no more space to read/write. But for “last block + 2” or higher, even the the seek will go past the end of the drive, hence the seek error. It might also worth noting that current badblocks doesn’t exactly check what the write error is (but just return to its caller that the written length is 0): https://github.com/tytso/e2fsprogs/blob/v1.45.4/misc/badblocks.c#L443

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply