# [Script]Mesurer la fragmentation sur Reiserfs (et autres)

## _droop_

Bonjour à tous,

Je me fait ma traduction : https://forums.gentoo.org/viewtopic-p-3081971.html.

Reiserfs est un système de fichier pour lequel il n'y a pas d'outil qui indique le taux de fragmentation. 

J'ai donc écrit un script en perl capable de mesurer cette fragmentation. Il nécessite l'installation du paquet e2fsprogs (mais ce paquet doît être installé par défaut sur toutes les gentoo. Il est basé sur filefrag. Et comme cette commande est scencée fonctionner sur la plupart des systèmes de fichiers (reiserfs compris), ce script devrait aussi marcher sur la plupart des systèmes de fichiers.

Le script :

```

#!/usr/bin/perl -w

#this script search for frag on a fs

use strict;

#number of files

my $files = 0;

#number of fragment

my $fragments = 0;

#number of fragmented files

my $fragfiles = 0;

#search fs for all file

open (FILES, "find " . $ARGV[0] . " -xdev -type f |");

while (defined (my $file = <FILES>)) {

        #quote some chars in filename

        $file =~ s/!/\\!/g;

        $file =~ s/#/\\#/g;

        $file =~ s/&/\\&/g;

        $file =~ s/>/\\>/g;

        $file =~ s/</\\</g;

        $file =~ s/\$/\\\$/g;

        $file =~ s/\(/\\\(/g;

        $file =~ s/\)/\\\)/g;

        $file =~ s/\|/\\\|/g;

        $file =~ s/'/\\'/g;

        $file =~ s/ /\\ /g;

        #nb of fragment for the file

        open (FRAG, "filefrag $file |");

        my $res = <FRAG>;

        if ($res =~ m/.*:\s+(\d+) extents? found/) {

                my $fragment = $1;

                $fragments+=$fragment;

                if ($fragment > 1) {

                        $fragfiles++;

                }

                $files++;

        } else {

                print ("$res : not understand for $file.\n");

        }

        close (FRAG);

}

close (FILES);

print ( $fragfiles / $files * 100 . "% non contiguous files, " . $fragments / $files . " average fragments.\n");
```

Pour l'exécuter, ecriver le dans un coin (genre /root/fragck.pl), un ti chmod u+x /root/fragck.pl et c'est parti...

Bon faut être root pour le lancer (sinon filefrag marche pas) et il faut donner le chemin de montage de la partition à analyser en argument. Le script va afficher (après quelques instants) le taux de fichier fragmenté et le nombre moyen de fragment par fichier.

Le script doit scanner tous les fichiers réguliers (?) du fs, donc ce n'est pas instantanné... Environ 5min sur ma partition root (/) qui contient environ 2go de données (/usr/portage est sur une autre partition).

Quelques examples personnels :

```
/root/fragck.pl /

5.10010105507148% non contiguous files, 1.11087084031179 average fragments.

/root/fragck.pl /divers

79.5620437956204% non contiguous files, 7060.22627737226 average fragments. 
```

Dans le meilleur des cas (partition non fractionné), le script doit afficher "0% non contiguous files, 1 average fragments.". J'ai donc une partition dans un état très fragmentée...

Il y a peut être encore quelques problèmes avec les noms de fichiers si vous constaté ce genre de problèmes, n'hesitez pas à les reporter (?), ils seront corrigés...

Voilà, j'espère que ca servira...

PS : Je n'ai pas mis de licence sur le code, faites en ce que vous en voulez. Je suis tout de même interessé par les améliorations...

PPS : le français n'est pas ma langue maternelle, n'hésitez pas à corriger mes erreurs...   :Laughing:   :Embarassed: 

----------

## TGL

Voilà aussi un petit script qui trainait (allez zou, domaine public pour moi aussi...) qui ajoute à la sortie de filefrag un « pourcentage de fragmentation ». Je pense que c'est pas mal comme métrique, parceque bon, 10 extents¹ sur un fichier de 100Ko c'est pas mal fragmenté, alors que sur un fichier de 100Mo c'est absolument négligeable. Ce pourcentage représente donc un rapport entre nombre d'extents et nombre total de blocks occupés. 

Ça marche juste avec un simple fichier en paramètre par contre : 

```
#!/bin/bash

[[ -f "${1}" ]] || exit 1

blocksize=$(stat -f -c %S "${1}")

filesize=$(ls -s --block-size=${blocksize} "${1}")

filesize=${filesize%%[^0-9]*}

if [[ ${filesize} -gt 1 ]] ; then

   extents=$(/sbin/filefrag "${1}" | sed -n 's/.*: \([0-9]\+\) extent.*/\1/p')

   fragmentation=$(bc <<<"scale=1;100*(${extents}-1)/${filesize}" )

fi

echo "${1}: ${filesize} blocks, \

${extents:-${filesize}} extents, \

${fragmentation:-0}% fragmentation"
```

Exemple d'utilisation (filefrag d'abord, et le script ensuite) : 

