1 /*
2  * Author: Don Capps
3  * 3/13/2006
4  *
5  *       Author: Don Capps (capps@iozone.org)
6  *               7417 Crenshaw
7  *               Plano, TX 75025
8  *
9  *  Copyright 2006, 2007, 2008, 2009   Don Capps.
10  *
11  *  License to freely use and distribute this software is hereby granted
12  *  by the author, subject to the condition that this copyright notice
13  *  remains intact.  The author retains the exclusive right to publish
14  *  derivative works based on this work, including, but not limited to,
15  *  revised versions of this work",
16  *
17  *
18   fileop [-f X ]|[-l # -u #] [-s Y] [-e] [-b] [-w] [-d <dir>] [-t] [-v] [-h]
19        -f #      Force factor. X^3 files will be created and removed.
20        -l #      Lower limit on the value of the Force factor.
21        -u #      Upper limit on the value of the Force factor.
22        -s #      Optional. Sets filesize for the create/write. May use suffix 'K' or 'M'.
23        -e        Excel importable format.
24        -b        Output best case.
25        -w        Output worst case.
26        -d <dir>  Specify starting directory.
27        -U <dir>  Mount point to remount between tests.
28        -t        Verbose output option.
29        -v        Version information.
30        -h        Help text.
31  *
32  * X is a force factor. The total number of files will
33  *   be X * X * X   ( X ^ 3 )
34  *   The structure of the file tree is:
35  *   X number of Level 1 directories, with X number of
36  *   level 2 directories, with X number of files in each
37  *   of the level 2 directories.
38  *
39  *   Example:  fileop 2
40  *
41  *           dir_1                        dir_2
42  *          /     \                      /     \
43  *    sdir_1       sdir_2          sdir_1       sdir_2
44  *    /     \     /     \          /     \      /     \
45  * file_1 file_2 file_1 file_2   file_1 file_2 file_1 file_2
46  *
47  * Each file will be created, and then 1 byte is written to the file.
48  *
49  */
50 
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <fcntl.h>
54 #include <sys/time.h>
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <signal.h>
58 #include <unistd.h>
59 #include <dirent.h>
60 #include <string.h>
61 
62 #include <limits.h>
63 
64 #if defined(Windows)
65 #include <Windows.h>
66 #endif
67 #if !defined(PATH_MAX)
68 #define PATH_MAX 255
69 #endif
70 
71 #if defined(_SUA_)
72 extern char *optarg;
73 extern char *opterr;
74 int fsync();
75 int getopt();
76 #endif
77 int junk, *junkp;
78 int x,excel;
79 int verbose = 0;
80 int sz = 1;
81 char *mbuffer;
82 int incr = 1;
83 #define _STAT_CREATE 0
84 #define _STAT_WRITE 1
85 #define _STAT_CLOSE 2
86 #define _STAT_LINK 3
87 #define _STAT_UNLINK 4
88 #define _STAT_DELETE 5
89 #define _STAT_STAT 6
90 #define _STAT_ACCESS 7
91 #define _STAT_CHMOD 8
92 #define _STAT_READDIR 9
93 #define _STAT_DIR_CREATE 10
94 #define _STAT_DIR_DELETE 11
95 #define _STAT_READ 12
96 #define _STAT_OPEN 13
97 #define _STAT_DIR_TRAVERSE 14
98 #define _NUM_STATS 15
99 struct stat_struct {
100 	double starttime;
101 	double endtime;
102 	double speed;
103 	double best;
104 	double worst;
105 	double dummy;
106 	double total_time;
107 	double dummy1;
108 	long long counter;
109 } volatile stats[_NUM_STATS];
110 
111 
112 static double time_so_far(void);
113 void dir_create(int);
114 void dir_traverse(int);
115 void dir_delete(int);
116 void file_create(int);
117 void file_stat(int);
118 void file_access(int);
119 void file_chmod(int);
120 void file_readdir(int);
121 void file_delete(int);
122 void file_link(int);
123 void file_unlink(int);
124 void file_read(int);
125 void splash(void);
126 void usage(void);
127 void clear_stats();
128 int validate(char *, int , char );
129 
130 #define THISVERSION "        $Revision: 1.63 $"
131 /*#define NULL 0*/
132 
133 char version[]=THISVERSION;
134 char thedir[PATH_MAX]="."; /* Default is to use the current directory */
135 const char *mountname=NULL; /* Default is not to unmount anything between the tests */
136 
137 int cret;
138 int lower, upper,range;
139 int i;
140 int best, worst;
141 int dirlen;
142 
143 /************************************************************************/
144 /* Routine to purge the buffer cache by unmounting drive.		*/
145 /************************************************************************/
purge_buffer_cache()146 void purge_buffer_cache()
147 {
148 	if (!mountname)
149 		return;
150 
151 	char cwd[PATH_MAX];
152 	char command[1024];
153 	int ret,i;
154 
155 	junkp=(int *)getcwd(cwd, sizeof(cwd));
156 	junk=chdir("/");
157 	strcpy(command,"umount ");
158 	strcat(command, mountname);
159         /*
160            umount might fail if the device is still busy, so
161            retry unmounting several times with increasing delays
162         */
163         for (i = 1; i < 10; ++i) {
164                ret = system(command);
165                if (ret == 0)
166                        break;
167                sleep(i); /* seconds */
168         }
169 	strcpy(command,"mount ");
170 	strcat(command, mountname);
171 	junk=system(command);
172 	junk=chdir(cwd);
173 }
174 
main(int argc,char ** argv)175 int main(int argc, char **argv)
176 {
177 	if(argc == 1)
178 	{
179 		usage();
180 		exit(1);
181 	}
182 	while((cret = getopt(argc,argv,"hbwetvf:s:l:u:d:U:i: ")) != EOF){
183 		switch(cret){
184                 case 'h':
185                         usage();
186                         exit(0);
187                         break;
188                 case 'd' :
189                         dirlen=strlen(optarg);
190                         if (optarg[dirlen-1]=='/')
191                           --dirlen;
192                         strncpy(thedir, optarg, dirlen);
193 			thedir[dirlen] = 0;
194                         break;
195 		case 'U':
196 			mountname = optarg;
197 			break;
198 		case 'i':	/* Increment force by */
199 			incr=atoi(optarg);
200 			if(incr < 0)
201 				incr=1;
202 			break;
203 		case 'f':	/* Force factor */
204 			x=atoi(optarg);
205 			if(x < 0)
206 				x=1;
207 			break;
208 		case 's':	/* Size of files */
209                         sz=atoi(optarg);
210                         if(optarg[strlen(optarg)-1]=='k' ||
211                                 optarg[strlen(optarg)-1]=='K'){
212                                 sz = (1024 * atoi(optarg));
213                         }
214                         if(optarg[strlen(optarg)-1]=='m' ||
215                                 optarg[strlen(optarg)-1]=='M'){
216                                 sz = (1024 * 1024 * atoi(optarg));
217                         }
218 			if(sz < 0)
219 				sz=1;
220 			break;
221 		case 'l':	/* lower force value */
222 			lower=atoi(optarg);
223 			range=1;
224 			if(lower < 0)
225 				lower=1;
226 			break;
227 		case 'v':	/* version */
228 			splash();
229 			exit(0);
230 			break;
231 		case 'u':	/* upper force value */
232 			upper=atoi(optarg);
233 			range=1;
234 			if(upper < 0)
235 				upper=1;
236 			break;
237 		case 't':	/* verbose */
238 			verbose=1;
239 			break;
240 		case 'e':	/* Excel */
241 			excel=1;
242 			break;
243 		case 'b':	/* Best */
244 			best=1;
245 			break;
246 		case 'w':	/* Worst */
247 			worst=1;
248 			break;
249 		}
250 	}
251 	mbuffer=(char *)malloc(sz);
252 	memset(mbuffer,'a',sz);
253 	if(!excel)
254 	  printf("\nFileop:  Working in %s, File size is %d,  Output is in Ops/sec. (A=Avg, B=Best, W=Worst)\n", thedir, sz);
255 	if(!verbose)
256 	{
257 #ifdef Windows
258 	   	printf(" .     %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %10s\n",
259        	   	"mkdir","chdir","rmdir","create","open","read","write","close","stat",
260 		"access","chmod","readdir","delete"," Total_files");
261 #else
262 
263 	   	printf(" .     %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s %10s\n",
264        	   	"mkdir","chdir","rmdir","create","open", "read","write","close","stat",
265 		"access","chmod","readdir","link  ","unlink","delete",
266 		" Total_files");
267 #endif
268 	}
269 	junk=chdir(thedir); /* change starting point */
270 	if(x==0)
271 		x=1;
272 	if(range==0)
273 		lower=upper=x;
274 	for(i=lower;i<=upper;i+=incr)
275 	{
276 		clear_stats();
277 		x=i;
278 	   /*
279 	    * Dir Create test
280 	    */
281 	   purge_buffer_cache();
282 	   dir_create(x);
283 
284 	   if(verbose)
285 	   {
286 	      printf("mkdir:   Dirs = %9lld ",stats[_STAT_DIR_CREATE].counter);
287 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_DIR_CREATE].total_time);
288 	      printf("         Avg mkdir(s)/sec     = %12.2f (%12.9f seconds/op)\n",
289 			stats[_STAT_DIR_CREATE].counter/stats[_STAT_DIR_CREATE].total_time,
290 			stats[_STAT_DIR_CREATE].total_time/stats[_STAT_DIR_CREATE].counter);
291 	      printf("         Best mkdir(s)/sec    = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_CREATE].best,stats[_STAT_DIR_CREATE].best);
292 	      printf("         Worst mkdir(s)/sec   = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_CREATE].worst,stats[_STAT_DIR_CREATE].worst);
293 	   }
294 
295 	   /*
296 	    * Dir Traverse test
297 	    */
298 	   purge_buffer_cache();
299 	   dir_traverse(x);
300 
301 	   if(verbose)
302 	   {
303 	      printf("chdir:   Dirs = %9lld ",stats[_STAT_DIR_TRAVERSE].counter);
304 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_DIR_TRAVERSE].total_time);
305 	      printf("         Avg chdir(s)/sec     = %12.2f (%12.9f seconds/op)\n",
306 			stats[_STAT_DIR_TRAVERSE].counter/stats[_STAT_DIR_TRAVERSE].total_time,
307 			stats[_STAT_DIR_TRAVERSE].total_time/stats[_STAT_DIR_TRAVERSE].counter);
308 	      printf("         Best chdir(s)/sec    = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_TRAVERSE].best,stats[_STAT_DIR_TRAVERSE].best);
309 	      printf("         Worst chdir(s)/sec   = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_TRAVERSE].worst,stats[_STAT_DIR_TRAVERSE].worst);
310 	   }
311 
312 	   /*
313 	    * Dir delete test
314 	    */
315 	   purge_buffer_cache();
316 	   dir_delete(x);
317 
318 	   if(verbose)
319 	   {
320 	   printf("rmdir:   Dirs = %9lld ",stats[_STAT_DIR_DELETE].counter);
321 	   printf("Total Time = %12.9f seconds\n",stats[_STAT_DIR_DELETE].total_time);
322 	   printf("         Avg rmdir(s)/sec     = %12.2f (%12.9f seconds/op)\n",
323 			stats[_STAT_DIR_DELETE].counter/stats[_STAT_DIR_DELETE].total_time,
324 			stats[_STAT_DIR_DELETE].total_time/stats[_STAT_DIR_DELETE].counter);
325 	   printf("         Best rmdir(s)/sec    = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_DELETE].best,stats[_STAT_DIR_DELETE].best);
326 	   printf("         Worst rmdir(s)/sec   = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_DELETE].worst,stats[_STAT_DIR_DELETE].worst);
327 	   }
328 
329 	   /*
330 	    * Create test
331 	    */
332 	   purge_buffer_cache();
333 	   file_create(x);
334 	   if(verbose)
335 	   {
336 	      printf("create:  Files = %9lld ",stats[_STAT_CREATE].counter);
337 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_CREATE].total_time);
338 	      printf("         Avg create(s)/sec    = %12.2f (%12.9f seconds/op)\n",
339 			stats[_STAT_CREATE].counter/stats[_STAT_CREATE].total_time,
340 			stats[_STAT_CREATE].total_time/stats[_STAT_CREATE].counter);
341 	      printf("         Best create(s)/sec   = %12.2f (%12.9f seconds/op)\n",
342 			1/stats[_STAT_CREATE].best,stats[_STAT_CREATE].best);
343 	      printf("         Worst create(s)/sec  = %12.2f (%12.9f seconds/op)\n\n",
344 			1/stats[_STAT_CREATE].worst,stats[_STAT_CREATE].worst);
345 	      printf("write:   Files = %9lld ",stats[_STAT_WRITE].counter);
346 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_WRITE].total_time);
347 	      printf("         Avg write(s)/sec     = %12.2f (%12.9f seconds/op)\n",
348 			stats[_STAT_WRITE].counter/stats[_STAT_WRITE].total_time,
349 			stats[_STAT_WRITE].total_time/stats[_STAT_WRITE].counter);
350 	      printf("         Best write(s)/sec    = %12.2f (%12.9f seconds/op)\n",
351 			1/stats[_STAT_WRITE].best,stats[_STAT_WRITE].best);
352    	      printf("         Worst write(s)/sec   = %12.2f (%12.9f seconds/op)\n\n",
353 			1/stats[_STAT_WRITE].worst,stats[_STAT_WRITE].worst);
354 	      printf("close:   Files = %9lld ",stats[_STAT_CLOSE].counter);
355 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_CLOSE].total_time);
356 	      printf("         Avg close(s)/sec     = %12.2f (%12.9f seconds/op)\n",
357 			stats[_STAT_CLOSE].counter/stats[_STAT_CLOSE].total_time,
358 			stats[_STAT_CLOSE].total_time/stats[_STAT_CLOSE].counter);
359 	      printf("         Best close(s)/sec    = %12.2f (%12.9f seconds/op)\n",
360 			1/stats[_STAT_CLOSE].best,stats[_STAT_CLOSE].best);
361 	      printf("         Worst close(s)/sec   = %12.2f (%12.9f seconds/op)\n\n",
362 			1/stats[_STAT_CLOSE].worst,stats[_STAT_CLOSE].worst);
363 	   }
364 
365 	   /*
366 	    * Stat test
367 	    */
368 	   purge_buffer_cache();
369 	   file_stat(x);
370 
371 	   if(verbose)
372 	   {
373 	      printf("stat:    Files = %9lld ",stats[_STAT_STAT].counter);
374 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_STAT].total_time);
375 	      printf("         Avg stat(s)/sec      = %12.2f (%12.9f seconds/op)\n",
376 			stats[_STAT_STAT].counter/stats[_STAT_STAT].total_time,
377 			stats[_STAT_STAT].total_time/stats[_STAT_STAT].counter);
378 	      printf("         Best stat(s)/sec     = %12.2f (%12.9f seconds/op)\n",
379 			1/stats[_STAT_STAT].best,stats[_STAT_STAT].best);
380 	      printf("         Worst stat(s)/sec    = %12.2f (%12.9f seconds/op)\n\n",
381 			1/stats[_STAT_STAT].worst,stats[_STAT_STAT].worst);
382 	   }
383 	   /*
384 	    * Read test
385 	    */
386 	   purge_buffer_cache();
387 	   file_read(x);
388 
389 	   if(verbose)
390 	   {
391 	      printf("open:    Files = %9lld ",stats[_STAT_OPEN].counter);
392 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_OPEN].total_time);
393 	      printf("         Avg open(s)/sec      = %12.2f (%12.9f seconds/op)\n",
394 			stats[_STAT_OPEN].counter/stats[_STAT_OPEN].total_time,
395 			stats[_STAT_OPEN].total_time/stats[_STAT_OPEN].counter);
396 	      printf("         Best open(s)/sec     = %12.2f (%12.9f seconds/op)\n",
397 			1/stats[_STAT_OPEN].best,stats[_STAT_OPEN].best);
398 	      printf("         Worst open(s)/sec    = %12.2f (%12.9f seconds/op)\n\n",
399 			1/stats[_STAT_OPEN].worst,stats[_STAT_OPEN].worst);
400 
401 	      printf("read:    Files = %9lld ",stats[_STAT_READ].counter);
402 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_READ].total_time);
403 	      printf("         Avg read(s)/sec      = %12.2f (%12.9f seconds/op)\n",
404 			stats[_STAT_READ].counter/stats[_STAT_READ].total_time,
405 			stats[_STAT_READ].total_time/stats[_STAT_READ].counter);
406 	      printf("         Best read(s)/sec     = %12.2f (%12.9f seconds/op)\n",
407 			1/stats[_STAT_READ].best,stats[_STAT_READ].best);
408 	      printf("         Worst read(s)/sec    = %12.2f (%12.9f seconds/op)\n\n",
409 			1/stats[_STAT_READ].worst,stats[_STAT_READ].worst);
410 	   }
411 
412 	   /*
413 	    * Access test
414 	    */
415 	   purge_buffer_cache();
416 	   file_access(x);
417 	   if(verbose)
418 	   {
419 	      printf("access:  Files = %9lld ",stats[_STAT_ACCESS].counter);
420 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_ACCESS].total_time);
421 	      printf("         Avg access(s)/sec    = %12.2f (%12.9f seconds/op)\n",
422 			stats[_STAT_ACCESS].counter/stats[_STAT_ACCESS].total_time,
423 			stats[_STAT_ACCESS].total_time/stats[_STAT_ACCESS].counter);
424 	      printf("         Best access(s)/sec   = %12.2f (%12.9f seconds/op)\n",
425 			1/stats[_STAT_ACCESS].best,stats[_STAT_ACCESS].best);
426 	      printf("         Worst access(s)/sec  = %12.2f (%12.9f seconds/op)\n\n",
427 			1/stats[_STAT_ACCESS].worst,stats[_STAT_ACCESS].worst);
428 	   }
429 	   /*
430 	    * Chmod test
431 	    */
432 	   purge_buffer_cache();
433 	   file_chmod(x);
434 
435 	   if(verbose)
436 	   {
437 	      printf("chmod:   Files = %9lld ",stats[_STAT_CHMOD].counter);
438 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_CHMOD].total_time);
439 	      printf("         Avg chmod(s)/sec     = %12.2f (%12.9f seconds/op)\n",
440 			stats[_STAT_CHMOD].counter/stats[_STAT_CHMOD].total_time,
441 			stats[_STAT_CHMOD].total_time/stats[_STAT_CHMOD].counter);
442 	      printf("         Best chmod(s)/sec    = %12.2f (%12.9f seconds/op)\n",
443 			1/stats[_STAT_CHMOD].best,stats[_STAT_CHMOD].best);
444 	      printf("         Worst chmod(s)/sec   = %12.2f (%12.9f seconds/op)\n\n",
445 			1/stats[_STAT_CHMOD].worst,stats[_STAT_CHMOD].worst);
446 	   }
447 	   /*
448 	    * readdir test
449 	    */
450 	   purge_buffer_cache();
451 	   file_readdir(x);
452 
453 	   if(verbose)
454 	   {
455 	      printf("readdir: Files = %9lld ",stats[_STAT_READDIR].counter);
456 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_READDIR].total_time);
457 	      printf("         Avg readdir(s)/sec   = %12.2f (%12.9f seconds/op)\n",
458 			stats[_STAT_READDIR].counter/stats[_STAT_READDIR].total_time,
459 			stats[_STAT_READDIR].total_time/stats[_STAT_READDIR].counter);
460 	      printf("         Best readdir(s)/sec  = %12.2f (%12.9f seconds/op)\n",
461 			1/stats[_STAT_READDIR].best,stats[_STAT_READDIR].best);
462 	      printf("         Worst readdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n",
463 			1/stats[_STAT_READDIR].worst,stats[_STAT_READDIR].worst);
464 	   }
465 #if !defined(Windows)
466 	   /*
467 	    * link test
468 	    */
469 	   purge_buffer_cache();
470 	   file_link(x);
471 	   if(verbose)
472 	   {
473 	      printf("link:    Files = %9lld ",stats[_STAT_LINK].counter);
474 	      printf("Total Time = %12.9f seconds\n",stats[_STAT_LINK].total_time);
475 	      printf("         Avg link(s)/sec      = %12.2f (%12.9f seconds/op)\n",
476 			stats[_STAT_LINK].counter/stats[_STAT_LINK].total_time,
477 			stats[_STAT_LINK].total_time/stats[_STAT_LINK].counter);
478 	      printf("         Best link(s)/sec     = %12.2f (%12.9f seconds/op)\n",
479 			1/stats[_STAT_LINK].best,stats[_STAT_LINK].best);
480 	      printf("         Worst link(s)/sec    = %12.2f (%12.9f seconds/op)\n\n",
481 			1/stats[_STAT_LINK].worst,stats[_STAT_LINK].worst);
482 	   }
483 	   /*
484 	    * unlink test
485 	    */
486 	   purge_buffer_cache();
487 	   file_unlink(x);
488 	   if(verbose)
489 	   {
490 	      printf("unlink:  Files = %9lld ",stats[_STAT_UNLINK].counter);
491 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_UNLINK].total_time);
492 	      printf("         Avg unlink(s)/sec    = %12.2f (%12.9f seconds/op)\n",
493 			stats[_STAT_UNLINK].counter/stats[_STAT_UNLINK].total_time,
494 			stats[_STAT_UNLINK].total_time/stats[_STAT_UNLINK].counter);
495 	      printf("         Best unlink(s)/sec   = %12.2f (%12.9f seconds/op)\n",
496 			1/stats[_STAT_UNLINK].best,stats[_STAT_UNLINK].best);
497 	      printf("         Worst unlink(s)/sec  = %12.2f (%12.9f seconds/op)\n\n",
498 			1/stats[_STAT_UNLINK].worst,stats[_STAT_UNLINK].worst);
499 	   }
500 #endif
501 	   /*
502 	    * Delete test
503 	    */
504 	   purge_buffer_cache();
505 	   file_delete(x);
506 	   if(verbose)
507 	   {
508 	      printf("delete:  Files = %9lld ",stats[_STAT_DELETE].counter);
509 	      printf("Total Time = %12.9f seconds\n", stats[_STAT_DELETE].total_time);
510 	      printf("         Avg delete(s)/sec    = %12.2f (%12.9f seconds/op)\n",
511 			stats[_STAT_DELETE].counter/stats[_STAT_DELETE].total_time,
512 			stats[_STAT_DELETE].total_time/stats[_STAT_DELETE].counter);
513 	      printf("         Best delete(s)/sec   = %12.2f (%12.9f seconds/op)\n",
514 			1/stats[_STAT_DELETE].best,stats[_STAT_DELETE].best);
515 	      printf("         Worst delete(s)/sec  = %12.2f (%12.9f seconds/op)\n\n",
516 			1/stats[_STAT_DELETE].worst,stats[_STAT_DELETE].worst);
517 	   }
518 	   if(!verbose)
519 	   {
520 	         printf("%c %4d %7.0f ",'A',x,stats[_STAT_DIR_CREATE].counter/stats[_STAT_DIR_CREATE].total_time);
521 	         printf("%7.0f ",stats[_STAT_DIR_TRAVERSE].counter/stats[_STAT_DIR_TRAVERSE].total_time);
522 	         printf("%7.0f ",stats[_STAT_DIR_DELETE].counter/stats[_STAT_DIR_DELETE].total_time);
523 	         printf("%7.0f ",stats[_STAT_CREATE].counter/stats[_STAT_CREATE].total_time);
524 	         printf("%7.0f ",stats[_STAT_OPEN].counter/stats[_STAT_OPEN].total_time);
525 	         printf("%7.0f ",stats[_STAT_READ].counter/stats[_STAT_READ].total_time);
526 	         printf("%7.0f ",stats[_STAT_WRITE].counter/stats[_STAT_WRITE].total_time);
527 	         printf("%7.0f ",stats[_STAT_CLOSE].counter/stats[_STAT_CLOSE].total_time);
528 	         printf("%7.0f ",stats[_STAT_STAT].counter/stats[_STAT_STAT].total_time);
529 	         printf("%7.0f ",stats[_STAT_ACCESS].counter/stats[_STAT_ACCESS].total_time);
530 	         printf("%7.0f ",stats[_STAT_CHMOD].counter/stats[_STAT_CHMOD].total_time);
531 	         printf("%7.0f ",stats[_STAT_READDIR].counter/stats[_STAT_READDIR].total_time);
532 #ifndef Windows
533 	         printf("%7.0f ",stats[_STAT_LINK].counter/stats[_STAT_LINK].total_time);
534 	         printf("%7.0f ",stats[_STAT_UNLINK].counter/stats[_STAT_UNLINK].total_time);
535 #endif
536 	         printf("%7.0f ",stats[_STAT_DELETE].counter/stats[_STAT_DELETE].total_time);
537 	         printf("%10d ",x*x*x);
538 	         printf("\n");
539   	   	 fflush(stdout);
540 
541 		if(best)
542 		{
543 	         printf("%c %4d %7.0f ",'B',x, 1/stats[_STAT_DIR_CREATE].best);
544 	         printf("%7.0f ",1/stats[_STAT_DIR_TRAVERSE].best);
545 	         printf("%7.0f ",1/stats[_STAT_DIR_DELETE].best);
546 	         printf("%7.0f ",1/stats[_STAT_CREATE].best);
547 	         printf("%7.0f ",1/stats[_STAT_OPEN].best);
548 	         printf("%7.0f ",1/stats[_STAT_READ].best);
549 	         printf("%7.0f ",1/stats[_STAT_WRITE].best);
550 	         printf("%7.0f ",1/stats[_STAT_CLOSE].best);
551 	         printf("%7.0f ",1/stats[_STAT_STAT].best);
552 	         printf("%7.0f ",1/stats[_STAT_ACCESS].best);
553 	         printf("%7.0f ",1/stats[_STAT_CHMOD].best);
554 	         printf("%7.0f ",1/stats[_STAT_READDIR].best);
555 #ifndef Windows
556 	         printf("%7.0f ",1/stats[_STAT_LINK].best);
557 	         printf("%7.0f ",1/stats[_STAT_UNLINK].best);
558 #endif
559 	         printf("%7.0f ",1/stats[_STAT_DELETE].best);
560 	         printf("%10d ",x*x*x);
561 		 printf("\n");
562   	   	 fflush(stdout);
563 		}
564 		if(worst)
565 		{
566 	         printf("%c %4d %7.0f ",'W',x, 1/stats[_STAT_DIR_CREATE].worst);
567 	         printf("%7.0f ",1/stats[_STAT_DIR_TRAVERSE].worst);
568 	         printf("%7.0f ",1/stats[_STAT_DIR_DELETE].worst);
569 	         printf("%7.0f ",1/stats[_STAT_CREATE].worst);
570 	         printf("%7.0f ",1/stats[_STAT_OPEN].worst);
571 	         printf("%7.0f ",1/stats[_STAT_READ].worst);
572 	         printf("%7.0f ",1/stats[_STAT_WRITE].worst);
573 	         printf("%7.0f ",1/stats[_STAT_CLOSE].worst);
574 	         printf("%7.0f ",1/stats[_STAT_STAT].worst);
575 	         printf("%7.0f ",1/stats[_STAT_ACCESS].worst);
576 	         printf("%7.0f ",1/stats[_STAT_CHMOD].worst);
577 	         printf("%7.0f ",1/stats[_STAT_READDIR].worst);
578 #ifndef Windows
579 	         printf("%7.0f ",1/stats[_STAT_LINK].worst);
580 	         printf("%7.0f ",1/stats[_STAT_UNLINK].worst);
581 #endif
582 	         printf("%7.0f ",1/stats[_STAT_DELETE].worst);
583 	         printf("%10d ",x*x*x);
584 		 printf("\n");
585   	   	 fflush(stdout);
586 		}
587 	   }
588 	}
589 	return(0);
590 }
591 
592 void
dir_create(int x)593 dir_create(int x)
594 {
595 	int i,j,k;
596 	int ret;
597 	char buf[100];
598 	stats[_STAT_DIR_CREATE].best=(double)99999.9;
599 	stats[_STAT_DIR_CREATE].worst=(double)0.00000000;
600 	for(i=0;i<x;i++)
601 	{
602 	  sprintf(buf,"fileop_L1_%d",i);
603 	  stats[_STAT_DIR_CREATE].starttime=time_so_far();
604 	  ret=mkdir(buf,0777);
605 	  if(ret < 0)
606 	  {
607 	      printf("Mkdir failed\n");
608 	      exit(1);
609 	  }
610 	  stats[_STAT_DIR_CREATE].endtime=time_so_far();
611 	  stats[_STAT_DIR_CREATE].speed=stats[_STAT_DIR_CREATE].endtime-stats[_STAT_DIR_CREATE].starttime;
612 	  if(stats[_STAT_DIR_CREATE].speed < (double)0.0)
613 		stats[_STAT_DIR_CREATE].speed=(double)0.0;
614 	  stats[_STAT_DIR_CREATE].total_time+=stats[_STAT_DIR_CREATE].speed;
615 	  stats[_STAT_DIR_CREATE].counter++;
616 	  if(stats[_STAT_DIR_CREATE].speed < stats[_STAT_DIR_CREATE].best)
617 	 	stats[_STAT_DIR_CREATE].best=stats[_STAT_DIR_CREATE].speed;
618 	  if(stats[_STAT_DIR_CREATE].speed > stats[_STAT_DIR_CREATE].worst)
619 		 stats[_STAT_DIR_CREATE].worst=stats[_STAT_DIR_CREATE].speed;
620 	  junk=chdir(buf);
621 	  for(j=0;j<x;j++)
622 	  {
623 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
624 	    stats[_STAT_DIR_CREATE].starttime=time_so_far();
625 	    ret=mkdir(buf,0777);
626 	    if(ret < 0)
627 	    {
628 	      printf("Mkdir failed\n");
629 	      exit(1);
630 	    }
631 	    stats[_STAT_DIR_CREATE].endtime=time_so_far();
632 	    stats[_STAT_DIR_CREATE].speed=stats[_STAT_DIR_CREATE].endtime-stats[_STAT_DIR_CREATE].starttime;
633 	    if(stats[_STAT_DIR_CREATE].speed < (double)0.0)
634 		stats[_STAT_DIR_CREATE].speed=(double) 0.0;
635 	    stats[_STAT_DIR_CREATE].total_time+=stats[_STAT_DIR_CREATE].speed;
636 	    stats[_STAT_DIR_CREATE].counter++;
637 	    if(stats[_STAT_DIR_CREATE].speed < stats[_STAT_DIR_CREATE].best)
638 		 stats[_STAT_DIR_CREATE].best=stats[_STAT_DIR_CREATE].speed;
639 	    if(stats[_STAT_DIR_CREATE].speed > stats[_STAT_DIR_CREATE].worst)
640 		 stats[_STAT_DIR_CREATE].worst=stats[_STAT_DIR_CREATE].speed;
641 	    junk=chdir(buf);
642 	    for(k=0;k<x;k++)
643 	    {
644 	      sprintf(buf,"fileop_dir_%d_%d_%d",i,j,k);
645 	      stats[_STAT_DIR_CREATE].starttime=time_so_far();
646 	      ret=mkdir(buf,0777);
647 	      if(ret < 0)
648 	      {
649 	        printf("Mkdir failed\n");
650 	        exit(1);
651 	      }
652 	      stats[_STAT_DIR_CREATE].endtime=time_so_far();
653 	      stats[_STAT_DIR_CREATE].speed=stats[_STAT_DIR_CREATE].endtime-stats[_STAT_DIR_CREATE].starttime;
654 	      if(stats[_STAT_DIR_CREATE].speed < (double)0.0)
655 		stats[_STAT_DIR_CREATE].speed=(double) 0.0;
656 	      stats[_STAT_DIR_CREATE].total_time+=stats[_STAT_DIR_CREATE].speed;
657 	      stats[_STAT_DIR_CREATE].counter++;
658 	      if(stats[_STAT_DIR_CREATE].speed < stats[_STAT_DIR_CREATE].best)
659 		 stats[_STAT_DIR_CREATE].best=stats[_STAT_DIR_CREATE].speed;
660 	      if(stats[_STAT_DIR_CREATE].speed > stats[_STAT_DIR_CREATE].worst)
661 		 stats[_STAT_DIR_CREATE].worst=stats[_STAT_DIR_CREATE].speed;
662 	      junk=chdir(buf);
663 	      junk=chdir("..");
664 	    }
665 	    junk=chdir("..");
666 	  }
667 	  junk=chdir("..");
668 	}
669 }
670 
671 void
dir_traverse(int x)672 dir_traverse(int x)
673 {
674 	int i,j,k;
675 	char buf[100];
676 	double time1, time2;
677 	stats[_STAT_DIR_TRAVERSE].best=(double)99999.9;
678 	stats[_STAT_DIR_TRAVERSE].worst=(double)0.00000000;
679 	for(i=0;i<x;i++)
680 	{
681 	  sprintf(buf,"fileop_L1_%d",i);
682 	  stats[_STAT_DIR_TRAVERSE].starttime=time_so_far();
683 	  junk=chdir(buf);
684 	  stats[_STAT_DIR_TRAVERSE].endtime=time_so_far();
685 	  time1=stats[_STAT_DIR_TRAVERSE].endtime-stats[_STAT_DIR_TRAVERSE].starttime;
686 	  for(j=0;j<x;j++)
687 	  {
688 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
689 	    stats[_STAT_DIR_TRAVERSE].starttime=time_so_far();
690 	    junk=chdir(buf);
691 	    stats[_STAT_DIR_TRAVERSE].endtime=time_so_far();
692 	    time2=stats[_STAT_DIR_TRAVERSE].endtime-stats[_STAT_DIR_TRAVERSE].starttime;
693 	    for(k=0;k<x;k++)
694 	    {
695 	      sprintf(buf,"fileop_dir_%d_%d_%d",i,j,k);
696 	      stats[_STAT_DIR_TRAVERSE].starttime=time_so_far();
697 	      junk=chdir(buf);
698 	      junk=chdir("..");
699 	      stats[_STAT_DIR_TRAVERSE].endtime=time_so_far();
700 	      stats[_STAT_DIR_TRAVERSE].speed=stats[_STAT_DIR_TRAVERSE].endtime-stats[_STAT_DIR_TRAVERSE].starttime;
701 	      if(stats[_STAT_DIR_TRAVERSE].speed < (double)0.0)
702 		stats[_STAT_DIR_TRAVERSE].speed=(double) 0.0;
703 	      stats[_STAT_DIR_TRAVERSE].total_time+=stats[_STAT_DIR_TRAVERSE].speed;
704 	      stats[_STAT_DIR_TRAVERSE].counter++;
705 	      if(stats[_STAT_DIR_TRAVERSE].speed < stats[_STAT_DIR_TRAVERSE].best)
706 		 stats[_STAT_DIR_TRAVERSE].best=stats[_STAT_DIR_TRAVERSE].speed;
707 	      if(stats[_STAT_DIR_TRAVERSE].speed > stats[_STAT_DIR_TRAVERSE].worst)
708 		 stats[_STAT_DIR_TRAVERSE].worst=stats[_STAT_DIR_TRAVERSE].speed;
709 	    }
710 	    stats[_STAT_DIR_TRAVERSE].starttime=time_so_far();
711 	    junk=chdir("..");
712 	    stats[_STAT_DIR_TRAVERSE].endtime=time_so_far();
713 	    stats[_STAT_DIR_TRAVERSE].speed=time2+stats[_STAT_DIR_TRAVERSE].endtime-stats[_STAT_DIR_TRAVERSE].starttime;
714 	    if(stats[_STAT_DIR_TRAVERSE].speed < (double)0.0)
715 		stats[_STAT_DIR_TRAVERSE].speed=(double) 0.0;
716 	    stats[_STAT_DIR_TRAVERSE].total_time+=stats[_STAT_DIR_TRAVERSE].speed;
717 	    stats[_STAT_DIR_TRAVERSE].counter++;
718 	    if(stats[_STAT_DIR_TRAVERSE].speed < stats[_STAT_DIR_TRAVERSE].best)
719 		 stats[_STAT_DIR_TRAVERSE].best=stats[_STAT_DIR_TRAVERSE].speed;
720 	    if(stats[_STAT_DIR_TRAVERSE].speed > stats[_STAT_DIR_TRAVERSE].worst)
721 		 stats[_STAT_DIR_TRAVERSE].worst=stats[_STAT_DIR_TRAVERSE].speed;
722 	  }
723 	  stats[_STAT_DIR_TRAVERSE].starttime=time_so_far();
724 	  junk=chdir("..");
725 	  stats[_STAT_DIR_TRAVERSE].endtime=time_so_far();
726 	  stats[_STAT_DIR_TRAVERSE].speed=time1+stats[_STAT_DIR_TRAVERSE].endtime-stats[_STAT_DIR_TRAVERSE].starttime;
727 	  if(stats[_STAT_DIR_TRAVERSE].speed < (double)0.0)
728 		stats[_STAT_DIR_TRAVERSE].speed=(double)0.0;
729 	  stats[_STAT_DIR_TRAVERSE].total_time+=stats[_STAT_DIR_TRAVERSE].speed;
730 	  stats[_STAT_DIR_TRAVERSE].counter++;
731 	  if(stats[_STAT_DIR_TRAVERSE].speed < stats[_STAT_DIR_TRAVERSE].best)
732 	 	stats[_STAT_DIR_TRAVERSE].best=stats[_STAT_DIR_TRAVERSE].speed;
733 	  if(stats[_STAT_DIR_TRAVERSE].speed > stats[_STAT_DIR_TRAVERSE].worst)
734 		 stats[_STAT_DIR_TRAVERSE].worst=stats[_STAT_DIR_TRAVERSE].speed;
735 	}
736 }
737 
738 void
file_create(int x)739 file_create(int x)
740 {
741 	int i,j,k;
742 	int fd;
743 	int ret;
744 	char buf[100];
745 	char value;
746 	stats[_STAT_CREATE].best=(double)999999.9;
747 	stats[_STAT_CREATE].worst=(double)0.0;
748 	stats[_STAT_WRITE].best=(double)999999.9;
749 	stats[_STAT_WRITE].worst=(double)0.0;
750 	stats[_STAT_CLOSE].best=(double)999999.9;
751 	stats[_STAT_CLOSE].worst=(double)0.0;
752 	for(i=0;i<x;i++)
753 	{
754 	  sprintf(buf,"fileop_L1_%d",i);
755 	  ret=mkdir(buf,0777);
756 	  if(ret < 0)
757 	  {
758 	      printf("Mkdir failed\n");
759 	      exit(1);
760 	  }
761 	  junk=chdir(buf);
762 	  for(j=0;j<x;j++)
763 	  {
764 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
765 	    ret=mkdir(buf,0777);
766 	    if(ret < 0)
767 	    {
768 	      printf("Mkdir failed\n");
769 	      exit(1);
770 	    }
771 	    junk=chdir(buf);
772 	    for(k=0;k<x;k++)
773 	    {
774 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
775 	      value=(char) ((i^j^k) & 0xff);
776 	      memset(mbuffer,value,sz);
777 	      stats[_STAT_CREATE].starttime=time_so_far();
778 	      fd=creat(buf,O_RDWR|0600);
779 	      if(fd < 0)
780 	      {
781 	        printf("Create failed\n");
782 	        exit(1);
783 	      }
784 	      stats[_STAT_CREATE].endtime=time_so_far();
785 	      stats[_STAT_CREATE].speed=stats[_STAT_CREATE].endtime-stats[_STAT_CREATE].starttime;
786 	      if(stats[_STAT_CREATE].speed < (double)0.0)
787 		stats[_STAT_CREATE].speed=(double)0.0;
788 	      stats[_STAT_CREATE].total_time+=stats[_STAT_CREATE].speed;
789 	      stats[_STAT_CREATE].counter++;
790 	      if(stats[_STAT_CREATE].speed < stats[_STAT_CREATE].best)
791 		 stats[_STAT_CREATE].best=stats[_STAT_CREATE].speed;
792 	      if(stats[_STAT_CREATE].speed > stats[_STAT_CREATE].worst)
793 		 stats[_STAT_CREATE].worst=stats[_STAT_CREATE].speed;
794 
795 	      stats[_STAT_WRITE].starttime=time_so_far();
796 	      junk=write(fd,mbuffer,sz);
797 	      stats[_STAT_WRITE].endtime=time_so_far();
798 	      stats[_STAT_WRITE].counter++;
799 	      stats[_STAT_WRITE].speed=stats[_STAT_WRITE].endtime-stats[_STAT_WRITE].starttime;
800 	      if(stats[_STAT_WRITE].speed < (double)0.0)
801 		stats[_STAT_WRITE].speed=(double)0.0;
802 	      stats[_STAT_WRITE].total_time+=stats[_STAT_WRITE].speed;
803 	      if(stats[_STAT_WRITE].speed < stats[_STAT_WRITE].best)
804 		 stats[_STAT_WRITE].best=stats[_STAT_WRITE].speed;
805 	      if(stats[_STAT_WRITE].speed > stats[_STAT_WRITE].worst)
806 		 stats[_STAT_WRITE].worst=stats[_STAT_WRITE].speed;
807 
808 	      fsync(fd);
809 	      stats[_STAT_CLOSE].starttime=time_so_far();
810 	      close(fd);
811 	      stats[_STAT_CLOSE].endtime=time_so_far();
812 	      stats[_STAT_CLOSE].speed=stats[_STAT_CLOSE].endtime-stats[_STAT_CLOSE].starttime;
813 	      if(stats[_STAT_CLOSE].speed < (double)0.0)
814 		stats[_STAT_CLOSE].speed=(double)0.0;
815 	      stats[_STAT_CLOSE].total_time+=stats[_STAT_CLOSE].speed;
816 	      stats[_STAT_CLOSE].counter++;
817 	      if(stats[_STAT_CLOSE].speed < stats[_STAT_CLOSE].best)
818 		 stats[_STAT_CLOSE].best=stats[_STAT_CLOSE].speed;
819 	      if(stats[_STAT_CLOSE].speed > stats[_STAT_CLOSE].worst)
820 		 stats[_STAT_CLOSE].worst=stats[_STAT_CLOSE].speed;
821 	    }
822 	    junk=chdir("..");
823 	  }
824 	  junk=chdir("..");
825 	}
826 }
827 
828 void
file_stat(int x)829 file_stat(int x)
830 {
831 	int i,j,k,y;
832 	char buf[100];
833 	struct stat mystat;
834 	stats[_STAT_STAT].best=(double)99999.9;
835 	stats[_STAT_STAT].worst=(double)0.00000000;
836 	for(i=0;i<x;i++)
837 	{
838 	  sprintf(buf,"fileop_L1_%d",i);
839 	  junk=chdir(buf);
840 	  for(j=0;j<x;j++)
841 	  {
842 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
843 	    junk=chdir(buf);
844 	    for(k=0;k<x;k++)
845 	    {
846 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
847 	      stats[_STAT_STAT].starttime=time_so_far();
848 	      y=stat(buf,&mystat);
849 	      if(y < 0)
850 	      {
851 	        printf("Stat failed\n");
852 	        exit(1);
853 	      }
854 	      stats[_STAT_STAT].endtime=time_so_far();
855 	      stats[_STAT_STAT].speed=stats[_STAT_STAT].endtime-stats[_STAT_STAT].starttime;
856 	      if(stats[_STAT_STAT].speed < (double)0.0)
857 		stats[_STAT_STAT].speed=(double)0.0;
858 	      stats[_STAT_STAT].total_time+=stats[_STAT_STAT].speed;
859 	      stats[_STAT_STAT].counter++;
860 	      if(stats[_STAT_STAT].speed < stats[_STAT_STAT].best)
861 		 stats[_STAT_STAT].best=stats[_STAT_STAT].speed;
862 	      if(stats[_STAT_STAT].speed > stats[_STAT_STAT].worst)
863 		 stats[_STAT_STAT].worst=stats[_STAT_STAT].speed;
864 	    }
865 	    junk=chdir("..");
866 	  }
867 	  junk=chdir("..");
868 	}
869 }
870 
871 void
file_access(int x)872 file_access(int x)
873 {
874 	int i,j,k,y;
875 	char buf[100];
876 	stats[_STAT_ACCESS].best=(double)999999.9;
877 	stats[_STAT_ACCESS].worst=(double)0.0;
878 	for(i=0;i<x;i++)
879 	{
880 	  sprintf(buf,"fileop_L1_%d",i);
881 	  junk=chdir(buf);
882 	  for(j=0;j<x;j++)
883 	  {
884 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
885 	    junk=chdir(buf);
886 	    for(k=0;k<x;k++)
887 	    {
888 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
889 	      stats[_STAT_ACCESS].starttime=time_so_far();
890 	      y=access(buf,W_OK|F_OK);
891 	      if(y < 0)
892 	      {
893 	        printf("access failed\n");
894 		perror("what");
895 	        exit(1);
896 	      }
897 	      stats[_STAT_ACCESS].endtime=time_so_far();
898 	      stats[_STAT_ACCESS].speed=stats[_STAT_ACCESS].endtime-stats[_STAT_ACCESS].starttime;
899 	      if(stats[_STAT_ACCESS].speed < (double)0.0)
900 		stats[_STAT_ACCESS].speed=(double)0.0;
901 	      stats[_STAT_ACCESS].total_time+=stats[_STAT_ACCESS].speed;
902 	      stats[_STAT_ACCESS].counter++;
903 	      if(stats[_STAT_ACCESS].speed < stats[_STAT_ACCESS].best)
904 		 stats[_STAT_ACCESS].best=stats[_STAT_ACCESS].speed;
905 	      if(stats[_STAT_ACCESS].speed > stats[_STAT_ACCESS].worst)
906 		 stats[_STAT_ACCESS].worst=stats[_STAT_ACCESS].speed;
907 	    }
908 	    junk=chdir("..");
909 	  }
910 	  junk=chdir("..");
911 	}
912 }
913 
914 void
file_chmod(int x)915 file_chmod(int x)
916 {
917 	int i,j,k,y;
918 	char buf[100];
919 	stats[_STAT_CHMOD].best=(double)999999.9;
920 	stats[_STAT_CHMOD].worst=(double)0.0;
921 	for(i=0;i<x;i++)
922 	{
923 	  sprintf(buf,"fileop_L1_%d",i);
924 	  junk=chdir(buf);
925 	  for(j=0;j<x;j++)
926 	  {
927 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
928 	    junk=chdir(buf);
929 	    for(k=0;k<x;k++)
930 	    {
931 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
932 	      stats[_STAT_CHMOD].starttime=time_so_far();
933 	      y=chmod(buf,0666);
934 	      if(y < 0)
935 	      {
936 	        printf("chmod failed\n");
937 		perror("what");
938 	        exit(1);
939 	      }
940 	      stats[_STAT_CHMOD].endtime=time_so_far();
941 	      stats[_STAT_CHMOD].speed=stats[_STAT_CHMOD].endtime-stats[_STAT_CHMOD].starttime;
942 	      if(stats[_STAT_CHMOD].speed < (double)0.0)
943 		stats[_STAT_CHMOD].speed=(double)0.0;
944 	      stats[_STAT_CHMOD].total_time+=stats[_STAT_CHMOD].speed;
945 	      stats[_STAT_CHMOD].counter++;
946 	      if(stats[_STAT_CHMOD].speed < stats[_STAT_CHMOD].best)
947 		 stats[_STAT_CHMOD].best=stats[_STAT_CHMOD].speed;
948 	      if(stats[_STAT_CHMOD].speed > stats[_STAT_CHMOD].worst)
949 		 stats[_STAT_CHMOD].worst=stats[_STAT_CHMOD].speed;
950 	    }
951 	    junk=chdir("..");
952 	  }
953 	  junk=chdir("..");
954 	}
955 }
956 
957 void
file_readdir(int x)958 file_readdir(int x)
959 {
960 	int i,j,ret1;
961 	char buf[100];
962 	DIR *dirbuf;
963 	struct dirent *y;
964 	stats[_STAT_READDIR].best=(double)999999.9;
965 	stats[_STAT_READDIR].worst=(double)0.0;
966 	for(i=0;i<x;i++)
967 	{
968 	  sprintf(buf,"fileop_L1_%d",i);
969 	  junk=chdir(buf);
970 	  for(j=0;j<x;j++)
971 	  {
972 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
973 	    junk=chdir(buf);
974 	    dirbuf=opendir(".");
975 	    if(dirbuf==0)
976 	    {
977 		printf("opendir failed\n");
978 		exit(1);
979 	    }
980 	    stats[_STAT_READDIR].starttime=time_so_far();
981 	    y=readdir(dirbuf);
982 	    if(y == 0)
983 	    {
984 	      printf("readdir failed\n");
985 	      exit(1);
986 	    }
987 	    stats[_STAT_READDIR].endtime=time_so_far();
988 	    stats[_STAT_READDIR].speed=stats[_STAT_READDIR].endtime-stats[_STAT_READDIR].starttime;
989 	      if(stats[_STAT_READDIR].speed < (double)0.0)
990 		stats[_STAT_READDIR].speed=(double)0.0;
991 	    stats[_STAT_READDIR].total_time+=stats[_STAT_READDIR].speed;
992 	    stats[_STAT_READDIR].counter++;
993 	    if(stats[_STAT_READDIR].speed < stats[_STAT_READDIR].best)
994 		 stats[_STAT_READDIR].best=stats[_STAT_READDIR].speed;
995 	    if(stats[_STAT_READDIR].speed > stats[_STAT_READDIR].worst)
996 		 stats[_STAT_READDIR].worst=stats[_STAT_READDIR].speed;
997 	    ret1=closedir(dirbuf);
998 	    if(ret1 < 0)
999 	    {
1000 	      printf("closedir failed\n");
1001 	      exit(1);
1002 	    }
1003 	    junk=chdir("..");
1004 	  }
1005 	  junk=chdir("..");
1006 	}
1007 }
1008 
1009 void
file_link(int x)1010 file_link(int x)
1011 {
1012 	int i,j,k,y;
1013 	char buf[100];
1014 	char bufn[100];
1015 	stats[_STAT_LINK].best=(double)999999.9;
1016 	stats[_STAT_LINK].worst=(double)0.0;
1017 	for(i=0;i<x;i++)
1018 	{
1019 	  sprintf(buf,"fileop_L1_%d",i);
1020 	  junk=chdir(buf);
1021 	  for(j=0;j<x;j++)
1022 	  {
1023 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1024 	    junk=chdir(buf);
1025 	    for(k=0;k<x;k++)
1026 	    {
1027 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
1028 	      sprintf(bufn,"fileop_file_%d_%d_%dL",i,j,k);
1029 	      stats[_STAT_LINK].starttime=time_so_far();
1030 	      y=link(buf,bufn);
1031 	      if(y < 0)
1032 	      {
1033 	        printf("Link failed\n");
1034 	        exit(1);
1035 	      }
1036 	      stats[_STAT_LINK].endtime=time_so_far();
1037 	      stats[_STAT_LINK].speed=stats[_STAT_LINK].endtime-stats[_STAT_LINK].starttime;
1038 	      if(stats[_STAT_LINK].speed < (double)0.0)
1039 		stats[_STAT_LINK].speed=(double)0.0;
1040 	      stats[_STAT_LINK].total_time+=stats[_STAT_LINK].speed;
1041 	      stats[_STAT_LINK].counter++;
1042 	      if(stats[_STAT_LINK].speed < stats[_STAT_LINK].best)
1043 		 stats[_STAT_LINK].best=stats[_STAT_LINK].speed;
1044 	      if(stats[_STAT_LINK].speed > stats[_STAT_LINK].worst)
1045 		 stats[_STAT_LINK].worst=stats[_STAT_LINK].speed;
1046 	    }
1047 	    junk=chdir("..");
1048 	  }
1049 	  junk=chdir("..");
1050 	}
1051 }
1052 
1053 void
file_unlink(int x)1054 file_unlink(int x)
1055 {
1056 	int i,j,k,y;
1057 	char buf[100];
1058 	char bufn[100];
1059 	stats[_STAT_UNLINK].best=(double)999999.9;
1060 	stats[_STAT_UNLINK].worst=(double)0.0;
1061 	for(i=0;i<x;i++)
1062 	{
1063 	  sprintf(buf,"fileop_L1_%d",i);
1064 	  junk=chdir(buf);
1065 	  for(j=0;j<x;j++)
1066 	  {
1067 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1068 	    junk=chdir(buf);
1069 	    for(k=0;k<x;k++)
1070 	    {
1071 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
1072 	      sprintf(bufn,"fileop_file_%d_%d_%dL",i,j,k);
1073 	      stats[_STAT_UNLINK].starttime=time_so_far();
1074 	      y=unlink(bufn);
1075 	      if(y < 0)
1076 	      {
1077 	        printf("Unlink failed\n");
1078 	        exit(1);
1079 	      }
1080 	      stats[_STAT_UNLINK].endtime=time_so_far();
1081 	      stats[_STAT_UNLINK].speed=stats[_STAT_UNLINK].endtime-stats[_STAT_UNLINK].starttime;
1082 	      if(stats[_STAT_UNLINK].speed < (double)0.0)
1083 		stats[_STAT_UNLINK].speed=(double)0.0;
1084 	      stats[_STAT_UNLINK].total_time+=stats[_STAT_UNLINK].speed;
1085 	      stats[_STAT_UNLINK].counter++;
1086 	      if(stats[_STAT_UNLINK].speed < stats[_STAT_UNLINK].best)
1087 		 stats[_STAT_UNLINK].best=stats[_STAT_UNLINK].speed;
1088 	      if(stats[_STAT_UNLINK].speed > stats[_STAT_UNLINK].worst)
1089 		 stats[_STAT_UNLINK].worst=stats[_STAT_UNLINK].speed;
1090 	    }
1091 	    junk=chdir("..");
1092 	  }
1093 	  junk=chdir("..");
1094 	}
1095 }
1096 
1097 void
dir_delete(int x)1098 dir_delete(int x)
1099 {
1100 	int i,j,k;
1101 	char buf[100];
1102 	stats[_STAT_DIR_DELETE].best=(double)99999.9;
1103 	stats[_STAT_DIR_DELETE].worst=(double)0.00000000;
1104 	for(i=0;i<x;i++)
1105 	{
1106 	  sprintf(buf,"fileop_L1_%d",i);
1107 	  junk=chdir(buf);
1108 	  for(j=0;j<x;j++)
1109 	  {
1110 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1111 	    junk=chdir(buf);
1112 	    for(k=0;k<x;k++)
1113 	    {
1114 	      sprintf(buf,"fileop_dir_%d_%d_%d",i,j,k);
1115 	      junk=chdir(buf);
1116 	      junk=chdir("..");
1117 	      stats[_STAT_DIR_DELETE].starttime=time_so_far();
1118 	      rmdir(buf);
1119 	      stats[_STAT_DIR_DELETE].endtime=time_so_far();
1120 	      stats[_STAT_DIR_DELETE].speed=stats[_STAT_DIR_DELETE].endtime-stats[_STAT_DIR_DELETE].starttime;
1121 	      if(stats[_STAT_DIR_DELETE].speed < (double)0.0)
1122 		stats[_STAT_DIR_DELETE].speed=(double)0.0;
1123 	      stats[_STAT_DIR_DELETE].total_time+=stats[_STAT_DIR_DELETE].speed;
1124 	      stats[_STAT_DIR_DELETE].counter++;
1125 	      if(stats[_STAT_DIR_DELETE].speed < stats[_STAT_DIR_DELETE].best)
1126 		 stats[_STAT_DIR_DELETE].best=stats[_STAT_DIR_DELETE].speed;
1127 	      if(stats[_STAT_DIR_DELETE].speed > stats[_STAT_DIR_DELETE].worst)
1128 		 stats[_STAT_DIR_DELETE].worst=stats[_STAT_DIR_DELETE].speed;
1129 	    }
1130 	    junk=chdir("..");
1131 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1132 	    stats[_STAT_DIR_DELETE].starttime=time_so_far();
1133 	    rmdir(buf);
1134 	    stats[_STAT_DIR_DELETE].endtime=time_so_far();
1135 	    stats[_STAT_DIR_DELETE].speed=stats[_STAT_DIR_DELETE].endtime-stats[_STAT_DIR_DELETE].starttime;
1136 	      if(stats[_STAT_DIR_DELETE].speed < (double)0.0)
1137 		stats[_STAT_DIR_DELETE].speed=(double)0.0;
1138 	    stats[_STAT_DIR_DELETE].total_time+=stats[_STAT_DIR_DELETE].speed;
1139 	    stats[_STAT_DIR_DELETE].counter++;
1140 	    if(stats[_STAT_DIR_DELETE].speed < stats[_STAT_DIR_DELETE].best)
1141 		 stats[_STAT_DIR_DELETE].best=stats[_STAT_DIR_DELETE].speed;
1142 	    if(stats[_STAT_DIR_DELETE].speed > stats[_STAT_DIR_DELETE].worst)
1143 		 stats[_STAT_DIR_DELETE].worst=stats[_STAT_DIR_DELETE].speed;
1144 	  }
1145 	  junk=chdir("..");
1146 	  sprintf(buf,"fileop_L1_%d",i);
1147 	  stats[_STAT_DIR_DELETE].starttime=time_so_far();
1148 	  rmdir(buf);
1149 	  stats[_STAT_DIR_DELETE].endtime=time_so_far();
1150 	  stats[_STAT_DIR_DELETE].speed=stats[_STAT_DIR_DELETE].endtime-stats[_STAT_DIR_DELETE].starttime;
1151 	  if(stats[_STAT_DIR_DELETE].speed < (double)0.0)
1152 		stats[_STAT_DIR_DELETE].speed=(double)0.0;
1153 	  stats[_STAT_DIR_DELETE].total_time+=stats[_STAT_DIR_DELETE].speed;
1154 	  stats[_STAT_DIR_DELETE].counter++;
1155 	  if(stats[_STAT_DIR_DELETE].speed < stats[_STAT_DIR_DELETE].best)
1156 		 stats[_STAT_DIR_DELETE].best=stats[_STAT_DIR_DELETE].speed;
1157 	  if(stats[_STAT_DIR_DELETE].speed > stats[_STAT_DIR_DELETE].worst)
1158 		 stats[_STAT_DIR_DELETE].worst=stats[_STAT_DIR_DELETE].speed;
1159 	}
1160 }
1161 
1162 void
file_delete(int x)1163 file_delete(int x)
1164 {
1165 	int i,j,k;
1166 	char buf[100];
1167 	stats[_STAT_DELETE].best=(double)999999.9;
1168 	stats[_STAT_DELETE].worst=(double)0.0;
1169 	for(i=0;i<x;i++)
1170 	{
1171 	  sprintf(buf,"fileop_L1_%d",i);
1172 	  junk=chdir(buf);
1173 	  for(j=0;j<x;j++)
1174 	  {
1175 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1176 	    junk=chdir(buf);
1177 	    for(k=0;k<x;k++)
1178 	    {
1179 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
1180 	      stats[_STAT_DELETE].starttime=time_so_far();
1181 	      unlink(buf);
1182 	      stats[_STAT_DELETE].endtime=time_so_far();
1183 	      stats[_STAT_DELETE].speed=stats[_STAT_DELETE].endtime-stats[_STAT_DELETE].starttime;
1184 	      if(stats[_STAT_DELETE].speed < (double)0.0)
1185 		stats[_STAT_DELETE].speed=(double)0.0;
1186 	      stats[_STAT_DELETE].total_time+=stats[_STAT_DELETE].speed;
1187 	      stats[_STAT_DELETE].counter++;
1188 	      if(stats[_STAT_DELETE].speed < stats[_STAT_DELETE].best)
1189 		 stats[_STAT_DELETE].best=stats[_STAT_DELETE].speed;
1190 	      if(stats[_STAT_DELETE].speed > stats[_STAT_DELETE].worst)
1191 		 stats[_STAT_DELETE].worst=stats[_STAT_DELETE].speed;
1192 	    }
1193 	    junk=chdir("..");
1194 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1195 	    rmdir(buf);
1196 	  }
1197 	  junk=chdir("..");
1198 	  sprintf(buf,"fileop_L1_%d",i);
1199 	  rmdir(buf);
1200 	}
1201 }
1202 void
file_read(int x)1203 file_read(int x)
1204 {
1205 	int i,j,k,y,fd;
1206 	char buf[100];
1207 	char value;
1208 	stats[_STAT_READ].best=(double)99999.9;
1209 	stats[_STAT_READ].worst=(double)0.00000000;
1210 	stats[_STAT_OPEN].best=(double)99999.9;
1211 	stats[_STAT_OPEN].worst=(double)0.00000000;
1212 	for(i=0;i<x;i++)
1213 	{
1214 	  sprintf(buf,"fileop_L1_%d",i);
1215 	  junk=chdir(buf);
1216 	  for(j=0;j<x;j++)
1217 	  {
1218 	    sprintf(buf,"fileop_L1_%d_L2_%d",i,j);
1219 	    junk=chdir(buf);
1220 	    for(k=0;k<x;k++)
1221 	    {
1222 	      sprintf(buf,"fileop_file_%d_%d_%d",i,j,k);
1223 	      value=(char)((i^j^k) &0xff);
1224 	      stats[_STAT_OPEN].starttime=time_so_far();
1225 	      fd=open(buf,O_RDONLY);
1226 	      if(fd < 0)
1227 	      {
1228 	        printf("Open failed\n");
1229 	        exit(1);
1230 	      }
1231 	      stats[_STAT_OPEN].endtime=time_so_far();
1232 	      stats[_STAT_OPEN].speed=stats[_STAT_OPEN].endtime-stats[_STAT_OPEN].starttime;
1233 	      if(stats[_STAT_OPEN].speed < (double)0.0)
1234 		stats[_STAT_OPEN].speed=(double)0.0;
1235 	      stats[_STAT_OPEN].total_time+=stats[_STAT_OPEN].speed;
1236 	      stats[_STAT_OPEN].counter++;
1237 	      if(stats[_STAT_OPEN].speed < stats[_STAT_OPEN].best)
1238 		 stats[_STAT_OPEN].best=stats[_STAT_OPEN].speed;
1239 	      if(stats[_STAT_OPEN].speed > stats[_STAT_OPEN].worst)
1240 		 stats[_STAT_OPEN].worst=stats[_STAT_OPEN].speed;
1241 
1242 	      stats[_STAT_READ].starttime=time_so_far();
1243 	      y=read(fd,mbuffer,sz);
1244 	      if(y < 0)
1245 	      {
1246 	        printf("Read failed\n");
1247 	        exit(1);
1248 	      }
1249 	      if(validate(mbuffer,sz, value) !=0)
1250 		printf("Error: Data Mis-compare\n");;
1251 	      stats[_STAT_READ].endtime=time_so_far();
1252 	      close(fd);
1253 	      stats[_STAT_READ].speed=stats[_STAT_READ].endtime-stats[_STAT_READ].starttime;
1254 	      if(stats[_STAT_READ].speed < (double)0.0)
1255 		stats[_STAT_READ].speed=(double)0.0;
1256 	      stats[_STAT_READ].total_time+=stats[_STAT_READ].speed;
1257 	      stats[_STAT_READ].counter++;
1258 	      if(stats[_STAT_READ].speed < stats[_STAT_READ].best)
1259 		 stats[_STAT_READ].best=stats[_STAT_READ].speed;
1260 	      if(stats[_STAT_READ].speed > stats[_STAT_READ].worst)
1261 		 stats[_STAT_READ].worst=stats[_STAT_READ].speed;
1262 	    }
1263 	    junk=chdir("..");
1264 	  }
1265 	  junk=chdir("..");
1266 	}
1267 }
1268 
1269 /************************************************************************/
1270 /* Time measurement routines. Thanks to Iozone :-)			*/
1271 /************************************************************************/
1272 
1273 #ifdef HAVE_ANSIC_C
1274 static double
time_so_far(void)1275 time_so_far(void)
1276 #else
1277 static double
1278 time_so_far()
1279 #endif
1280 {
1281 #ifdef Windows
1282    LARGE_INTEGER freq,counter;
1283    double wintime,bigcounter;
1284 	/* For Windows the time_of_day() is useless. It increments in 55 milli second   */
1285 	/* increments. By using the Win32api one can get access to the high performance */
1286 	/* measurement interfaces. With this one can get back into the 8 to 9  		*/
1287 	/* microsecond resolution.							*/
1288         QueryPerformanceFrequency(&freq);
1289         QueryPerformanceCounter(&counter);
1290         bigcounter=(double)counter.HighPart *(double)0xffffffff +
1291                 (double)counter.LowPart;
1292         wintime = (double)(bigcounter/(double)freq.LowPart);
1293         return((double)wintime);
1294 #else
1295 #if defined (OSFV4) || defined(OSFV3) || defined(OSFV5)
1296   struct timespec gp;
1297 
1298   if (getclock(TIMEOFDAY, (struct timespec *) &gp) == -1)
1299     perror("getclock");
1300   return (( (double) (gp.tv_sec)) +
1301     ( ((float)(gp.tv_nsec)) * 0.000000001 ));
1302 #else
1303   struct timeval tp;
1304 
1305   if (gettimeofday(&tp, (struct timezone *) NULL) == -1)
1306     perror("gettimeofday");
1307   return ((double) (tp.tv_sec)) +
1308     (((double) tp.tv_usec) * 0.000001 );
1309 #endif
1310 #endif
1311 }
1312 
1313 void
splash(void)1314 splash(void)
1315 {
1316 	printf("\n");
1317 	printf("     --------------------------------------\n");
1318 	printf("     |              Fileop                | \n");
1319 	printf("     | %s          | \n",version);
1320 	printf("     |                                    | \n");
1321 	printf("     |                by                  |\n");
1322 	printf("     |                                    | \n");
1323 	printf("     |             Don Capps              |\n");
1324 	printf("     --------------------------------------\n");
1325 	printf("\n");
1326 }
1327 
1328 void
usage(void)1329 usage(void)
1330 {
1331   splash();
1332   printf("     fileop [-f X ]|[-l # -u #] [-s Y] [-e] [-b] [-w] [-d <dir>] [-t] [-v] [-h]\n");
1333   printf("\n");
1334   printf("     -f #      Force factor. X^3 files will be created and removed.\n");
1335   printf("     -l #      Lower limit on the value of the Force factor.\n");
1336   printf("     -u #      Upper limit on the value of the Force factor.\n");
1337   printf("     -s #      Optional. Sets filesize for the create/write. May use suffix 'K' or 'M'.\n");
1338   printf("     -e        Excel importable format.\n");
1339   printf("     -b        Output best case results.\n");
1340   printf("     -i #      Increment force factor by this increment.\n");
1341   printf("     -w        Output worst case results.\n");
1342   printf("     -d <dir>  Specify starting directory.\n");
1343   printf("     -U <dir>  Mount point to remount between tests.\n");
1344   printf("     -t        Verbose output option.\n");
1345   printf("     -v        Version information.\n");
1346   printf("     -h        Help text.\n");
1347   printf("\n");
1348   printf("     The structure of the file tree is:\n");
1349   printf("     X number of Level 1 directories, with X number of\n");
1350   printf("     level 2 directories, with X number of files in each\n");
1351   printf("     of the level 2 directories.\n");
1352   printf("\n");
1353   printf("     Example:  fileop 2\n");
1354   printf("\n");
1355   printf("             dir_1                        dir_2\n");
1356   printf("            /     \\                      /     \\ \n");
1357   printf("      sdir_1       sdir_2          sdir_1       sdir_2\n");
1358   printf("      /     \\     /     \\          /     \\      /     \\ \n");
1359   printf("   file_1 file_2 file_1 file_2   file_1 file_2 file_1 file_2\n");
1360   printf("\n");
1361   printf("   Each file will be created, and then Y bytes is written to the file.\n");
1362   printf("\n");
1363 }
1364 void
clear_stats()1365 clear_stats()
1366 {
1367 	int i;
1368 	for(i=0;i<_NUM_STATS;i++)
1369 		memset((char *)&stats[i],0,sizeof(struct stat_struct));
1370 }
1371 int
validate(char * buffer,int size,char value)1372 validate(char *buffer, int size, char value)
1373 {
1374 	register int i;
1375 	register char *cp;
1376 	register char v1;
1377 	v1=value;
1378 	cp = buffer;
1379 	for(i=0;i<size;i++)
1380 	{
1381 		if(*cp++ != v1)
1382 			return(1);
1383 	}
1384 	return(0);
1385 }
1386 
1387