Více mě ale zajímá to, jak defrag zjistí počet fragmentů souboru - pokud vím, na úrovni Linux VFS neexistuje žádná rutina, na základě které by se to dalo deterministicky zjistit. Bojím se toho, že defrag pouze určitým způsobem odhaduje počet fragmentů porovnáním velikosti souboru, času O_DIRECT přečtení souboru a rychlosti sekvenčního čtení disku (hdparm -tT --direct, pokud chcete změřit svůj disk). Budu rád, pokud mi toto někdo vyvrátí.
Mno, já si zkusmo zbastlil tohle:
#include <stdio.h>
#include <linux/fs.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
int main(int argc, char **argv)
{
int fd=0, block, block_size, block_position, fragment_size=0, last_block_position, fragments=1;
struct stat st;
if (argc < 2)
{
printf("Enter a file name.\n");
exit(EXIT_FAILURE);
}
printf("File: '%s'\n", argv[1]);
fd = open(argv[1], O_RDONLY);
if(fd==-1)
{
perror(argv[1]);
exit(EXIT_FAILURE);
}
if (stat(argv[1], &st) == -1)
{
perror("stat");
exit(EXIT_FAILURE);
}
if (ioctl(fd, FIGETBSZ, &block_size) == -1)
{
perror("ioctl");
exit(EXIT_FAILURE);
}
printf("File size: %d (%d blocks, a block has %d bytes)\n", (int)st.st_size, 1+((int)st.st_size/block_size), (int)block_size);
for (block=0; block<=st.st_size/block_size; block++)
{
last_block_position = block_position;
block_position = block;
if (ioctl(fd, FIBMAP, &block_position) == -1)
{
perror("ioctl");
exit(EXIT_FAILURE);
}
/* printf("%d: %d\n", block, block_position); */
if (fragment_size > 0 && block_position != last_block_position+1)
{
printf("A fragment (%d blocks) ends at block %d\n", fragment_size, block);
fragment_size = 0;
fragments++;
}
else
{
fragment_size++;
}
}
printf("Total: The file has %d fragments with average size of %.1f blocks each.\n", fragments, (1+st.st_size/block_size)/(double)fragments);
exit(0);
}
Je to "narychlo zprasené" (jsou tři ráno ;-)), ale zdá se mi, že to funguje. :-) (A nekamenovat za formu, prosím, Cčko neumím. ;-))