```
% sudo /sbin/filefrag linux-2.6.15.tar.bz2

linux-2.6.15.tar.bz2: 127 extents found, perfection would be 1 extent

% sudo /usr/local/sbin/fragmentation.sh linux-2.6.15.tar.bz2

linux-2.6.15.tar.bz2: 9970 blocks, 127 extents, 1.2% fragmentation
```

Ça serait peut-être intéressant que ton script rapporte aussi cette métrique, non ? Enfin là toi ça te ferait cumuler les blocks et les extents de ton ensemble de fichiers, mais c'est à peine plus compliqué a priori (par contre, moi le Perl... bref je te laisse faire).

¹  Pour info, et si j'ai bien compris, les extents c'est le nombre de sauts que la tête de lecture va faire pour lire le fichier en entier. Le minimum est de 1 dans le cas d'un fichier parfaitement contigu (on compte 1 pour aller au début du fichier), incrémenté à chaque rupture (quand deux blocks consécutifs sont non-contigus). Au pire cas, on a N extents pour un fichier de N blocks (100% de fragmentation).

----------

## _droop_

 *TGL wrote:*   

> Ça serait peut-être intéressant que ton script rapporte aussi cette métrique, non ? Enfin là toi ça te ferait cumuler les blocks et les extents de ton ensemble de fichiers, mais c'est à peine plus compliqué a priori (par contre, moi le Perl... bref je te laisse faire).
> 
> ¹  Pour info, et si j'ai bien compris, les extents c'est le nombre de sauts que la tête de lecture va faire pour lire le fichier en entier. Le minimum est de 1 dans le cas d'un fichier parfaitement contigu (on compte 1 pour aller au début du fichier), incrémenté à chaque rupture (quand deux blocks consécutifs sont non-contigus). Au pire cas, on a N extents pour un fichier de N blocks (100% de fragmentation).

 

Bonjour,

Ca me paraît correct et effectivement interessant comme mesure. Je l'intègres dès que possible.

Merci, pour ta contribution...

----------

## TGL

Bon bah en fait j'ai rebidouillé sur la base de mon script (erf, une soudaine envie de Bash au réveil...) pour faire ce pourcentage moyen de fragmentation sur un dossier ou point de montage. Ça donne ça : 

```
#!/bin/bash

blocksize=$(stat -f -c %s "${1}")

total_size=0 ; total_extents=0 ; total_files=0

all_files=$(find "${1}" -xdev -type f | wc -l)

find "${1}" -xdev -type f -size +${blocksize}c \

   -printf "%s " -exec filefrag {} \; \

| sed -n 's|^\([0-9]\+\) .*: \([0-9]\+\) extent.*$|\1 \2|p' \

| { while read filesize extents ; do

      ((total_size += (filesize - 1) / blocksize + 1))

      ((total_extents += extents))

      ((total_files++))

   done

   ((ignored_files = all_files - total_files))

   echo " - total number of files:   ${total_files} (ignored: ${ignored_files})"

   echo " - total files size:        ${total_size} blocks of ${blocksize} bytes"

   echo " - total number of extents: ${total_extents}"

   [[ ${total_size} -le  ${total_files} ]] && exit 0

   avg_frag=$(bc <<<"scale=1 ; \

      100 * (${total_extents} - ${total_files}) \

          / (${total_size} - ${total_files})")

   echo " - average fragmentation:   ${avg_frag}%"

}
```

