diff options
Diffstat (limited to 'historic/frag.c')
-rw-r--r-- | historic/frag.c | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/historic/frag.c b/historic/frag.c deleted file mode 100644 index 0098e02f2..000000000 --- a/historic/frag.c +++ /dev/null @@ -1,311 +0,0 @@ -/* frag.c - simple fragmentation checker - V1.0 by Werner Almesberger - V1.1 by Steffen Zahn, adding directory recursion - V1.2 by Rob Hooft, adding hole counts - V1.3 by Steffen Zahn, email: szahn%masterix@emndev.siemens.co.at - 14 Nov 93 - - ignore symlinks, - - don't cross filesys borders - - get filesystem block size at runtime - V1.4 by Michael Bischoff <mbi@mo.math.nat.tu-bs.de> to handle - indirect blocks better, but only for ext2fs - (applied by faith@cs.unc.edu, Sat Feb 4 22:06:27 1995) - - TODO: - handle hard links - */ - -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <sys/stat.h> -#include <sys/vfs.h> -#include <linux/fs.h> /* for FIBMAP */ - -typedef struct StackElem { - struct StackElem *backref, *next; - char name[NAME_MAX]; - char dir_seen; - char from_cmd_line; -} StackElem; - -StackElem *top = NULL; - - -void discard( void ) -{ - StackElem *se = top; - if( se == NULL ) - return ; - top = se->next; - free(se); -} - -void push( StackElem * se ) -{ - se -> next = top; - top = se; -} - -char *p2s( StackElem *se, char *path ) -{ - char *s; - if( se->backref!=NULL ) { - path = p2s( se->backref, path ); - if( path[-1]!='/' ) - *path++ = '/'; - } - s = se->name; - while( *s ) - *path++ = *s++; - return path; -} - -char *path2str( StackElem *se, char *path ) -{ - *(p2s( se, path ))=0; - return path; -} - -void *xmalloc( size_t size ) -{ - void *p; - if( (p=malloc(size))==NULL ) { - fprintf(stderr,"\nvirtual memory exhausted.\n"); - exit(1); - } - return p; -} - -int main(int argc,char **argv) -{ - int fd,last_phys_block, - fragments_in_file, blocks_in_file, - blocks,current_phys_block, - this_fragment, largest_fragment, i; - long sum_blocks=0, sum_frag_blocks=0, sum_files=0, sum_frag_files=0; - long num_hole=0, sum_hole=0, hole; - struct stat st; - struct statfs stfs; - StackElem *se, *se1; - char path[PATH_MAX], pathlink[PATH_MAX], *p; - DIR *dir; - struct dirent *de; - char silent_flag=0; - dev_t local_fs; - int block_size; - - if (argc < 2) - { - fprintf(stderr,"usage: %s [-s [-s]] filename ...\n",argv[0]); - exit(1); - } - argc--; argv++; - while (argc>0) - { - p = *argv; - if( *p=='-' ) - while( *++p ) - switch( *p ) - { - case 's': - silent_flag++; /* may be 1 or 2 */ - break; - default: - fprintf(stderr,"\nunknown flag %c\n", *p ); - exit(1); - } - else - { - se = xmalloc( sizeof(StackElem) ); - se->backref=NULL; se->dir_seen=0; se->from_cmd_line=1; - strcpy( se->name, p ); - push(se); - } - argc--; argv++; - } - while ( top != NULL) - { - se = top; - if( se->dir_seen ) - discard(); - else - { - path2str( se, path ); - if( readlink( path, pathlink, sizeof(pathlink) )>=0 ) - { /* ignore symlinks */ - if(silent_flag<1) - { - printf("symlink %s\n", path ); - } - discard(); - } - else if( stat( path,&st) < 0) - { - perror( path ); - discard(); - } - else if( !se->from_cmd_line && (local_fs!=st.st_dev) ) - { /* do not cross filesystem borders */ - if(silent_flag<2) - { - printf("different filesystem %s\n", path ); - } - discard(); - } - else - { - if( se->from_cmd_line ) - { - local_fs = st.st_dev; - if ( statfs( path, &stfs )<0 ) - { - perror( path ); - block_size = 1024; - } - else - block_size = stfs.f_bsize; - } - if( S_ISREG(st.st_mode)) /* regular file */ - { - if ( (fd = open( path ,O_RDONLY)) < 0 ) - { - perror( path ); - discard(); - } - else - { - last_phys_block = -1; - fragments_in_file = 0; - hole = 0; this_fragment=0; - largest_fragment=0; - blocks_in_file = (st.st_size+block_size-1)/block_size; - for (blocks = 0; blocks < blocks_in_file; blocks++) - { - current_phys_block = blocks; - if (ioctl(fd,FIBMAP,¤t_phys_block) < 0) - { - perror(path); - break; - } - if (current_phys_block) { /* no hole here */ - int indirect; - /* indirect is the number of indirection */ - /* blocks which must be skipped */ - indirect = 0; - /* every 256 blocks there is an indirect block, - the first of these is before block 12 */ - if (blocks >= 12 && (blocks-12) % 256 == 0) - ++indirect; - /* there is a block pointing to the indirect - blocks every 64K blocks */ - if (blocks >= 256+12 && (blocks-256-12) % 65536 == 0) - ++indirect; /* 2nd indirect block */ - /* there is a single triple indirect block */ - if (blocks == 65536 + 256 + 12) - ++indirect; - if (last_phys_block == current_phys_block-1-indirect) - this_fragment++; - else { /* start of first or new fragment */ - if( largest_fragment<this_fragment ) - largest_fragment=this_fragment; - this_fragment=1; - fragments_in_file++; - } - last_phys_block = current_phys_block; - } - else - { - hole++; - } - } - if( largest_fragment<this_fragment ) - largest_fragment=this_fragment; - blocks_in_file-=hole; - /* number of allocated blocks in file */ - if( !silent_flag ) - { - if( fragments_in_file < 2 - || blocks_in_file < 2 ) - i = 0; /* fragmentation 0 % */ - else - i = (fragments_in_file - 1) * 100 / - (blocks_in_file-1); - /* maximum fragmentation 100% - means every block is an fragment */ - printf(" %3d%% %s (%d block(s), %d fragment(s), largest %d", - i, path, blocks_in_file, - fragments_in_file,largest_fragment); - if (hole) - { - printf(", %d hole(s))\n",hole); - } - else - { - printf(")\n"); - } - } - sum_blocks+=blocks_in_file; - if (hole) - num_hole++; - sum_hole+=hole; - sum_files++; - if( fragments_in_file>1 ) - { - sum_frag_blocks+=blocks_in_file-largest_fragment; - sum_frag_files++; - } - discard(); - close(fd); - } - } - else if( S_ISDIR( st.st_mode ) ) /* push dir contents */ - { - if( (dir=opendir( path ))==NULL ) - { - perror(path); - discard(); - } - else - { - if( silent_flag<2 ) - printf("reading %s\n", path); - while( (de=readdir(dir))!=NULL ) - { - if( (strcmp(de->d_name,".")!=0) - && (strcmp(de->d_name,"..")!=0) ) - { - se1 = xmalloc( sizeof(StackElem) ); - se1->backref=se; se1->dir_seen=0; - se1->from_cmd_line=0; - strcpy( se1->name, de->d_name ); - push(se1); - } - } - closedir( dir ); - se->dir_seen=1; - } - } - else /* if( S_ISREG(st.st_mode)) */ - discard(); - } - } /* if( se->dir_seen ) */ - } /* while ( top != NULL) */ - if (sum_files>1) - { - printf("\nsummary:\n"); - printf(" %3ld%% file fragmentation (%ld of %ld files contain fragments)\n", - sum_files<1 ? 0L : sum_frag_files*100/sum_files, - sum_frag_files, sum_files); - printf(" %3ld%% block fragmentation (%ld of %ld blocks are in fragments)\n", - sum_blocks<1 ? 0L : sum_frag_blocks*100/sum_blocks, - sum_frag_blocks, sum_blocks); - if (num_hole>1) - printf(" %ld files contain %ld blocks in holes\n", - num_hole,sum_hole); - } - exit(0); -} |