Vlákno názorů k článku Defragmentace disků v Linuxu od anonym - Zaráží mě fakt, že autor ani nenaznačuje způsob,...

  • Článek je starý, nové názory již nelze přidávat.
  • 7. 1. 2008 0:38

    bez přezdívky
    Zaráží mě fakt, že autor ani nenaznačuje způsob, kterým testovaný program degragmentuje soubory, dokonce ani způsob, kterým analyzuje fragmentaci.

    Zatím všechny mě známé programy, které "defragmentovaly" svazky nezávilse a filesystému to dělaly tak, že každý soubor zkopírovaly a následně změnily link současného souboru na zkopírovaný (což je ostudně hloupá metoda, na kterou nemusíte mít žádný program - stačí jeden bash one-liner). Defrag k této práci asi používá rsync, což je zajímavé.. ;) (na to, že rsync je program na synchronizaci složek)

    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í.

    Tolik můj kousek do pranice - neříkám, že defrag nedělá nic, ale já bych k schopnostem takovéhoto programu přistupoval mnohem více skepticky než autor.
  • 7. 1. 2008 1:25

    Dan Ohnesorg
    Koukam do kodu a vola to:

    fragresult=subprocess.Popen(["filefrag",file],stdout=subprocess.PIPE).communicate()[0]

    takze na zjisteni fragmentace to pozuiva nejaky program filefrag, ktery nemam, ale google ho celkem zna, takze asi v nekterych distribucich bude bezne.

    Samotna defragmentace probiha zkopirovanim rsyncem, takze zadna zazracna metoda se nekona.
  • 7. 1. 2008 15:49

    alpha (neregistrovaný)
    Jestli je to od e2fsprogs, jak to muze spolehlive merit fragmentaci jinych FS?
  • 7. 1. 2008 3:32

    Rejpal (neregistrovaný)
    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. ;-))
  • 7. 1. 2008 16:20

    bez přezdívky
    Musím přiznat že máš pravdu a jde to - koukal jsem na zdroják filefrag-u z e2fsprogs a dělá to úplně stejně (tj přes FIGETBSZ a FIBMAP ioctl-y). Pouze mi přijde filefrag trochu nepřesný, a to tím, že nebere v potaz jaká je vzdálenost mezi jednotlivými fragmenty - fragmentované soubory na mém reiserfs oddílu vypadají takto:
    nb-esprimo /usr/portage/distfiles # filefrag -v tetex-src-3.0_p1.tar.gz.new
    Checking tetex-src-3.0_p1.tar.gz.new
    Filesystem type is: 52654973
    Filesystem cylinder groups is approximately 80
    Blocksize of file tetex-src-3.0_p1.tar.gz.new is 4096
    File size of tetex-src-3.0_p1.tar.gz.new is 13357541 (3262 blocks)
    First block: 79879
    Last block: 84138
    Discontinuity: Block 221 is at 80101 (was 80099)      -- vzdálenost mezi fragmenty je jen 1 blok
    Discontinuity: Block 993 is at 81867 (was 80872)      -- vzdálenost ~1000 bloků (4MB)
    Discontinuity: Block 1010 is at 81885 (was 81883)     -- vzdálenost 1 blok
    Discontinuity: Block 2013 is at 82889 (was 82887)     -- 1 blok
    Discontinuity: Block 3033 is at 83910 (was 83908)     -- 1 blok
    tetex-src-3.0_p1.tar.gz.new: 6 extents found
    
    Filefrag tedy reportuje 6 fragmentů, ale prakticky jsou pouze 2 (2 čtení s díru 1 blok spojí kernel do jednoho čtení, a když to neudělá kernel, tak to spadne do disk readaheadu). Jediné, co nevím, je jestli reiserfs dělá tyto díry schválně a jsou prázdné, či jestli to jsou data jiných souborů (jednoblokových souborů mám hodně - portage), či metadata.