Et à l'usage (un peu lent, évidemment) :

```
% sudo /usr/local/sbin/avgfrag /home/

 - total number of files:   52986 (ignored: 69357)

 - total files size:        637281 blocks of 4096 bytes

 - total number of extents: 109421

 - average fragmentation:   9.6%
```

Random notes :

 - les fichiers ignorés, c'est ceux qui occupent 0 ou 1 block, et qui donc ne sont évidemment pas fragmentés ;

 - telle que la fragmentation moyenne est calculée, elle est pondérée par la taille des fichiers considérés. Donc une partition avec un petit fichier très fragmenté à côté d'un gros bien contigu donnera un faible pourcentage moyen ; 

- oui, 9.6% ça commence à faire pas mal. Mon /home est passé par des phases où il était vraiment trop plein pour que les fichiers aient trouvé des espaces confortables, donc ça n'est pas très étonnant. Faudra que je me fasse un defrag à coup de "archivage, suppression, restauration" un de ses quatres...

EDIT : une p'tite optimisation du script...

EDIT 2 : "stat -f -c %s", cf. le post de bong.Last edited by TGL on Sat Feb 04, 2006 3:34 pm; edited 1 time in total

----------

## bong

 *TGL wrote:*   

> 
> 
> ```
> ...
> 
> ...

 

Juste pour faire remarquet que chez moi, stat ne comprend pas %S mais %s

Je suis peut être pas le seul dans ce cas   :Wink: 

----------

## TGL

 *bong wrote:*   

> Juste pour faire remarquet que chez moi, stat ne comprend pas %S mais %s
> 
> Je suis peut être pas le seul dans ce cas  

 

Argh, bien vu ! 

/usr/share/doc/coreutils-5.93/NEWS.gz me dit que c'est effectivement une nouveauté introduite dans la version 5.90. Bon bah va pour %s alors, qui aura en général la même valeur.

(je corrige au dessus)

----------

## boozo

'alute

je viens de tester (c'est chaud en ressources par rapport à celui de TGL   :Razz:  ) mais j'ai pas tout saisi... j'ai des incohérences   :Sad: 

```
fragck.pl /

print (...) interpreted as function at ./fragck.pl line 47.

4.81772165293921% non contiguous files, 1.36452847492901 average fragments.

fragck.pl /home/<user>

print (...) interpreted as function at ./fragck.pl line 47.

10.5205241068687% non contiguous files, 4.07797625140751 average fragments.
```

dans ce cas de figure, c'est la m^ partition... c'est normal çà ?  :Confused: 

* je n'ose imaginer sur /usr/portage   :Neutral:  *

----------

## Enlight

 *boozo wrote:*   

> 'alute
> 
> je viens de tester (c'est chaud en ressources par rapport à celui de TGL   ) mais j'ai pas tout saisi... j'ai des incohérences  
> 
> ```
> ...

 

Oui l'argument passé est la base de l'arbre qui va être utilisé.

Sinon @TGL je m'étais fait la même reflexion que toi, mais il se trouve qu'a priori, avec les tails (désactivables) des reisers* un fichier de taille < à la taille des blocs puisse se retrouver tout de même fragmentée (petit fichier qui grossit)

----------

## TGL

 *Enlight wrote:*   

> Sinon @TGL je m'étais fait la même reflexion que toi, mais il se trouve qu'a priori, avec les tails (désactivables) des reisers* un fichier de taille < à la taille des blocs puisse se retrouver tout de même fragmentée (petit fichier qui grossit)

 

Héhé, bien vu, très bien vu...   :Wink: 

Bon, c'est embêtant, parceque c'était bien pratique de les zapper ces fichiers : grosse accélération d'une part, et simplification du calcul d'autre part. En fait, je suis pas sûr de voir comment adapter la métrique à ce cas... Hum, faudra y réfléchir à tête plus reposée. 

Et en attendant, y'a qu'à se dire qu'il faudrait vraiment pas de bol pour que ça commence à avoir une influence sur la moyenne globale d'une partoche.  :Smile: 

