Virgula
Virgula

Reputation: 348

Search for bad sectors of a device in C

I'm trying to create a simple script in c which is able to identify bad sectors of (a device) for educational purpose. In my example, I use an HD with read-only mode. The idea behind is simple, but maybe too simple and I would know if this is correct and eventually get known about any other way to reach my goal.

Let's take a look to my code:

#include<stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char ** argcv){
        size_t size_block = 512;
        int fd = open("/dev/disk2",O_RDONLY);
        ssize_t bytes_read = 1;
        char *buff = malloc(size_block * sizeof(char));

        if (buff == NULL){
           exit(EXIT_FAILURE);
        }

        while (bytes_read > 0){
                bytes_read = read(fd,buff,size_block);
                int position = lseek(fd, 0, SEEK_CUR);
                if (bytes_read == -1){
                        perror("main");
                }
                //printf("%s",buff); //prints the content of what I read
                if (bytes_read < size_block){
                        printf("the block at %p address is probably damaged",&position);
                }
        }
        free(buff);
        close(fd);
        return 0;
}

So I try to read sectors of my HD with read syscalls by seeking the file pointer of 512 bytes every time. And that's the first question: since the preferred, I/O block size is 2048 byte (info retrieved with stat of sys/stat.h), is it correct seek every time of 512 bytes instead of 2048? Also, to check if a sector is bad I use to compare (bytes_read < size_block)because I assume that if I cannot read the totality of bytes of a sector, it could be damaged. But if I reach the end "of the file" and it isn't a multiple of 512 with this method I will get that the sector is damaged anyway also if it isn't. Is what I wrote really working? Otherwise, how can I do this check?

Upvotes: 1

Views: 478

Answers (1)

Kevin Boone
Kevin Boone

Reputation: 4307

On Linux, at least, I'm fairly sure that a block device will always appear to have a readable size that is be a multiple of 512 bytes, regardless of the underlying device capacity. The kernel pads out the last block if there isn't enough physical data to fill 512 bytes. When a filesystem is created on a device, the filesystem tools round down the allocated size to account for this.

What that means is that a read() of size 512 will always return 512 or an error, even if it's the last read and it doesn't fill a whole 512 byte buffer.

However, I think it's unlikely that a bad sector will cause what appears to be a short read. I think it's more likely that the read() will simply fail and return -1, or just appear to succeed and return some nonsense. I suspect that you need to write and read to check for bad sectors.

Upvotes: 0

Related Questions