Add proper per-file copyright notices/licenses and top-level license.
[bluesky.git] / TBBT / trace_play / rfs_c_age.c.unit_base
1 /* rfs_age_unit_base.c */
2 #include <sys/vfs.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <errno.h>
6 #include <stdio.h>
7 #include "rfs_assert.h"
8 #include "profile.h"
9 #define MKDIR 1
10 #define RMDIR 2
11 #define CREATE 3
12 #define REMOVE 4
13 #define WRITE 5
14 #define TRUNCATE 6
15
16 #define MAX_FILES 100000
17 #define MAX_DIRS  100000
18 #define FILE_FH_HTABLE_SIZE MAX_FILES
19 #define MAX_NAMELEN 512
20 #define MAX_PLAY_PATH_SIZE 1024
21 #define MAX_COMMAND_LEN (MAX_PLAY_PATH_SIZE+16)
22 #define NFS_MAXDATA 4096
23 //#define NFS_MAXDATA 32768
24 #define TRACE_FH_SIZE 64
25
26 #define FH_T_FLAG_FREE 0
27 #define FH_T_FLAG_IN_USE 1
28 #define IS_FILE 0
29 #define IS_DIR 1
30 #define EXIST 0
31 #define NON_EXIST 1
32 #define COMPLETE 3
33 #define ACTIVE 0
34 #define INACTIVE 1
35 #define DONT_CARE 2
36 #define FILE_RATIO 50
37 #define DISK_FRAGMENT_SIZE 4096
38 //#define FRAGMENT_NUM 5
39 //#define MIN_WRITE_SIZE 512
40 //#define MIN_WRITE_SIZE 2000000000
41
42 static char ftypename[3][32] = {"FILE", "DIR", "FTYPE_DONT_CARE"};
43 static char activename[3][32] = {"ACTIVE", "INACTIVE", "ACTIVE_DONT_CARE"};
44 static char existname[4][32] = {"EXIST", "NON_EXIST", "EXIST_DONT_CARE", "COMPLETE"};
45
46 typedef struct {
47     char flag;
48         char ftype;
49         char exist_flag;
50         int psfh;
51         int size;
52         int cur_size;
53     //char trace_fh [TRACE_FH_SIZE+1];
54     char path[MAX_PLAY_PATH_SIZE];
55 } fh_t;
56
57 typedef struct {
58         char name[32];
59         fh_t * fh;
60         //struct generic_entry * htable;
61         int fh_size;
62         int fh_max;
63         int active_fh_max;
64         //int index;
65         //int htable_size;
66 } fh_info_t;
67
68 fh_info_t obj_fh;
69 profile_t read_line_profile, fgets_profile;
70 char trace_file[MAX_NAMELEN];
71 FILE * profile_fp = NULL;
72 char testdir[MAX_NAMELEN];
73
74 int active_obj_num = 0;
75 int exist_active_obj_num = 0;
76 static int active_file_num = 0, active_dir_num =0, age_file_num = 0, age_dir_num = 0;
77
78 int age_create_num = 0;
79 int age_mkdir_num = 0;
80 int assure_create_num = 0;
81 int assure_mkdir_num = 0;
82 int age_write_num = 0;
83 int nonage_write_num = 0;
84 int overlap_write_num = 0;
85
86 int rfs_debug = 0;
87
88
89 int ACTIVE_RATIO;
90 int FRAGMENT_NUM;
91 int MIN_WRITE_SIZE = 512;
92
93 int aging_dirs ()
94 {
95
96 }
97
98
99 int init_profile_variables()
100 {
101         init_profile ("read_line profile", &read_line_profile);
102         init_profile ("fgets profile", &fgets_profile);
103 }
104
105 int init_fh_info (char * name, fh_info_t * fh_infop, int fh_size, int htable_size)
106 {
107         int i;
108
109         RFS_ASSERT (strlen(name) < sizeof(fh_infop->name));
110         strcpy (fh_infop->name, name);
111         fh_infop->fh_max = 0;
112         //fh_infop->index = 0;
113         fh_infop->fh_size = fh_size;
114         //fh_infop->htable_size = htable_size;
115         fh_infop->fh = (fh_t *)malloc (sizeof(fh_t)*fh_size);
116         RFS_ASSERT (fh_infop->fh);
117         //fh_infop->htable = malloc (sizeof(struct*generic_entry)*htable_size);
118         //RFS_ASSERT (fh_infop->htable);
119         printf("initialize %s size %d bytes\n", 
120                 //name, sizeof(fh_t)*fh_size + sizeof(struct*generic_entry)*htable_size);
121                 name, sizeof(fh_t)*fh_size);
122
123         for (i=0; i<fh_size; i++)
124                 fh_infop->fh[i].flag = FH_T_FLAG_FREE;
125 }
126
127 int init()
128 {
129 //      init_fh_info ("file_fh", &file_fh, MAX_FILES, MAX_FILES);
130 //      init_fh_info ("dir_fh", &dir_fh, MAX_DIRS, MAX_DIRS);
131         init_fh_info ("obj_fh", &obj_fh, MAX_FILES+MAX_DIRS, MAX_FILES+MAX_DIRS);
132 }
133
134 int add_fh_t (fh_info_t * fh_table, char * path, int sfh, int psfh, int size, int ftype, int exist_flag, int active_flag)
135 {
136         int i;
137
138         RFS_ASSERT (sfh >0);
139
140         if (active_flag == ACTIVE)
141                 active_obj_num ++;
142         else
143                 RFS_ASSERT (sfh >= fh_table->active_fh_max);
144
145         if (rfs_debug)
146                 printf ("add to %s path %s sfh %d size %d %s %s %s\n", fh_table->name, path, sfh, size, 
147                 ftypename[ftype], existname[exist_flag], activename[active_flag]);
148
149         RFS_ASSERT ( (sfh>=0) && (sfh<fh_table->fh_size) );
150         RFS_ASSERT (fh_table->fh[sfh].flag==FH_T_FLAG_FREE);
151         fh_table->fh[sfh].flag = FH_T_FLAG_IN_USE;
152         if (sfh >= fh_table->fh_max)
153                 fh_table->fh_max = sfh+1;
154         strcpy (fh_table->fh[sfh].path, path);
155         fh_table->fh[sfh].psfh = psfh;
156         fh_table->fh[sfh].size = size;
157         fh_table->fh[sfh].cur_size = 0;
158         fh_table->fh[sfh].ftype = ftype;
159         fh_table->fh[sfh].exist_flag = exist_flag;
160         if (active_flag == ACTIVE) {
161                 if (ftype == IS_FILE)
162                         active_file_num ++;
163                 else {
164                         RFS_ASSERT (ftype== IS_DIR);
165                         active_dir_num ++;
166                 }
167         } else {
168                 if (ftype == IS_FILE)
169                         age_file_num ++;
170                 else {
171                         RFS_ASSERT (ftype== IS_DIR);
172                         age_dir_num ++;
173                 }
174         }
175         //print_fh_map(fh_table);
176 }
177
178
179 int loop_write (int fd, char * buf, int buflen)
180 {
181     int ret;
182     int pos = 0;
183
184     while (1) {
185         ret = write (fd, buf+pos, buflen-pos);
186
187         if (ret == -1) {
188                         printf ("fd %d\n", fd);
189             perror ("loop write");
190             exit (-1);
191         }
192         if (ret == buflen-pos)
193             break;
194         pos += ret;
195     }
196     return 0;
197 }
198
199 int assure_exist(int sfh, char * path, int ftype_flag)
200 {
201         char name[MAX_NAMELEN];
202         int ret;
203         char *p, *q;
204         int non_exist_flag = 0;
205         int count=0;
206         struct stat st;
207
208         if (rfs_debug)
209                 printf("assure_exist %s\n", path);
210
211         ret = stat (path, &st);
212         if (ret == 0)
213                 return 0;
214         RFS_ASSERT (errno == ENOENT);
215         
216         p = path;
217         q = name;
218         if (*p=='/') {
219                 *q='/';
220                 p++;
221                 q++;
222         }
223         while (count++<100) {
224                 /* copy the next component from path to name */
225                 for (; *p!=0 && *p!='/'; p++, q++ ) 
226                         *q = *p;
227                 *q = 0;
228                 ret = stat (name, &st);
229                 if (ret == -1) {
230                         RFS_ASSERT (errno == ENOENT)
231                         if ((*p)==0 && (ftype_flag==IS_FILE)) {
232                                 ret = creat (name, S_IRWXU);
233                                 if (ret == -1)
234                                         perror (name);
235                                 RFS_ASSERT (ret >=0);
236                                 assure_create_num ++;
237                                 if (rfs_debug)
238                                         printf("sfh %d create %s\n", sfh, name);
239                                 close(ret);
240                         } else {
241                                 ret = mkdir (name, S_IRWXU);
242                                 assure_mkdir_num ++;
243                                 if (rfs_debug) {
244                                         if (*p==0) 
245                                                 printf("sfh %d mkdir %s\n", sfh, name);
246                                         else
247                                                 printf("sfh %d middle mkdir %s\n", sfh, name);
248                                 }
249                                 RFS_ASSERT (ret >=0);
250                         }
251                 }
252                 if ((*p)=='/') {
253                         *q = '/';
254                         p++; q++;
255                 } else {
256                         RFS_ASSERT ((*p)==0)
257                         return 0;
258                 }
259         }
260         RFS_ASSERT (0);
261 }
262
263
264 int print_fh_map(fh_info_t * fhp)
265 {
266         int i;
267         int num = 0;
268         int active_obj_num = 0;
269
270
271         for (i=0; i<fhp->fh_max; i++) {
272                 if (fhp->fh[i].flag == FH_T_FLAG_IN_USE) {
273                         num ++;
274                         if (i < fhp->active_fh_max)
275                                 active_obj_num++;
276
277                         if (rfs_debug)
278                                 printf("%s[%d] %s %s %s\n", fhp->name, i, fhp->fh[i].path, ftypename[fhp->fh[i].ftype], existname[fhp->fh[i].exist_flag]);
279                 }
280         }
281         fprintf(stderr, "fh_max %d active_fh_max %d, in_use_num %d entries active_obj_num %d \n", fhp->fh_max, fhp->active_fh_max, num, active_obj_num);
282 }
283
284 void read_fh_map(char * fh_map_file)
285 {
286         FILE * fp;
287         int i = 0;
288         char buf[1024];
289         char trace_fh[TRACE_FH_SIZE];
290         char intbuf[9];
291         char * trace_path;
292         char * p;
293         int map_flag;
294         int lineno = 0;
295         int fh_map_debug =0;
296         char name[MAX_NAMELEN];
297         int sfh;
298
299         fp = fopen(fh_map_file, "r");
300         if (!fp) {
301                 printf ("can not opern %s\n", fh_map_file);
302                 perror("open");
303                 exit (0);
304         }
305         RFS_ASSERT (fp!=NULL);
306         
307         intbuf[8]=0;
308
309         memset(buf, 0, sizeof(buf));
310         while (fgets(buf, 1024, fp)) {
311                 RFS_ASSERT (fh_map_debug==0);
312                 lineno ++;
313                 if (rfs_debug)
314                         printf ("line %d %s", lineno, buf);
315                 if (lineno % 10000==0)
316                         printf("%d fh_map entry read\n", lineno);
317
318                 sfh = 0;
319                 if (!strncmp(buf, "::DIR ", strlen("::DIR "))) {
320                         strcpy (name, testdir);
321                         if (buf[6]=='/') {
322                                 sscanf(buf, "::DIR %s %d\n", name+strlen(name), &sfh);
323                                 add_fh_t (&obj_fh, name, sfh, -1, -1, IS_DIR, NON_EXIST, ACTIVE);
324                         } else { 
325                                 RFS_ASSERT (!strncmp(buf,"::DIR Fake 1\n", strlen("::DIR Fake 1\n")));
326                                 sfh = 1;
327                                 add_fh_t (&obj_fh, name, sfh, -1, -1, IS_DIR, EXIST, ACTIVE);
328                                 exist_active_obj_num ++;
329                         }
330                 } else {
331                         char * p;
332                         int psfh, sfh, size;
333                         char filename[MAX_NAMELEN];
334
335                         if (!strncmp(buf, "::TBDIR", strlen("::TBDIR"))) 
336                                 continue; 
337
338                         p = strstr(buf, "parent");
339                         RFS_ASSERT (p);
340                         sscanf(p, "parent %d\n", &psfh);
341                         RFS_ASSERT (obj_fh.fh[psfh].flag == FH_T_FLAG_IN_USE);
342                         p = strstr(p, "name");
343                         RFS_ASSERT (p);
344                         if (!strncmp(p, "name xx", strlen("name xx"))) {
345                                 sscanf(p, "name xx-%s sfh %d size %x", filename, &sfh, &size);
346                                 //printf ("name xx-%s sfh %d\n", filename, sfh);
347                         } else {
348                                 sscanf(p, "name \"%s sfh %d size %x", filename, &sfh, &size);
349                                 //printf ("name %s sfh %d\n", filename, sfh);
350                                 filename[strlen(filename)-1]=0;
351                         }
352                         strcpy (name, obj_fh.fh[psfh].path);    
353                         strcat (name, "/");
354                         strcat (name, filename);
355                         add_fh_t (&obj_fh, name, sfh, psfh, size, IS_FILE, NON_EXIST, ACTIVE);
356                 }
357         }
358                         
359         fclose(fp);
360         obj_fh.active_fh_max  = obj_fh.fh_max;
361         if (fh_map_debug) {
362                 print_fh_map (&obj_fh);
363         }
364 }
365
366 int print_usage()
367 {
368         printf("agefs ACTIVE_RATIO FRAGMENT_NUM fh_path_map testdir\n");
369         printf("Note: if populate_scale is 4, the total active file size is 1GB\n");
370         printf("      then the total initial file system size is about 4GB\n");
371 }
372
373 inline char * read_line (int disk_index)
374 {
375         static FILE * fp=NULL;
376         static int start=0;
377         static int start_disk_index=0;
378         int i;
379         static int finish_flag = 0;
380
381 #define READ_LINE_BUF_SIZE 1000
382 #define READ_LINE_LENGTH 32
383
384         static char line_buf[READ_LINE_BUF_SIZE][READ_LINE_LENGTH];
385         start_profile (&read_line_profile);
386
387         if (fp==NULL) {
388                 if (strcmp(trace_file, "stdin")) {
389                         fp = fopen(trace_file, "r");
390                         if (!fp) {
391                                 printf("can not open files %s\n", fp);
392                                 perror("open");
393                         }
394                 } else {
395                         fp = stdin;
396                 }
397                 RFS_ASSERT (fp!=NULL);
398                 for (i=0; i<READ_LINE_BUF_SIZE; i++) {
399                         start_profile(&fgets_profile);
400                         if (!fgets(line_buf[i], READ_LINE_LENGTH, fp)) {
401                                 RFS_ASSERT (0);
402                         }
403                         end_profile(&fgets_profile);
404                         //printf ("read_line, line_buf[%d]:%s", i, line_buf[i]);
405                 }
406         }
407         
408         RFS_ASSERT (disk_index <= start_disk_index+READ_LINE_BUF_SIZE)
409         if (disk_index==(start_disk_index+READ_LINE_BUF_SIZE)) {
410                 if (finish_flag) {
411                         return NULL;
412                 }
413                 start_profile(&fgets_profile);
414                 if (!fgets(line_buf[start], READ_LINE_LENGTH, fp)) {
415                         end_profile(&fgets_profile);
416                         fclose(fp);
417                         finish_flag = 1;
418                         return NULL;
419                 }
420                 end_profile(&fgets_profile);
421                 //printf ("read_line, line_buf[%d]:%s", start, line_buf[start]);
422                 start = (start+1) % READ_LINE_BUF_SIZE;
423                 start_disk_index ++;
424         }
425         RFS_ASSERT (disk_index < start_disk_index+READ_LINE_BUF_SIZE)
426         i = (start+disk_index-start_disk_index)%READ_LINE_BUF_SIZE;
427
428         end_profile (&read_line_profile);
429         return (line_buf[i]);
430 }
431
432 int f()
433 {};
434
435 int print_result()
436 {
437         struct statfs stfs;
438         int ret;
439         static struct statfs first_stfs;
440         static int first_entry = 1;
441
442         ret = statfs (testdir, &stfs);
443         RFS_ASSERT (ret == 0);
444         if (first_entry) {
445                 first_entry = 0;
446                 first_stfs = stfs;
447         }
448
449         fprintf(stderr, "active_file_num %d active_dir_num %d age_file_num %d age_dir_num %d\n",
450                 active_file_num, active_dir_num, age_file_num, age_dir_num);
451         fprintf(stderr, "number of used file nodes %d, used (4K) blocks in fs %d (%d MB)\n", first_stfs.f_ffree-stfs.f_ffree, first_stfs.f_bfree - stfs.f_bfree, (first_stfs.f_bfree-stfs.f_bfree)/(1000000/4096));
452         fprintf(stderr, "assure_create_num %d assure_mkdir_num %d\n", assure_create_num, assure_mkdir_num);
453 }
454
455 typedef struct {
456     int     pcnt;       /* percentile */
457     int     size;       /* file size in KB */
458 } sfs_io_file_size_dist;
459
460 sfs_io_file_size_dist Default_file_size_dist[] = {
461     /* percentage   KB size */
462     {    94,     64},           /*  4% */
463     {    97,    128},           /*  3% */
464 #ifdef notdef
465     {    33,      1},           /* 33% */
466     {    54,      2},           /* 21% */
467     {    67,      4},           /* 13% */
468     {    77,      8},           /* 10% */
469     {    85,     16},           /*  8% */
470     {    90,     32},           /*  5% */
471     {    94,     64},           /*  4% */
472     {    97,    128},           /*  3% */
473 #endif
474     {    99,    256},           /*  2% */
475     {   100,   1024},           /*  1% */
476     {     0,      0}
477 };
478
479 /*
480  * For a value between 0-99, return a size based on distribution
481  */
482 static int
483 get_file_size()
484 {
485         static file_array_initialized = 0;
486         static int file_size_array[100];
487         int i;
488
489         i = random() % 100;
490
491     if (i < 0 || i > 99)
492     return (0);
493
494     if (file_array_initialized == 0) {
495             int j, k;
496         for (j = 0, k = 0; j < 100; j++) {
497                 if (j >= Default_file_size_dist[k].pcnt &&
498                 Default_file_size_dist[k + 1].size != 0)
499             k++;
500                 file_size_array[j] = Default_file_size_dist[k].size * 1024;
501         }
502         file_array_initialized++;
503     }
504     return (file_size_array[i]);
505 }
506
507 int range_random(int min, int max)
508 {
509         int i;
510         i = random()%(max-min) + min;
511         return i;
512 }
513
514 /* answer 1 with a probability of percent/100 */
515 int decide(int percent)
516 {
517         int i = random()%100;
518         if (i<percent)
519                 return 1;
520         else
521                 return 0;
522 }
523
524 int select_obj (fh_info_t * fhp, int ftype, int exist_flag, int active_flag)
525 {
526         int i;
527         int min, max;
528         int sfh, count = 0;
529
530         //printf ("select_obj %s %s %s\n", ftypename[ftype], existname[exist_flag], activename[active_flag]);
531         if (active_flag == ACTIVE) {
532                 sfh = range_random (0, fhp->active_fh_max);
533                 for (i=0; i<fhp->active_fh_max; i++) {
534                         if ((fhp->fh[sfh].flag == FH_T_FLAG_IN_USE) &&
535                                 ((ftype==DONT_CARE) || (ftype ==fhp->fh[sfh].ftype)) &&
536                                 ((exist_flag==DONT_CARE) || (fhp->fh[sfh].exist_flag == exist_flag))) 
537                                 return sfh;
538                         sfh = (sfh+1) % fhp->active_fh_max;
539                 }
540         } else {
541                 RFS_ASSERT (active_flag == DONT_CARE);
542                 RFS_ASSERT (exist_flag == EXIST);
543                 sfh = range_random (0, fhp->fh_max);
544                 for (i=0; i<fhp->fh_max; i++) {
545                         if ((fhp->fh[sfh].flag == FH_T_FLAG_IN_USE) &&
546                             ((ftype==DONT_CARE) || (fhp->fh[sfh].ftype == ftype)) &&
547                                 (fhp->fh[sfh].exist_flag == EXIST)) {
548                                 return sfh;
549                         }
550                         sfh = (sfh+1) % fhp->fh_max;
551                 }
552         }
553         return -1;
554
555         print_fh_map(&obj_fh);
556         printf ("active_obj_num %d exist_active_obj_num %d \n", active_obj_num, exist_active_obj_num);
557         printf ("failed select_obj %s %s\n", ftypename[ftype], activename[active_flag]);
558         RFS_ASSERT (0);
559 }
560
561 /* append "size" to file "path" */
562 int append_file (int sfh, char * path, int size)
563 {
564         int fd;
565         int written_bytes = 0;
566         static char buf[NFS_MAXDATA];
567
568         if (rfs_debug)
569                 printf ("sfh %d append_file %s size %d\n", sfh, path, size);
570
571         fd = open (path, O_WRONLY|O_APPEND);
572         if (fd==-1)
573                 perror(path);
574         RFS_ASSERT (fd > 0);
575         
576         while (written_bytes+NFS_MAXDATA < size) {
577                 loop_write (fd, buf, NFS_MAXDATA);
578                 written_bytes += NFS_MAXDATA;
579         }
580         loop_write (fd, buf, size-written_bytes);
581         close(fd);
582 }
583
584 int get_write_size (int target_size, int cur_size)
585 {
586         int i;
587         if (target_size - cur_size < MIN_WRITE_SIZE)
588                 return (target_size - cur_size);
589
590         /* target_size/FRAGMENT_NUM would be the average value of i */
591         if (target_size < FRAGMENT_NUM) {
592                 i = MIN_WRITE_SIZE;
593         } else {
594                 i = random() % (2*(target_size/FRAGMENT_NUM));
595                 if (i < MIN_WRITE_SIZE)
596                         i = MIN_WRITE_SIZE;
597         }
598         if (i > (target_size - cur_size))
599                 i = target_size - cur_size;
600
601         return i;
602 }
603
604 int main(int argc, char ** argv)
605 {
606         char * buf;
607         static int disk_index=0;
608         int j, nfs3proc, size, off, count;
609         char procname[16];
610         struct stat st;
611         int ret;
612         int i;
613         int ftype_flag = 0, active_flag = 0;
614         char name[MAX_PLAY_PATH_SIZE];  
615         int sfh, psfh;
616
617         if (argc!=5) {
618                 print_usage();
619                 exit(0);
620         }
621
622         init();
623         ACTIVE_RATIO = atoi(argv[1]);
624         FRAGMENT_NUM = atoi(argv[2]);
625         if (FRAGMENT_NUM==0)
626                 MIN_WRITE_SIZE = 2000000000;
627         else
628                 MIN_WRITE_SIZE = DISK_FRAGMENT_SIZE;
629
630         strcpy (testdir, argv[4]);
631         ret = stat (testdir, &st);
632         if ((ret == -1) && (errno==ENOENT)) {
633                 ret = mkdir (testdir, S_IRWXU);
634         }
635         RFS_ASSERT (ret >= 0);
636         read_fh_map(argv[3]);
637         print_fh_map(&obj_fh);
638         init_profile_variables();
639
640 /* NOTE: should have put file and directories in one table */
641
642         for (i=0; exist_active_obj_num < active_obj_num; i++) {
643
644                 if ((i!=0) && ((i%1000)==0)) {
645                         fprintf (stderr, "\n%d object created \n", i);
646                         print_result();
647                 }
648
649                 /* decide on the exact active obj or populated obj */
650                 if (decide(ACTIVE_RATIO)) {
651                         sfh = select_obj (&obj_fh, DONT_CARE, NON_EXIST, ACTIVE);
652                         if (sfh == -1)
653                                 break;
654
655                         obj_fh.fh[sfh].exist_flag = EXIST;
656                         exist_active_obj_num ++;
657                         ftype_flag = obj_fh.fh[sfh].ftype;
658                         size = obj_fh.fh[sfh].size;
659
660 /*
661                         {
662                                 int tmpfh = sfh;
663                                 while (obj_fh.fh[--tmpfh].exist_flag == NON_EXIST) {
664                                         if (strstr(obj_fh.fh[sfh].path, obj_fh.fh[tmpfh].path)) {
665                                                 obj_fh.fh[tmpfh].exist_flag = EXIST;
666                                                 //printf ("set %s to exist due to %s\n", obj_fh.fh[tmpfh].path, obj_fh.fh[sfh].path);
667                                                 exist_active_obj_num ++;
668                                         }
669                                 }       
670                         }
671 */
672                 } else {
673                         psfh = select_obj (&obj_fh, IS_DIR, EXIST, DONT_CARE);
674                         strcpy (name, obj_fh.fh[psfh].path);
675                         sfh = obj_fh.fh_max;
676                         sprintf(name+strlen(name), "/AGE%d", obj_fh.fh_max); 
677
678                         /* decide next obj is file or directory */
679                         if (decide(FILE_RATIO)) {
680                                 ftype_flag = IS_FILE;
681                                 size = get_file_size();
682                         } else {
683                                 ftype_flag = IS_DIR;
684                                 size = -1;
685                         }
686                         add_fh_t (&obj_fh, name, sfh, psfh, size, ftype_flag, EXIST, INACTIVE);
687
688                 }
689
690                 /* make sure/create the  obj pathname on disk */
691                 assure_exist (sfh, obj_fh.fh[sfh].path, ftype_flag);
692                 /* write file to sizes according certain distribution 
693                 if (ftype_flag == IS_FILE) 
694                         append_file (obj_fh.fh[sfh].path, obj_fh.fh[sfh].size);
695                 */
696
697         }
698
699         i = 0;
700         printf ("start writing files\n");
701         while (1) {
702                 int write_size;
703                 sfh = select_obj (&obj_fh, IS_FILE, EXIST, DONT_CARE);
704                 if (sfh == -1)
705                         break;
706                 write_size = get_write_size (obj_fh.fh[sfh].size, obj_fh.fh[sfh].cur_size);
707                 append_file (sfh, obj_fh.fh[sfh].path, write_size);
708                 obj_fh.fh[sfh].cur_size += write_size;
709                 if (obj_fh.fh[sfh].cur_size == obj_fh.fh[sfh].size) {
710                         obj_fh.fh[sfh].exist_flag = COMPLETE;
711                 }
712                 if ((i%100)==0)
713                         printf ("%d append_file operation performed\n", i);
714                 i++;
715         }
716
717         printf ("end of file system object creation\n");
718         print_fh_map(&obj_fh);
719         print_result();
720 }
721
722 #ifdef notdef
723 int create_mkdir_op (int flag)
724 {
725         static int fhno = 0;
726         char name[MAX_NAMELEN];
727         char command[MAX_COMMAND_LEN];
728         int i;
729         int fd;
730         int count = 0;
731         fh_info_t * fh_infop;
732
733         while (count++ < 100) {
734                 i = random()%dir_fh.fh_max;
735                 if (dir_fh.fh[i].flag==FH_T_FLAG_IN_USE) {
736                         assure_exist(dir_fh.fh[i].path);
737                         strcpy (name, dir_fh.fh[i].path);
738                         if (flag == IS_FILE) {
739                                 sprintf (name+strlen(name), "AGEfile%d", fhno++);
740                                 fd = creat (name, S_IRWXU);
741                                 age_create_num++;
742                                 //printf ("create fd %d\n", fd);
743                                 close(fd);
744                                 fh_infop = &file_fh;
745                         } else {
746                                 sprintf (name+strlen(name), "AGEdir%d", fhno++);
747                                 fd = mkdir (name, S_IRWXU);
748                                 age_mkdir_num++;
749                                 fh_infop = &dir_fh;
750                         }
751                         if (fd == -1) {
752                                 perror("");
753                                 if (errno == ENOENT) {
754                                         dir_fh.fh[i].flag = FH_T_FLAG_FREE;
755                                         continue;
756                                 } else
757                                         RFS_ASSERT (0);
758                         }
759                         add_fh_t (fh_infop, name, EXIST);
760                         RFS_ASSERT (fd >=0);
761                         return 0;
762                 }
763         };
764         return -1;
765 }
766
767 int remove_op ()
768 {
769         int i;
770         int count = 0;
771         int ret;
772
773         while (count++<100) {
774                 i = random()%file_fh.fh_max;
775                 if (file_fh.fh[i].flag == FH_T_FLAG_IN_USE) {
776 /*
777                         if (!strstr(file_fh.fh[i].path, "AGE"))
778                                 continue;
779 */
780                         assure_exist(file_fh.fh[i].path);
781                         ret = remove (file_fh.fh[i].path);
782                         RFS_ASSERT (ret ==0);
783                         file_fh.fh[i].flag = FH_T_FLAG_FREE;
784                         return 0;
785                 }
786         }
787         return -1;
788 }
789
790 int rmdir_op()
791 {
792         int i;
793         int count=0;
794         char command[MAX_COMMAND_LEN];
795         int ret;
796
797         while (count++<100) {
798                 i = random()%dir_fh.fh_max;
799                 if ( (dir_fh.fh[i].flag == FH_T_FLAG_IN_USE) ) {
800 /*
801                         if (!strstr(file_fh.fh[i].path, "AGE"))
802                                 continue;
803 */
804                         assure_exist(file_fh.fh[i].path);
805                         ret = rmdir (dir_fh.fh[i].path);
806                         if (ret == 0) {
807                                 dir_fh.fh[i].flag = FH_T_FLAG_FREE;
808                                 return 0;
809                         }
810                         RFS_ASSERT ((ret == -1) && (errno == ENOTEMPTY));
811                         //strcpy (command, "rm -r %s", dir_fh.fh[i].path);
812                         //system (command);
813                 }
814         }
815         return -1;
816 }
817
818 int write_op (int off, int size)
819 {
820         static char buf[NFS_MAXDATA];
821         int i;
822         int count=0;
823         int fd;
824         int ret;
825         struct stat st;
826
827         RFS_ASSERT (size <= NFS_MAXDATA);
828         while (count++<100) {
829                 i = random()%file_fh.fh_max;
830                 if ( (file_fh.fh[i].flag == FH_T_FLAG_IN_USE) ) {
831                         assure_exist(file_fh.fh[i].path);
832                         fd = open(file_fh.fh[i].path, O_WRONLY);
833                         if (fd == -1)
834                                 perror("");
835                         //else 
836                                 //printf ("write fd %d\n", fd);
837                         RFS_ASSERT (fd!=-1);
838                         fstat (fd, &st);
839                         if (st.st_size < (off+size)) {
840                                 int written_bytes = 0;
841                                 while (written_bytes+NFS_MAXDATA < off+size-st.st_size) {
842                                         loop_write (fd, buf, NFS_MAXDATA);
843                                         written_bytes += NFS_MAXDATA;
844                                 }
845                                 loop_write (fd, buf, off+size-st.st_size-written_bytes);
846                                 if (strstr(file_fh.fh[i].path, "AGE")) {
847                                         age_write_num+=(written_bytes+NFS_MAXDATA-1)/NFS_MAXDATA;
848                                 } else 
849                                         nonage_write_num+=(written_bytes+NFS_MAXDATA-1)/NFS_MAXDATA;
850                         } else
851                                 overlap_write_num++;
852 /*
853                         if (strstr(file_fh.fh[i].path, "AGE")) {
854                                 age_write_num++;
855                         } else 
856                                 nonage_write_num++;
857                         loop_write (fd, buf, size);
858 */
859                         close(fd);
860                         return 0;
861                 };
862         }
863         return -1;
864 }
865
866 int truncate_op(int size)
867 {
868         int i;
869         int count=0;
870         int ret;
871
872         while (count++<100) {
873                 i = random()%file_fh.fh_max;
874                 if ( (file_fh.fh[i].flag == FH_T_FLAG_IN_USE) ) {
875 /*
876                         if (!strstr(file_fh.fh[i].path, "AGE"))
877                                 continue;
878 */
879                         assure_exist (file_fh.fh[i].path);
880                         ret = truncate(file_fh.fh[i].path, size);
881                         if (ret ==0) 
882                                 return 0;
883                         RFS_ASSERT (errno == ENOENT);
884                         file_fh.fh[i].flag = FH_T_FLAG_FREE;
885                         continue;       
886                 }
887         };
888         return -1;
889 }
890
891 int aging_files ()
892 {
893         char name[MAX_NAMELEN];
894         int sfh;        /* file to be aged */
895         int psfh;
896         int ret;
897         struct stat st;
898         int agefd;
899
900         /* get the sfh and size of the selected file to be aged */
901         sfh = select_obj (&obj_fh, IS_FILE, EXIST, ACTIVE);
902         ret = stat (obj_fh.fh[sfh].path, &st);
903         RFS_ASSERT (ret == 0);
904         ret = truncate(obj_fh.fh[i].path, st.st_size/2);
905         RFS_ASSERT (ret==0);
906
907         psfh = obj_fh.fh[sfh].psfh;
908         strcpy (name, obj_fh.fh[psfh].path);
909         sprintf(name+strlen(name), "/AGE%d", obj_fh.fh_max); 
910         agefd = creat (name, S_IRWXU);
911         //write (agefs, buf, 0);
912
913         add_fh_t (&obj_fh, name, sfh, psfh, size, ftype_flag, EXIST, INACTIVE);
914 }
915 #endif