(Genre parceque les petits fichiers qui grossissent, on n'en a pas des milliers en général.)

----------

## kopp

Les résultats varient énormement entre les deux scripts quand même :

```
root:kopp # ~/fragfs.pl /home

20.0923490130429% non contiguous files, 1.83743262385254 average fragments.

root:kopp # ~/fsfrag.sh /home/

 - total number of files:   28050 (ignored: 26309)

 - total files size:        9088743 blocks of 4096 bytes

 - total number of extents: 72938

 - average fragmentation:   .4%

```

Je préfère le tien TGL  :Wink: 

Enfin, apparemment, c'est le boxon sur mon /home ... m'étonne qu'à moitier  :Smile: 

----------

## TGL

 *kopp wrote:*   

> Les résultats varient énormement entre les deux scripts quand même :
> 
> ```
> root:kopp # ~/fragfs.pl /home
> 
> ...

 

Ah ouais, il a l'air bien foireux mon script quand même.   :Laughing: 

Enfin manifestement, l'hypothèse du « le bug à Enlight il est négligeable » est complètement fausse, puisque toi tu as l'air d'avoir de très nombreux fichiers de moins d'un bloc qui sont quand même fragmentés (93.8% de tes fichiers sont ignorés, donc font moins de 4Ko, mais 20.1% ont plusieurs extents d'après le script de _droop_). 

Est-ce que tu pourrais réessayer avec cette version (toujours sur ton /home/) pour voir ce qu'elle donne ? 

```
#!/bin/bash

blocksize=$(stat -f -c %s "${1}")

total_blocks=0 ; total_extents=0 ; total_files=0

total_extra_blocks=0

total_small_files=0 ; total_small_files_extents=0

find "${1}" -xdev -type f -printf "%s " -exec filefrag {} \; \

| sed -n 's|^\([0-9]\+\) .*: \([0-9]\+\) extent.*$|\1 \2|p' \

| { while read filesize nb_extents ; do ((

      total_files++, total_extents += nb_extents,

      nb_blocks = ((filesize - 1) / blocksize) + 1,

      total_small_files += (nb_blocks == 1 ? 1 : 0),

      total_small_files_extents += (nb_blocks == 1 ? nb_extents : 0),

      nb_blocks = (nb_extents >= nb_blocks ? nb_extents : nb_blocks),

      total_blocks += nb_blocks,

      total_extra_blocks += (nb_blocks > 1 ? (nb_blocks - 1) : 1)

   )) ; done

   avg_frag=$(bc <<<"scale=1 ; \

      100 * (${total_extents} - ${total_files}) \

          / ${total_extra_blocks}")

   echo " - number of files:        ${total_files}"

   echo " - number of blocks:       ${total_blocks}"

   echo " - extra blocks:           ${total_extra_blocks}"

   echo " - number of extents:      ${total_extents}"

   echo " - number of small files:  ${total_small_files}"

   echo " - extents in small files: ${total_small_files_extents}"

   echo " - average fragmentation:  ${avg_frag}%"

}
```

 Je te préviens, ça va être pas mal plus lent par contre... 

La différence importante, c'est qu'elle essaye de prendre en compte la fragmentation des petits fichiers.  Par exemple, si sur une partoche on a :

 - 1 petit fichier de <4Ko fragmenté à 3 extents,

 - 1 fichier de 10Ko (3 blocs donc) parfaitement contigu (1 seul extent),

... alors la moyenne de fragmentation sera de 50%.

Bon, ça vaut ce que ça vaut, et ça représente pas forcement grand chose de concret, mais ça devrait donner une intuition plus fidèle de l'état de la partoche dans des cas comme le tiens.

----------

## kopp

Mauvais nouvelle, ça me donne le même résultat ...

```
root:kopp # time ~/fsfrag2.sh /home/

 - number of files:        52630

 - number of blocks:       9122449

 - extra blocks:           9094347

 - number of extents:      97825

 - number of small files:  24528

 - extents in small files: 24528

 - average fragmentation:  .4%

real    3m11.863s

user    0m41.477s

sys     2m5.780s

```

Comme j'suis pas un expert en bash, je peux pas vraiment t'aider pour voir d'où ça pourrait venir...

----------

## TGL

 *kopp wrote:*   

> Mauvais nouvelle, ça me donne le même résultat ...

 

Bonne nouvelle, c'est moi qui suis un gros boulet...  :Embarassed: 

 *TGL wrote:*   

>  *kopp wrote:*   
> 
> ```
> root:kopp # ~/fsfrag.sh /home/
> 
> ...

 

 :Embarassed:   :Embarassed:   :Embarassed: 

Tu n'avais évidement pas 93.8% ("26309/28050") de fichiers ignorés, mais 48.4% ("26309/(26309+28050)"). Donc en fait il n'y avais rien de surprenant à ces 20.1% de fichiers fragmentés ; ils sont dans les autres 51.6%, ce sont bien des fichiers de taille >4Ko, et donc il est aussi normal que le second script que je t'ai proposé rende le même résultat global.

Bref, tu peux ignorer mon précédent message, écrit probablement  sous le coup d'une trop courte grasse matinée, et te rassurer quant à l'état de ta partition /home :

 - la moitié des fichiers font moins d'un block (sans aucune fragmentation) ;

 - parmi l'autre moitié, il y en a ~40% (20.1% de la totalité) qui sont fragmentés... mais ils le sont vraiment très peu relativement à leur taille : le 0.4%, c'est ça qui compte, et c'est complètement négligeable.

----------

## kopp

C'est vrai que ta moyenne est pondérée. 

Tiens d'autres résultats comparatifs :

```
root:kopp # time ~/fsfrag2.sh /usr/

 - number of files:        390717

 - number of blocks:       2277403

 - extra blocks:           2145934

 - number of extents:      627084

 - number of small files:  259248

 - extents in small files: 259248

 - average fragmentation:  11.0%

real    16m50.123s

user    4m59.922s

sys     8m43.308s

root:kopp # time ~/fragfs.pl /usr

23.7320106368548% non contiguous files, 1.60495704051782 average fragments.

real    18m21.795s

user    2m28.995s

sys     9m59.494s

```

(tiens, celui en bash est plus rapide  :Smile: )

Là par contre, c'est pas mal fragmenté.

Bon, j'ai beaucoup de fichier dans /usr/portage/distfiles, donc ça pondère pas mal je pense. (miam les grosses archives d'openoffice et autres  :Smile:  : 

```
root:kopp # du -sh /usr/portage/distfiles/

3,6G    /usr/portage/distfiles/
```

 je devrais peut etre faire du vide)

Bon, merci pour ce script, c'est assez intéressant. Bon, maintenant je vous laisse faire un défragmenteur façon windows  :Smile: 

----------

## TGL

 *kopp wrote:*   

> 
> 
> ```
> root:kopp # time ~/fsfrag2.sh /usr/
> ```
> ...

 

Hésite pas à repasser à la version précédente du script (celle qui zappe les petits fichiers), vu que l'hypothèse « les fichiers de moins de 4Ko ne sont pas fragmentés en général » est à nouveau très plausible (d'ailleurs, ici comme sur ton /home, on a "extents in small files" == "number of small files", ce qui montre que ça ne servait à rien de les prendre en compte). Tu gagneras pas mal de temps...

 *Quote:*   

