Skip to content

Instantly share code, notes, and snippets.

@radiofreejohn
Created January 20, 2012 02:00
Show Gist options
  • Save radiofreejohn/1644519 to your computer and use it in GitHub Desktop.
Save radiofreejohn/1644519 to your computer and use it in GitHub Desktop.
check individual files for fragmentation on Mac OS X
/*
check-frag filename [blocksize guess]
blocksize default is 4096 -- smaller and seeks take too long
*/
#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);
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment