Reputation: 348
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
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