Ho posto la stessa domanda su quora e qualcuno ha risposto in modo impressionante con un programma in C che si è inventato.
Ecco il suo codice:
/*
check-frag filename [blockjump]
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
struct log2phys lf;
int start, end, i, status;
int blockjump = 4096;
struct stat st_buf;
if (argc < 2) {
printf("Enter a filename.\n");
return 1;
}
if (argc == 3) {
blockjump = atoi(argv[2]);
}
printf("Using block size of %d\n", blockjump);
status = stat(argv[1], &st_buf);
if (status != 0 || (!(S_ISREG (st_buf.st_mode)))) {
fprintf(stderr, "Error reading file %s or file is not regular file.\n", argv[1]);
return 1;
}
int fd = open(argv[1], O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Error or file not found: %s\n", argv[1]);
return 1;
}
start = lseek(fd, 0, SEEK_CUR);
end = lseek(fd, 0, SEEK_END);
printf("start: %d\tend: %d\n", start, end);
off_t last = 0;
int cblocks = 1;
int tblocks = 1;
for (i = 0; i < (end-blockjump); i=i+blockjump) {
tblocks++;
lseek(fd, i, SEEK_SET);
fcntl(fd, F_LOG2PHYS, &lf);
if (last != lf.l2p_devoffset && last != (lf.l2p_devoffset-blockjump)) {
printf("%jd\n", (intmax_t)lf.l2p_devoffset);
} else {
cblocks++;
}
last = lf.l2p_devoffset;
}
printf("contiguous blocks: %d\n", cblocks);
printf("total blocks: %d\n", tblocks);
printf("difference (fragmented extents): %d\n", tblocks-cblocks);
printf("percent contiguous in file: %f\n", (float)cblocks/(float)tblocks);
close(fd);
return 0;
}
Metti questo in un file, chiamalo frag.c o qualcosa del genere ed esegui make frag
o gcc frag.c -o frag
. Ora puoi eseguire ./frag path/to/your/file
. È inoltre possibile aggiungere la dimensione del blocco come secondo argomento.
Nota che dovrai essere in grado di compilare il programma, che su Mac OS X viene in genere fatto avendo XCode installato.