> Là par contre, c'est pas mal fragmenté.

 

Barf, 11% c'est pas la mort non plus, même si ça commence à faire. Le problème en fait, c'est que pour mesurer l'impact réel de cette fragmentation, il faudrait pondérer le caclul d'après la fréquence d'usage des fichiers concernés. Genre les sources d'OOo dans tes distfiles, même si elles sont fragmentées à 50%, tu t'en fiche complètement, parceque ça va juste te faire perdre genre 1/10ème de seconde sur l'unpack, et que tu ne le fais probablement pas 100 fois par jour...

Mais malheureusement, ce profiling de l'usage de nos fichiers, il n'est pas évident à obtenir... (Si quelqu'un connais un moyen de surveiller tout ça pour obtenir des jolies stats sans écrouler la machine non plus, je suis preneur !)

 *Quote:*   

> Bon, j'ai beaucoup de fichier dans /usr/portage/distfiles, donc ça pondère pas mal je pense. (miam les grosses archives d'openoffice et autres  : 
> 
> ```
> root:kopp # du -sh /usr/portage/distfiles/
> 
> ...

 

Facile  :Wink:  : 

```
# emerge gentoolkit

# man eclean
```

EDIT : ah, nan, mince, tu connaissais déjà, cf. mon thread sur le sujet.

 *Quote:*   

> Bon, maintenant je vous laisse faire un défragmenteur façon windows 

 

J'en ai un, mais pas vraiment scriptable  :Laughing:  :

 - booter depuis un LiveCD

 - faire un gros tar.gz de la partoche à défragmenter (sur une autre partoche, évidement)

 - effacer tout le contenu de la partoche à défragmenter

 - le restaurer depuis le tar.gz

----------

## PabOu

_droop_ : un problème avec ton script, et comme tu l'as demandé, je le "reporte" :

 *Quote:*   

> sh: -c: line 0: unexpected EOF while looking for matching ``'
> 
> sh: -c: line 1: syntax error: unexpected end of file
> 
> Use of uninitialized value in pattern match (m//) at ./fragmentation.sh line 32.
> ...

 

le caractere ` pose probleme.

un fichier ayant 2 fois ce caractère donne un output légèrement différent :

 *Quote:*   

> sh: no: command not found
> 
> statfs: No such file or directory
> 
> Use of uninitialized value in pattern match (m//) at ./fragmentation.sh line 32.
> ...

 

remarquez le "no" qui apparement est pris comme une commande (je n'ai aucune connaissance du langage perl)

Je n'ai pas essayé le script de TGL, car ca prend du temps tout ca ;)

 *Quote:*   

> 64.1462441643576% non contiguous files, 37.6285674239075 average fragments.
> 
> real    9m8.019s
> 
> user    2m45.020s
> ...

 

----------

## PabOu

 *Quote:*   

> chocolat ~ # time ./fragmentation.sh /home/
> 
> 64.1462441643576% non contiguous files, 37.6285674239075 average fragments.
> 
> real 9m8.019s
> ...

 

 *Quote:*   

> chocolat ~ # time ./fragmentation-tgl1.sh /home/
> 
>  - total number of files:   86686 (ignored: 6102)
> 
>  - total files size:        31964055 blocks of 4096 bytes
> ...

 

 *Quote:*   

> chocolat ~ # time ./fragmentation-tgl2.sh /home/
> 
>  - number of files:        92788
> 
>  - number of blocks:       31970158
> ...

 

bizarre, le 2eme script de TGL sensé etre plus lent est en fait plus rapide !

comment doit-on interpreter la différence de résultats entres le script de _droop_ et celui (ceux) de TGL ?

----------

## TGL

 *PabOu wrote:*   

> bizarre, le 2eme script de TGL sensé etre plus lent est en fait plus rapide !

 

Il est plus lent en ça qu'il vérifie la fragmentation sur plus de fichiers (il inclue ceux de moins d'un bloc). Mais comme tu as lancé l'autre avant, tu as sûrement un bon morceau de ton /home en cache, donc ça va plus vite parceque le disque gratte moins.

 *Quote:*   

> comment doit-on interpreter la différence de résultats entres le script de _droop_ et celui (ceux) de TGL ?

 

Le script de _droop_ compte les fichiers fragmentés (indépendament de leur taille), et le miens compte les blocs fragmentés (donc un gros fichier fragmenté en 100 morceaux pèse plus sur le résultat qu'un petit fragmenté en 10 morceaux).

Je pense que ma métrique est plus représentative de l'état de la partition, mais en même temps, ça n'est pas forcément ça qui compte : seul l'usage qu'on fait des fichiers détermine vraiment la gravité de leur fragmentation. Par exemple, avec mon script, un fichier de 700Mo extrêmement fragmenté (certains logiciels de p2p provoquent ça il me semble) peut influer très négativement sur le pourcentage global. Mais si il s'agit d'un film que tu vas mater une fois avant de l'effacer, bah tu t'en fiches pas mal... Le disque grattera un peu plus pendant la lecture, et alors ?

Bref, c'est rigolo toutes ces stats, mais bon, c'est pas forcement complètement pertinent, et en tout cas pas facile à interpréter...

Ceci dit, tant que je suis là, je vous colle la dernière version de mon script, que j'avais retouché un peu il y a quelques temps. Il prend des options et tout et tout maintenant, ça fait vachement plus mieux : 

```
#!/bin/bash

PROGRAM_NAME=$(basename "${0}")

die() { echo "${*}" >&2 ; exit 1 ; }

usage() {

   echo "\

Usage: ${PROGRAM_NAME} [option ...] <path> [<path> ...]

       ${PROGRAM_NAME} --help

Options:

  -s,--small-files  also inspect small (less than 1 block) files

                    (much slower, and very likely useless)

  -v,--verbose      display more infos

  -h,--help         show this help screen"

}

unset SMALL_FILES VERBOSE SEVERAL_ARGS

while [[ ${#} -gt 0 ]] ; do

   case ${1} in

      -s|--small-files) SMALL_FILES=yes ; shift;;

      -v|--verbose) VERBOSE=yes ; shift;;

      -h|--help) usage ; exit 0 ;;

      --) shift; break;;

      -*) echo "Invalid option: ${1}" >&2 ; usage >&2 ; exit 2 ;;

      *) break;;

   esac

done

[[ ${#} -eq 0 ]] && { usage >&2 ; exit 2 ; }

[[ ${#} -gt 1 ]] && SEVERAL_ARGS=yes

[[ -z $(which filefrag 2>/dev/null) ]] \

   && die "This script needs the \"filefrag\" command."

[[ -z $(which bc 2>/dev/null) ]] \

   && die "This script needs the \"bc\" command."

[[ $USER == root ]] || [[ $(id -u) == 0 ]] \

   || die "You must be root to run this script."

do_stuffs() {

   local blocksize=$(stat -f -c %s "${1}")

   local block_divisor

   ((block_divisor = blocksize / 512))

   local size_limit skipped_files

   if [[ ${SMALL_FILES} != "yes" ]] ; then

      size_limit="-size +${blocksize}c"

      skipped_files=$(find "${1}" -xdev -type f \

         -size ${blocksize}c -o -size -${blocksize}c | wc -l)

   fi

   find "${1}" -xdev -type f ${size_limit} -printf "%b " -exec filefrag {} \; \

   | sed -n 's|^\([0-9]\+\) .*: \([0-9]\+\) extent.*$|\1 \2|p' \

   | {

      total_blocks=0

      total_frag_blocks=0

      total_files=0

      total_extra_blocks=0

      while read nb_blocks nb_extents ; do ((

         total_files++, total_frag_blocks += nb_extents - 1,

         nb_blocks = ((nb_blocks - 1) / block_divisor) + 1,

         nb_blocks = (nb_extents >= nb_blocks ? nb_extents : nb_blocks),

         total_blocks += nb_blocks,

         total_extra_blocks += (nb_blocks > 1 ? (nb_blocks - 1) : 1)

      )) ; done

      if [[ -n ${skipped_files} ]] ; then

         ((total_extra_blocks += skipped_files))

         ((total_blocks += skipped_files))

      fi

      avg_frag=$(bc <<<"scale=2 ; \

         100 * ${total_frag_blocks} / ${total_extra_blocks}")

      if [[ $VERBOSE == "yes" ]] ; then

         echo " - inspected files:       ${total_files}"

         [[ ${SMALL_FILES} != "yes" ]] && \

            echo " - fast skipped files:    ${skipped_files}"

         echo " - number of blocks:      ${total_blocks}"

         echo " - fragmented blocks:     ${total_frag_blocks}"

         echo " - average fragmentation: ${avg_frag}%"

      else

         echo "${avg_frag}%"

      fi

   }

}

while [[ ${#} -gt 0 ]] ; do

   if [[ -n ${SEVERAL_ARGS} ]] ;then

      if [[ $VERBOSE == "yes" ]] ; then

         echo "-------------"

         echo "${1}:"

      else

         echo -n "${1}: "

      fi

   fi

   do_stuffs "${1}" ; shift

done
```

Ah et puis oui, toujours tant que je suis là, faut que je cause quand même d'un outil que j'ai découvert depuis : davl tools. Il a une jolie GUI qui va vous dessiner les blocs de votre partition et tout et tout, bref là on rentre dans la cour des grands. La métrique qu'il rapporte est très proche de celle de mon script, elle diffère juste dans le cas où on a beacoup de très petits fichiers (1 block, et donc non-fragmentés) : lui les prends en compte pour faire un peu baisser le pourcentage global, et moi non. Une autre différence, c'est qu'il compte aussi les blocs occupés par les répertoires, mais bon, quantitativement ça va pas faire des variations énormes. Par contre je crois qu'il ne fonctionne que pour les partoches ext{2,3}.

Un ebuild est dispo ici : bug #120182.

----------

## titoucha

 *Quote:*   

> Par contre je crois qu'il ne fonctionne que pour les partoches ext{2,3}. 

 

Il ne fonctionne que pour ext2 et 3 c'est bien indiqué dans la doc, ce qui limite tout de suite son utilisation, sinon il me rappelle fortement l'interface d'un programme qui tourne sous un autre OS.   :Mr. Green: 

----------

## Qc_Fox

c'est bien beau de savoir le niveau de fragmentation mais y a t'il des moyen pour le defragmenter

----------

## PabOu

Oui, tu déplaces tout sur une autre partition et puis tu remets tout en place. Pour gagner un peu d'espace sur la partition temporaire, tu peux utiliser une archive tar.

----------

## Enlight

XFS a un outil de defrag, mais bon pour ce qu'il sert : mrgreen:, ext3 en a un également il me semble, pour reiser3.6 il me semble que Con Kolivas maintient un outil de défrag, et pour reiser4 selon ce qu'indique la doc, il suffirait de laisser l'ordi allumé un moment en évitant au max les I/O.

edit le defragmenter online n'est pas/plus dans le design reiser-4 (mais toujours sur la première page de namesys)

----------

## cylgalad

Défragmenter, c'est une légende urbaine, je ne vois aucune différence entre un windaube fragmenté et un défragmenté, alors sous Linux où la fragmentation est minimale, aucun intérêt ! Sur un vieux 486 ou Pentium je veux bien qu'on puisse sentir une différence mais avec les PCs actuels, j'en doute...

----------

## PabOu

Oh que non, la défragmentation est encore et toujours tres pratique.

Surtout si on est adepte du peer2peer...

----------

## Enlight

 *cylgalad wrote:*   

> Défragmenter, c'est une légende urbaine, je ne vois aucune différence entre un windaube fragmenté et un défragmenté, alors sous Linux où la fragmentation est minimale, aucun intérêt ! Sur un vieux 486 ou Pentium je veux bien qu'on puisse sentir une différence mais avec les PCs actuels, j'en doute...

 

ouh là si tu vois pas la différence, je vote la cure de vitamine C (des benchs r4 montrent des perfs du simple au double)! Et la fragmentation minimale selon le FS ça reste à voir.

Maintenant sous win si t'es fragmenté à mort faut au moins lancer 3,4 défrag à la suite, sinon ça reste la m... absolue.

----------

## PabOu

 *Enlight wrote:*   

> Maintenant sous win si t'es fragmenté à mort faut au moins lancer 3,4 défrag à la suite, sinon ça reste la m... absolue.

 

Sous win, j'utilise un autre outil que le defrag de microsoft : contig (avec le GUI Power Defragmenter). Ils sont tous les 2 en libre téléchargement sur le web. C'est pratique pour défragmenter des fichiers (et non pas une partition) et puis il donne plein d'infos ;) Mais c'est vrai que parfois le lancer plusieurs fois est nécessaire (et surtout, le faire apres avoir vidé la corbeille, les repertoires temporaires et les repertoires cache)

En fait, c'est un outil comme ca qu'il me manque sous linux

----------

