Merge branch 'time_upgrade'
[yaffs2.git] / direct / test-framework / basic-tests / dtest.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2018 Aleph One Ltd.
5  *
6  * Created by Charles Manning <charles@aleph1.co.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <time.h>
19 #include <ctype.h>
20
21
22 #include "yaffsfs.h"
23
24 #include "yaffs_guts.h" /* Only for dumping device innards */
25 #include "yaffs_endian.h" /*For testing the swap_u64 macro */
26
27 extern int yaffs_trace_mask;
28
29 void dumpDir(const char *dname);
30
31 void copy_in_a_file(const char *yaffsName,const char *inName)
32 {
33         int inh,outh;
34         unsigned char buffer[100];
35         int ni,no;
36         inh = open(inName,O_RDONLY);
37         outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
38
39         while((ni = read(inh,buffer,100)) > 0)
40         {
41                 no = yaffs_write(outh,buffer,ni);
42                 if(ni != no)
43                 {
44                         printf("problem writing yaffs file\n");
45                 }
46
47         }
48
49         yaffs_close(outh);
50         close(inh);
51 }
52
53 void make_a_file(const char *yaffsName,char bval,int sizeOfFile)
54 {
55         int outh;
56         int i;
57         unsigned char buffer[100];
58
59         outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
60
61         memset(buffer,bval,100);
62
63         do{
64                 i = sizeOfFile;
65                 if(i > 100) i = 100;
66                 sizeOfFile -= i;
67
68                 yaffs_write(outh,buffer,i);
69
70         } while (sizeOfFile > 0);
71
72
73         yaffs_close(outh);
74
75 }
76
77 void make_pattern_file(char *fn,int size)
78 {
79         int outh;
80         int marker;
81         int i;
82         outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
83         yaffs_lseek(outh,size-1,SEEK_SET);
84         yaffs_write(outh,"A",1);
85
86         for(i = 0; i < size; i+=256)
87         {
88                 marker = ~i;
89                 yaffs_lseek(outh,i,SEEK_SET);
90                 yaffs_write(outh,&marker,sizeof(marker));
91         }
92         yaffs_close(outh);
93
94 }
95
96 int check_pattern_file(char *fn)
97 {
98         int h;
99         int marker;
100         int i;
101         int size;
102         int ok = 1;
103
104         h = yaffs_open(fn, O_RDWR,0);
105         size = yaffs_lseek(h,0,SEEK_END);
106
107         for(i = 0; i < size; i+=256)
108         {
109                 yaffs_lseek(h,i,SEEK_SET);
110                 yaffs_read(h,&marker,sizeof(marker));
111                 ok = (marker == ~i);
112                 if(!ok)
113                 {
114                    printf("pattern check failed on file %s, size %d at position %d. Got %x instead of %x\n",
115                                         fn,size,i,marker,~i);
116                 }
117         }
118         yaffs_close(h);
119         return ok;
120 }
121
122
123 int dump_file_data(char *fn)
124 {
125         int h;
126         int i = 0;
127         int ok = 1;
128         unsigned char b;
129
130         h = yaffs_open(fn, O_RDWR,0);
131
132
133         printf("%s\n",fn);
134         while(yaffs_read(h,&b,1)> 0)
135         {
136                 printf("%02x",b);
137                 i++;
138                 if(i > 32)
139                 {
140                    printf("\n");
141                    i = 0;;
142                  }
143         }
144         printf("\n");
145         yaffs_close(h);
146         return ok;
147 }
148
149
150
151 void dump_file(const char *fn)
152 {
153         int i;
154         int size;
155         int h;
156
157         h = yaffs_open(fn,O_RDONLY,0);
158         if(h < 0)
159         {
160                 printf("*****\nDump file %s does not exist\n",fn);
161         }
162         else
163         {
164                 size = yaffs_lseek(h,0,SEEK_SET);
165                 printf("*****\nDump file %s size %d\n",fn,size);
166                 for(i = 0; i < size; i++)
167                 {
168
169                 }
170         }
171 }
172
173 void create_file_of_size(const char *fn,int syze)
174 {
175         int h;
176         int n;
177         int result;
178         int iteration = 0;
179         char xx[200];
180
181         h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
182
183         while (syze > 0)
184         {
185                 sprintf(xx,"%s %8d",fn,iteration);
186                 n = strlen(xx);
187                 result = yaffs_write(h,xx,n);
188                 if(result != n){
189                         printf("Wrote %d, should have been %d. syze is %d\n",result,n,syze);
190                         syze = 0;
191                 } else
192                         syze-=n;
193                 iteration++;
194         }
195         yaffs_close (h);
196 }
197
198 void verify_file_of_size(const char *fn,int syze)
199 {
200         int h;
201         int result;
202
203         char xx[200];
204         char yy[200];
205         int l;
206
207         int iterations = (syze + strlen(fn) -1)/ strlen(fn);
208
209         h = yaffs_open(fn, O_RDONLY, S_IREAD | S_IWRITE);
210
211         while (iterations > 0)
212         {
213                 sprintf(xx,"%s %8d",fn,iterations);
214                 l = strlen(xx);
215
216                 result = yaffs_read(h,yy,l);
217                 if (result)
218                         printf("result in line %d is %d", __LINE__, result);
219                 yy[l] = 0;
220
221                 if(strcmp(xx,yy)){
222                         printf("=====>>>>> verification of file %s failed near position %lld\n",fn,(long long)yaffs_lseek(h,0,SEEK_CUR));
223                 }
224                 iterations--;
225         }
226         yaffs_close (h);
227 }
228
229 void create_resized_file_of_size(const char *fn,int syze1,int reSyze, int syze2)
230 {
231         int h;
232
233         int iterations;
234
235         h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
236
237         iterations = (syze1 + strlen(fn) -1)/ strlen(fn);
238         while (iterations > 0)
239         {
240                 yaffs_write(h,fn,strlen(fn));
241                 iterations--;
242         }
243
244         yaffs_ftruncate(h,reSyze);
245
246         yaffs_lseek(h,0,SEEK_SET);
247         iterations = (syze2 + strlen(fn) -1)/ strlen(fn);
248         while (iterations > 0)
249         {
250                 yaffs_write(h,fn,strlen(fn));
251                 iterations--;
252         }
253
254         yaffs_close (h);
255 }
256
257
258 void do_some_file_stuff(const char *path)
259 {
260
261         char fn[100];
262
263         sprintf(fn,"%s/%s",path,"f1");
264         create_file_of_size(fn,10000);
265
266         sprintf(fn,"%s/%s",path,"fdel");
267         create_file_of_size(fn,10000);
268         yaffs_unlink(fn);
269
270         sprintf(fn,"%s/%s",path,"f2");
271
272         create_resized_file_of_size(fn,10000,3000,4000);
273 }
274
275 void yaffs_backward_scan_test(const char *path)
276 {
277         char fn[100];
278
279         yaffs_start_up();
280
281         yaffs_mount(path);
282
283         do_some_file_stuff(path);
284
285         sprintf(fn,"%s/ddd",path);
286
287         yaffs_mkdir(fn,0);
288
289         do_some_file_stuff(fn);
290
291         yaffs_unmount(path);
292
293         yaffs_mount(path);
294 }
295
296 void null_name_test(const char *path)
297 {
298         char fn[100];
299         int h;
300         yaffs_start_up();
301
302         yaffs_mount(path);
303
304         sprintf(fn,"%s",path);
305
306         h = yaffs_open(fn,O_CREAT| O_TRUNC| O_RDWR, 0666);
307
308         printf("%d\n",h);
309
310 }
311
312 char xxzz[2000];
313
314
315 void yaffs_device_flush_test(const char *path)
316 {
317         char fn[100];
318         int h;
319         int i;
320
321         yaffs_start_up();
322
323         yaffs_mount(path);
324
325         do_some_file_stuff(path);
326
327         // Open and add some data to a few files
328         for(i = 0; i < 10; i++) {
329
330                 sprintf(fn,"%s/ff%d",path,i);
331
332                 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IWRITE | S_IREAD);
333                 yaffs_write(h,xxzz,2000);
334                 yaffs_write(h,xxzz,2000);
335         }
336         yaffs_unmount(path);
337
338         yaffs_mount(path);
339 }
340
341
342
343 void short_scan_test(const char *path, int fsize, int niterations)
344 {
345         int i;
346         char fn[100];
347
348         sprintf(fn,"%s/%s",path,"f1");
349
350         yaffs_start_up();
351         for(i = 0; i < niterations; i++)
352         {
353                 printf("\n*****************\nIteration %d\n",i);
354                 yaffs_mount(path);
355                 printf("\nmount: Directory look-up of %s\n",path);
356                 dumpDir(path);
357                 make_a_file(fn,1,fsize);
358                 yaffs_unmount(path);
359         }
360 }
361
362
363
364 void scan_pattern_test(const char *path, int fsize, int niterations)
365 {
366         int i;
367         int j;
368         char fn[3][100];
369         int result;
370
371         sprintf(fn[0],"%s/%s",path,"f0");
372         sprintf(fn[1],"%s/%s",path,"f1");
373         sprintf(fn[2],"%s/%s",path,"f2");
374
375         yaffs_start_up();
376
377         for(i = 0; i < niterations; i++)
378         {
379                 printf("\n*****************\nIteration %d\n",i);
380                 yaffs_mount(path);
381                 printf("\nmount: Directory look-up of %s\n",path);
382                 dumpDir(path);
383                 for(j = 0; j < 3; j++)
384                 {
385                         result = dump_file_data(fn[j]);
386                         result = check_pattern_file(fn[j]);
387                         make_pattern_file(fn[j],fsize);
388                         result = dump_file_data(fn[j]);
389                         result = check_pattern_file(fn[j]);
390                         if (result)
391                                 printf("result in line %d is %d", __LINE__, result);
392                 }
393                 yaffs_unmount(path);
394         }
395 }
396
397 void fill_disk(const char *path,int nfiles)
398 {
399         int h;
400         int n;
401         int result;
402         int f =0;
403
404         static char xx[600];
405         char str[50];
406
407         for(n = 0; n < nfiles; n++)
408         {
409                 sprintf(str,"%s/%d",path,n);
410
411                 h = yaffs_open(str, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
412
413                 printf("writing file %s handle %d ",str, h);
414
415                 while ((result = yaffs_write(h,xx,600)) == 600)
416                 {
417                         f = yaffs_freespace(path);
418                 }
419                 printf("last freespace was %d\n", f);
420                 result = yaffs_close(h);
421                 printf(" close %d\n", result);
422         }
423 }
424
425 void fill_disk_and_delete(const char *path, int nfiles, int ncycles)
426 {
427         int i,j;
428         char str[50];
429         int result;
430
431         for(i = 0; i < ncycles; i++)
432         {
433                 printf("@@@@@@@@@@@@@@ cycle %d\n",i);
434                 fill_disk(path,nfiles);
435
436                 for(j = 0; j < nfiles; j++)
437                 {
438                         sprintf(str,"%s/%d",path,j);
439                         result = yaffs_unlink(str);
440                         printf("unlinking file %s, result %d\n", str, result);
441                 }
442         }
443 }
444
445
446 void fill_files(const char *path,int flags, int maxIterations,int siz)
447 {
448         int i;
449         int j;
450         char str[50];
451         int h;
452
453         i = 0;
454
455         do{
456                 sprintf(str,"%s/%d",path,i);
457                 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
458
459                 if(h >= 0)
460                 {
461                         for(j = 0; j < siz; j++)
462                         {
463                                 yaffs_write(h,str,1);
464                         }
465                 }
466
467                 if( flags & 1)
468                 {
469                         yaffs_unlink(str);
470                 }
471                 i++;
472         } while(h >= 0 && i < maxIterations);
473
474         if(flags & 2)
475         {
476                 i = 0;
477                 do{
478                         sprintf(str,"%s/%d",path,i);
479                         printf("unlink %s\n",str);
480                         i++;
481                 } while(yaffs_unlink(str) >= 0);
482         }
483 }
484
485 void leave_unlinked_file(const char *path,int maxIterations,int siz)
486 {
487         int i;
488         char str[50];
489         int h;
490
491         i = 0;
492
493         do{
494                 sprintf(str,"%s/%d",path,i);
495                 printf("create %s\n",str);
496                 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
497                 if(h >= 0)
498                 {
499                         yaffs_unlink(str);
500                 }
501                 i++;
502         } while(h < 0 && i < maxIterations);
503
504         if(h >= 0)
505         {
506                 for(i = 0; i < siz; i++)
507                 {
508                         yaffs_write(h,str,1);
509                 }
510         }
511
512         printf("Leaving file %s open\n",str);
513
514 }
515
516 void dumpDirFollow(const char *dname)
517 {
518         yaffs_DIR *d;
519         struct yaffs_dirent *de;
520         struct yaffs_stat s;
521         char str[300];
522
523         d = yaffs_opendir(dname);
524
525         if(!d)
526         {
527                 printf("opendir failed\n");
528         }
529         else
530         {
531                 while((de = yaffs_readdir(d)) != NULL)
532                 {
533                         sprintf(str,"%s/%s",dname,de->d_name);
534
535                         yaffs_lstat(str,&s);
536
537                         printf("%s ino %d length %d mode %X ",
538                                 de->d_name, (int)s.st_ino, (int)s.st_size, s.st_mode);
539                         switch(s.st_mode & S_IFMT)
540                         {
541                                 case S_IFREG: printf("data file"); break;
542                                 case S_IFDIR: printf("directory"); break;
543                                 case S_IFLNK: printf("symlink -->");
544                                                           if(yaffs_readlink(str,str,100) < 0)
545                                                                 printf("no alias");
546                                                           else
547                                                                 printf("\"%s\"",str);
548                                                           break;
549                                 default: printf("unknown"); break;
550                         }
551
552                         printf("\n");
553                 }
554
555                 yaffs_closedir(d);
556         }
557         printf("\n");
558
559         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
560
561 }
562
563
564 void dump_directory_tree_worker(const char *dname,int recursive)
565 {
566         yaffs_DIR *d;
567         struct yaffs_dirent *de;
568         struct yaffs_stat s;
569         char str[1000];
570
571         d = yaffs_opendir(dname);
572
573         if(!d)
574         {
575                 printf("opendir failed\n");
576         }
577         else
578         {
579                 while((de = yaffs_readdir(d)) != NULL)
580                 {
581                         sprintf(str,"%s/%s",dname,de->d_name);
582
583                         yaffs_lstat(str,&s);
584
585                         printf("%s inode %d length %d mode %X ",
586                                 str, s.st_ino, (int)s.st_size, s.st_mode);
587                         switch(s.st_mode & S_IFMT)
588                         {
589                                 case S_IFREG: printf("data file"); break;
590                                 case S_IFDIR: printf("directory"); break;
591                                 case S_IFLNK: printf("symlink -->");
592                                                           if(yaffs_readlink(str,str,100) < 0)
593                                                                 printf("no alias");
594                                                           else
595                                                                 printf("\"%s\"",str);
596                                                           break;
597                                 default: printf("unknown"); break;
598                         }
599
600                         printf("\n");
601
602                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
603                                 dump_directory_tree_worker(str,1);
604
605                 }
606
607                 yaffs_closedir(d);
608         }
609
610 }
611
612 static void dump_directory_tree(const char *dname)
613 {
614         dump_directory_tree_worker(dname,1);
615         printf("\n");
616         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
617 }
618
619 void dump_directory_tree_worker_fd(const char *dname,int recursive)
620 {
621         int h;
622         struct yaffs_dirent *de;
623         struct yaffs_stat s;
624         char str[1000];
625
626         h = yaffs_open(dname, O_RDONLY, 0);
627
628         if(h < 0)
629         {
630                 printf("open of dir failed\n");
631         }
632         else
633         {
634                 printf("using fd %d\n", h);
635
636                 while((de = yaffs_readdir_fd(h)) != NULL)
637                 {
638                         sprintf(str,"%s/%s",dname,de->d_name);
639
640                         yaffs_lstat(str,&s);
641
642                         printf("%s inode %d length %d mode %X ",
643                                 str,s.st_ino, (int)s.st_size, s.st_mode);
644                         switch(s.st_mode & S_IFMT)
645                         {
646                                 case S_IFREG: printf("data file"); break;
647                                 case S_IFDIR: printf("directory"); break;
648                                 case S_IFLNK: printf("symlink -->");
649                                                           if(yaffs_readlink(str,str,100) < 0)
650                                                                 printf("no alias");
651                                                           else
652                                                                 printf("\"%s\"",str);
653                                                           break;
654                                 default: printf("unknown"); break;
655                         }
656
657                         printf("\n");
658
659                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
660                                 dump_directory_tree_worker_fd(str,1);
661
662                 }
663
664                 yaffs_close(h);
665         }
666
667 }
668
669 static void dump_directory_tree_fd(const char *dname)
670 {
671         dump_directory_tree_worker_fd(dname,1);
672         printf("\n");
673         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
674 }
675
676 void dumpDir(const char *dname)
677 {       dump_directory_tree_worker(dname,0);
678         printf("\n");
679         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
680 }
681
682
683 static void PermissionsCheck(const char *path, mode_t tmode, int tflags,int expectedResult)
684 {
685         int fd;
686
687         if(yaffs_chmod(path,tmode)< 0) printf("chmod failed\n");
688
689         fd = yaffs_open(path,tflags,0);
690
691         if((fd >= 0) != (expectedResult > 0))
692         {
693                 printf("Permissions check %x %x %d failed\n",tmode,tflags,expectedResult);
694         }
695         else
696         {
697                 printf("Permissions check %x %x %d OK\n",tmode,tflags,expectedResult);
698         }
699
700
701         yaffs_close(fd);
702
703
704 }
705
706 int long_test(int argc, char *argv[])
707 {
708
709         int f;
710         int r;
711         char buffer[20];
712
713         char str[100];
714
715         int h;
716         mode_t temp_mode;
717         struct yaffs_stat ystat;
718
719         (void) argc;
720         (void) argv;
721
722         yaffs_start_up();
723
724         yaffs_mount("/boot");
725         yaffs_mount("/data");
726         yaffs_mount("/flash");
727         yaffs_mount("/ram");
728
729         printf("\nDirectory look-up of /boot\n");
730         dumpDir("/boot");
731         printf("\nDirectory look-up of /data\n");
732         dumpDir("/data");
733         printf("\nDirectory look-up of /flash\n");
734         dumpDir("/flash");
735
736         //leave_unlinked_file("/flash",20000,0);
737         //leave_unlinked_file("/data",20000,0);
738
739         leave_unlinked_file("/ram",20,0);
740
741
742         f = yaffs_open("/boot/b1", O_RDONLY,0);
743
744         printf("open /boot/b1 readonly, f=%d\n",f);
745
746         f = yaffs_open("/boot/b1", O_CREAT,S_IREAD | S_IWRITE);
747
748         printf("open /boot/b1 O_CREAT, f=%d\n",f);
749
750
751         r = yaffs_write(f,"hello",1);
752         printf("write %d attempted to write to a read-only file\n",r);
753
754         r = yaffs_close(f);
755
756         printf("close %d\n",r);
757
758         f = yaffs_open("/boot/b1", O_RDWR,0);
759
760         printf("open /boot/b1 O_RDWR,f=%d\n",f);
761
762
763         r = yaffs_write(f,"hello",2);
764         printf("write %d attempted to write to a writeable file\n",r);
765         r = yaffs_write(f,"world",3);
766         printf("write %d attempted to write to a writeable file\n",r);
767
768         r= yaffs_lseek(f,0,SEEK_END);
769         printf("seek end %d\n",r);
770         memset(buffer,0,20);
771         r = yaffs_read(f,buffer,10);
772         printf("read %d \"%s\"\n",r,buffer);
773         r= yaffs_lseek(f,0,SEEK_SET);
774         printf("seek set %d\n",r);
775         memset(buffer,0,20);
776         r = yaffs_read(f,buffer,10);
777         printf("read %d \"%s\"\n",r,buffer);
778         memset(buffer,0,20);
779         r = yaffs_read(f,buffer,10);
780         printf("read %d \"%s\"\n",r,buffer);
781
782         // Check values reading at end.
783         // A read past end of file should return 0 for 0 bytes read.
784
785         r= yaffs_lseek(f,0,SEEK_END);
786         r = yaffs_read(f,buffer,10);
787         printf("read at end returned  %d\n",r);
788         r= yaffs_lseek(f,500,SEEK_END);
789         r = yaffs_read(f,buffer,10);
790         printf("read past end returned  %d\n",r);
791
792         r = yaffs_close(f);
793
794         printf("close %d\n",r);
795
796         copy_in_a_file("/boot/yyfile","xxx");
797
798         // Create a file with a long name
799
800         copy_in_a_file("/boot/file with a long name","xxx");
801
802
803         printf("\nDirectory look-up of /boot\n");
804         dumpDir("/boot");
805
806         // Check stat
807         r = yaffs_lstat("/boot/file with a long name",&ystat);
808
809         // Check rename
810
811         r = yaffs_rename("/boot/file with a long name","/boot/r1");
812
813         printf("\nDirectory look-up of /boot\n");
814         dumpDir("/boot");
815
816         // Check unlink
817         r = yaffs_unlink("/boot/r1");
818
819         printf("\nDirectory look-up of /boot\n");
820         dumpDir("/boot");
821
822         // Check mkdir
823
824         r = yaffs_mkdir("/boot/directory1",0);
825
826         printf("\nDirectory look-up of /boot\n");
827         dumpDir("/boot");
828         printf("\nDirectory look-up of /boot/directory1\n");
829         dumpDir("/boot/directory1");
830
831         // add a file to the directory
832         copy_in_a_file("/boot/directory1/file with a long name","xxx");
833
834         printf("\nDirectory look-up of /boot\n");
835         dumpDir("/boot");
836         printf("\nDirectory look-up of /boot/directory1\n");
837         dumpDir("/boot/directory1");
838
839         //  Attempt to delete directory (should fail)
840
841         r = yaffs_rmdir("/boot/directory1");
842
843         printf("\nDirectory look-up of /boot\n");
844         dumpDir("/boot");
845         printf("\nDirectory look-up of /boot/directory1\n");
846         dumpDir("/boot/directory1");
847
848         // Delete file first, then rmdir should work
849         r = yaffs_unlink("/boot/directory1/file with a long name");
850         r = yaffs_rmdir("/boot/directory1");
851
852
853         printf("\nDirectory look-up of /boot\n");
854         dumpDir("/boot");
855         printf("\nDirectory look-up of /boot/directory1\n");
856         dumpDir("/boot/directory1");
857
858 #if 0
859         fill_disk_and_delete("/boot",20,20);
860
861         printf("\nDirectory look-up of /boot\n");
862         dumpDir("/boot");
863 #endif
864
865         yaffs_symlink("yyfile","/boot/slink");
866
867         yaffs_readlink("/boot/slink",str,100);
868         printf("symlink alias is %s\n",str);
869
870
871
872
873         printf("\nDirectory look-up of /boot\n");
874         dumpDir("/boot");
875         printf("\nDirectory look-up of /boot (using stat instead of lstat)\n");
876         dumpDirFollow("/boot");
877         printf("\nDirectory look-up of /boot/directory1\n");
878         dumpDir("/boot/directory1");
879
880         h = yaffs_open("/boot/slink",O_RDWR,0);
881
882         printf("file length is %d\n",(int)yaffs_lseek(h,0,SEEK_END));
883
884         yaffs_close(h);
885
886         yaffs_unlink("/boot/slink");
887
888
889         printf("\nDirectory look-up of /boot\n");
890         dumpDir("/boot");
891
892         // Check chmod
893
894         yaffs_lstat("/boot/yyfile",&ystat);
895         temp_mode = ystat.st_mode;
896
897         yaffs_chmod("/boot/yyfile",0x55555);
898         printf("\nDirectory look-up of /boot\n");
899         dumpDir("/boot");
900
901         yaffs_chmod("/boot/yyfile",temp_mode);
902         printf("\nDirectory look-up of /boot\n");
903         dumpDir("/boot");
904
905         // Permission checks...
906         PermissionsCheck("/boot/yyfile",0, O_WRONLY,0);
907         PermissionsCheck("/boot/yyfile",0, O_RDONLY,0);
908         PermissionsCheck("/boot/yyfile",0, O_RDWR,0);
909
910         PermissionsCheck("/boot/yyfile",S_IREAD, O_WRONLY,0);
911         PermissionsCheck("/boot/yyfile",S_IREAD, O_RDONLY,1);
912         PermissionsCheck("/boot/yyfile",S_IREAD, O_RDWR,0);
913
914         PermissionsCheck("/boot/yyfile",S_IWRITE, O_WRONLY,1);
915         PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDONLY,0);
916         PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDWR,0);
917
918         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_WRONLY,1);
919         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDONLY,1);
920         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDWR,1);
921
922         yaffs_chmod("/boot/yyfile",temp_mode);
923
924         //create a zero-length file and unlink it (test for scan bug)
925
926         h = yaffs_open("/boot/zlf",O_CREAT | O_TRUNC | O_RDWR,0);
927         yaffs_close(h);
928
929         yaffs_unlink("/boot/zlf");
930
931
932         yaffs_dump_dev("/boot");
933
934         fill_disk_and_delete("/boot",20,20);
935
936         yaffs_dump_dev("/boot");
937
938         fill_files("/boot",1,10000,0);
939         fill_files("/boot",1,10000,5000);
940         fill_files("/boot",2,10000,0);
941         fill_files("/boot",2,10000,5000);
942
943         leave_unlinked_file("/data",20000,0);
944         leave_unlinked_file("/data",20000,5000);
945         leave_unlinked_file("/data",20000,5000);
946         leave_unlinked_file("/data",20000,5000);
947         leave_unlinked_file("/data",20000,5000);
948         leave_unlinked_file("/data",20000,5000);
949
950         yaffs_dump_dev("/boot");
951         yaffs_dump_dev("/data");
952
953
954
955         return 0;
956
957 }
958
959 int huge_directory_test_on_path(char *path)
960 {
961
962         yaffs_DIR *d;
963         struct yaffs_dirent *de;
964         struct yaffs_stat s;
965
966         int f;
967         int i;
968
969         int total = 0;
970         int lastTotal = 0;
971
972         char str[300];
973
974
975         yaffs_start_up();
976
977         yaffs_mount(path);
978
979         // Create a large number of files
980
981         for(i = 0; i < 2000; i++)
982         {
983           sprintf(str,"%s/%d",path,i);
984
985            f = yaffs_open(str,O_CREAT,S_IREAD | S_IWRITE);
986            yaffs_close(f);
987         }
988
989
990
991         d = yaffs_opendir(path);
992         i = 0;
993         if (d) {
994         while((de = yaffs_readdir(d)) != NULL) {
995         if (total >lastTotal+100*9*1024||(i & 1023)==0){
996         printf("files = %d, total = %d\n",i, total);
997         lastTotal = total;
998         }
999                 i++;
1000                 sprintf(str,"%s/%s",path,de->d_name);
1001                 yaffs_lstat(str,&s);
1002                 switch(s.st_mode & S_IFMT){
1003                 case S_IFREG:
1004         //printf("data file");
1005         total += s.st_size;
1006         break;
1007         }
1008         }
1009
1010         yaffs_closedir(d);
1011         }
1012
1013         return 0;
1014 }
1015
1016 int yaffs_scan_test(const char *path)
1017 {
1018         (void) path;
1019
1020         return 0;
1021 }
1022
1023
1024 void rename_over_test(const char *mountpt)
1025 {
1026         int i;
1027         char a[100];
1028         char b[100];
1029         char c[100];
1030
1031         sprintf(a,"%s/a",mountpt);
1032         sprintf(b,"%s/b",mountpt);
1033         sprintf(c,"%s/c",mountpt);
1034
1035         yaffs_start_up();
1036
1037         yaffs_mount(mountpt);
1038
1039         printf("Existing files\n");
1040         dumpDirFollow(mountpt);
1041
1042
1043
1044         i = yaffs_open(c,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1045         printf("File c handle is %d\n",i);
1046         yaffs_close(i);
1047         i = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE);
1048         yaffs_close(i);
1049         i = yaffs_open(b,O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE);
1050         yaffs_close(i);
1051         yaffs_rename(a,b); // rename over
1052         yaffs_rename(b,a); // rename back again (not renaimng over)
1053         yaffs_rename(a,b); // rename back again (not renaimng over)
1054
1055
1056         yaffs_unmount(mountpt);
1057
1058 }
1059
1060
1061 int resize_stress_test(const char *path)
1062 {
1063    int a,b,i,j;
1064    int x;
1065    int r;
1066    char aname[100];
1067    char bname[100];
1068
1069    char abuffer[1000];
1070    char bbuffer[1000];
1071
1072    yaffs_start_up();
1073
1074    yaffs_mount(path);
1075
1076    sprintf(aname,"%s%s",path,"/a");
1077    sprintf(bname,"%s%s",path,"/b");
1078
1079    memset(abuffer,'a',1000);
1080    memset(bbuffer,'b',1000);
1081
1082    a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1083    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1084
1085    printf(" %s %d %s %d\n",aname,a,bname,b);
1086
1087    x = 0;
1088
1089    for(j = 0; j < 100; j++)
1090    {
1091                 yaffs_lseek(a,0,SEEK_END);
1092
1093
1094                 for(i = 0; i <20000; i++)
1095                 {
1096                    //r =        yaffs_lseek(b,i,SEEK_SET);
1097                         //r = yaffs_write(b,bbuffer,1000);
1098
1099                         if(x & 0x16)
1100                         {
1101                                 // shrink
1102                                 int syz = yaffs_lseek(a,0,SEEK_END);
1103
1104                                 syz -= 500;
1105                                 if(syz < 0) syz = 0;
1106                                 yaffs_ftruncate(a,syz);
1107
1108                         }
1109                         else
1110                         {
1111                                 //expand
1112                                 r = yaffs_lseek(a,i * 500,SEEK_SET);
1113                                 if (r < 0)
1114                                         printf("At line %d, r is %d\n", __LINE__, r);
1115                                 r = yaffs_write(a,abuffer,1000);
1116                                 if (r < 0)
1117                                         printf("At line %d, r is %d\n", __LINE__, r);
1118                         }
1119                         x++;
1120
1121                 }
1122    }
1123
1124    return 0;
1125
1126 }
1127
1128
1129 int overwrite_test(const char *path)
1130 {
1131    char aname[100];
1132    char bname[100];
1133    int i;
1134    int j;
1135    int a;
1136    int b;
1137    yaffs_start_up();
1138
1139    yaffs_mount(path);
1140
1141    sprintf(aname,"%s%s",path,"/a");
1142    sprintf(bname,"%s%s",path,"/b");
1143
1144    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1145    for(j= 0; j < 500; j++){
1146         yaffs_write(b,bname,100);
1147         a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1148         for(i = 0; i < rand() % 20000; i++)
1149                 yaffs_write(a,&a,sizeof(a));
1150         yaffs_close(a);
1151    }
1152
1153    return 0;
1154
1155 }
1156
1157
1158 int root_perm_remount(const char *path)
1159 {
1160    struct yaffs_stat s;
1161
1162    yaffs_start_up();
1163
1164    yaffs_mount(path);
1165
1166    yaffs_lstat(path,&s);
1167    printf("root perms after mount %x\n",s.st_mode);
1168
1169    yaffs_chmod(path, 0777);
1170
1171    yaffs_lstat(path,&s);
1172    printf("root perms after setting to 0777 is  %x\n",s.st_mode);
1173
1174    yaffs_unmount(path);
1175
1176    return 0;
1177
1178 }
1179
1180
1181 int resize_stress_test_no_grow_complex(const char *path,int iters)
1182 {
1183    int a,b,i,j;
1184    int x;
1185    int r;
1186    char aname[100];
1187    char bname[100];
1188
1189    char abuffer[1000];
1190    char bbuffer[1000];
1191
1192
1193    yaffs_start_up();
1194
1195    yaffs_mount(path);
1196
1197    sprintf(aname,"%s%s",path,"/a");
1198    sprintf(bname,"%s%s",path,"/b");
1199
1200    memset(abuffer,'a',1000);
1201    memset(bbuffer,'b',1000);
1202
1203    a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1204    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1205
1206    printf(" %s %d %s %d\n",aname,a,bname,b);
1207
1208    x = 0;
1209
1210    for(j = 0; j < iters; j++)
1211    {
1212                 yaffs_lseek(a,0,SEEK_END);
1213
1214
1215                 for(i = 0; i <20000; i++)
1216                 {
1217                    //r =        yaffs_lseek(b,i,SEEK_SET);
1218                         //r = yaffs_write(b,bbuffer,1000);
1219
1220                         if(!(x%20))
1221                         {
1222                                 // shrink
1223                                 int syz = yaffs_lseek(a,0,SEEK_END);
1224
1225                                 while(syz > 4000)
1226                                 {
1227
1228                                         syz -= 2050;
1229                                         if(syz < 0) syz = 0;
1230                                         yaffs_ftruncate(a,syz);
1231                                         syz = yaffs_lseek(a,0,SEEK_END);
1232                                         printf("shrink to %d\n",syz);
1233                                 }
1234
1235
1236                         }
1237                         else
1238                         {
1239                                 //expand
1240                                 r = yaffs_lseek(a,500,SEEK_END);
1241                                 r = yaffs_write(a,abuffer,1000);
1242                                 if (r < 0)
1243                                         printf("At line %d, r is %d\n", __LINE__, r);
1244                         }
1245                         x++;
1246
1247
1248                 }
1249
1250                 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1251
1252    }
1253
1254    return 0;
1255
1256 }
1257
1258 int resize_stress_test_no_grow(const char *path,int iters)
1259 {
1260    int a,b,i,j;
1261    int x;
1262    int r;
1263    char aname[100];
1264    char bname[100];
1265
1266    char abuffer[1000];
1267    char bbuffer[1000];
1268
1269    yaffs_start_up();
1270
1271    yaffs_mount(path);
1272
1273    sprintf(aname,"%s%s",path,"/a");
1274    sprintf(bname,"%s%s",path,"/b");
1275
1276    memset(abuffer,'a',1000);
1277    memset(bbuffer,'b',1000);
1278
1279    a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1280    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1281
1282    printf(" %s %d %s %d\n",aname,a,bname,b);
1283
1284    x = 0;
1285
1286    for(j = 0; j < iters; j++)
1287    {
1288                 yaffs_lseek(a,0,SEEK_END);
1289
1290
1291                 for(i = 0; i <20000; i++)
1292                 {
1293                    //r =        yaffs_lseek(b,i,SEEK_SET);
1294                         //r = yaffs_write(b,bbuffer,1000);
1295
1296                         if(!(x%20))
1297                         {
1298                                 // shrink
1299                                 int syz = yaffs_lseek(a,0,SEEK_END);
1300
1301                                 while(syz > 4000)
1302                                 {
1303
1304                                         syz -= 2050;
1305                                         if(syz < 0) syz = 0;
1306                                         yaffs_ftruncate(a,syz);
1307                                         syz = yaffs_lseek(a,0,SEEK_END);
1308                                         printf("shrink to %d\n",syz);
1309                                 }
1310
1311
1312                         }
1313                         else
1314                         {
1315                                 //expand
1316                                 r = yaffs_lseek(a,-500,SEEK_END);
1317                                 r = yaffs_write(a,abuffer,1000);
1318                                 if (r < 0)
1319                                         printf("At line %d, r is %d\n", __LINE__, r);
1320                         }
1321                         x++;
1322
1323
1324                 }
1325                 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1326
1327    }
1328
1329    return 0;
1330
1331 }
1332
1333 int directory_rename_test(void)
1334 {
1335         int r;
1336         yaffs_start_up();
1337
1338         yaffs_mount("/ram");
1339         yaffs_mkdir("/ram/a",0);
1340         yaffs_mkdir("/ram/a/b",0);
1341         yaffs_mkdir("/ram/c",0);
1342
1343         printf("\nDirectory look-up of /ram\n");
1344         dumpDir("/ram");
1345         dumpDir("/ram/a");
1346         dumpDir("/ram/a/b");
1347
1348         printf("Do rename (should fail)\n");
1349
1350         r = yaffs_rename("/ram/a","/ram/a/b/d");
1351         if (r < 0)
1352                 printf("At line %d, r is %d\n", __LINE__, r);
1353
1354         printf("\nDirectory look-up of /ram\n");
1355         dumpDir("/ram");
1356         dumpDir("/ram/a");
1357         dumpDir("/ram/a/b");
1358
1359         printf("Do rename (should not fail)\n");
1360
1361         r = yaffs_rename("/ram/c","/ram/a/b/d");
1362         printf("\nDirectory look-up of /ram\n");
1363         dumpDir("/ram");
1364         dumpDir("/ram/a");
1365         dumpDir("/ram/a/b");
1366
1367
1368         return 1;
1369
1370 }
1371
1372 int cache_read_test(void)
1373 {
1374         int a,b,c;
1375         int i;
1376         int sizeOfFiles = 500000;
1377         char buffer[100];
1378
1379         yaffs_start_up();
1380
1381         yaffs_mount("/boot");
1382
1383         make_a_file("/boot/a",'a',sizeOfFiles);
1384         make_a_file("/boot/b",'b',sizeOfFiles);
1385
1386         a = yaffs_open("/boot/a",O_RDONLY,0);
1387         b = yaffs_open("/boot/b",O_RDONLY,0);
1388         c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
1389
1390         do{
1391                 i = sizeOfFiles;
1392                 if (i > 100) i = 100;
1393                 sizeOfFiles  -= i;
1394                 yaffs_read(a,buffer,i);
1395                 yaffs_read(b,buffer,i);
1396                 yaffs_write(c,buffer,i);
1397         } while(sizeOfFiles > 0);
1398
1399
1400
1401         return 1;
1402
1403 }
1404
1405 int cache_bypass_bug_test(void)
1406 {
1407         // This test reporoduces a bug whereby YAFFS caching *was* buypassed
1408         // resulting in erroneous reads after writes.
1409         // This bug has been fixed.
1410
1411         int a;
1412         char buffer1[1000];
1413         char buffer2[1000];
1414
1415         memset(buffer1,0,sizeof(buffer1));
1416         memset(buffer2,0,sizeof(buffer2));
1417
1418         yaffs_start_up();
1419
1420         yaffs_mount("/boot");
1421
1422         // Create a file of 2000 bytes.
1423         make_a_file("/boot/a",'X',2000);
1424
1425         a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE);
1426
1427         // Write a short sequence to the file.
1428         // This will go into the cache.
1429         yaffs_lseek(a,0,SEEK_SET);
1430         yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20);
1431
1432         // Read a short sequence from the file.
1433         // This will come from the cache.
1434         yaffs_lseek(a,0,SEEK_SET);
1435         yaffs_read(a,buffer1,30);
1436
1437         // Read a page size sequence from the file.
1438         yaffs_lseek(a,0,SEEK_SET);
1439         yaffs_read(a,buffer2,512);
1440
1441         printf("buffer 1 %s\n",buffer1);
1442         printf("buffer 2 %s\n",buffer2);
1443
1444         if(strncmp(buffer1,buffer2,20))
1445         {
1446                 printf("Cache bypass bug detected!!!!!\n");
1447         }
1448
1449
1450         return 1;
1451 }
1452
1453
1454 int free_space_check(void)
1455 {
1456         int f;
1457
1458         yaffs_start_up();
1459         yaffs_mount("/boot");
1460         fill_disk("/boot/",2);
1461         f = yaffs_freespace("/boot");
1462
1463         printf("%d free when disk full\n",f);
1464         return 1;
1465 }
1466
1467 int truncate_test(void)
1468 {
1469         int a;
1470         int r;
1471         int i;
1472         int l;
1473
1474         char y[10];
1475
1476         yaffs_start_up();
1477         yaffs_mount("/boot");
1478
1479         yaffs_unlink("/boot/trunctest");
1480
1481         a = yaffs_open("/boot/trunctest", O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE);
1482
1483         yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26);
1484
1485         yaffs_ftruncate(a,3);
1486         l= yaffs_lseek(a,0,SEEK_END);
1487
1488         printf("truncated length is %d\n",l);
1489
1490         yaffs_lseek(a,5,SEEK_SET);
1491         yaffs_write(a,"1",1);
1492
1493         yaffs_lseek(a,0,SEEK_SET);
1494
1495         r = yaffs_read(a,y,10);
1496
1497         printf("read %d bytes:", r);
1498
1499         for(i = 0; i < r; i++) printf("[%02X]",y[i]);
1500
1501         printf("\n");
1502
1503         return 0;
1504
1505 }
1506
1507
1508
1509
1510
1511 void fill_disk_test(const char *mountpt)
1512 {
1513         int i;
1514         yaffs_start_up();
1515
1516         for(i = 0; i < 5; i++)
1517         {
1518                 yaffs_mount(mountpt);
1519                 fill_disk_and_delete(mountpt,100,i+1);
1520                 yaffs_unmount(mountpt);
1521         }
1522
1523 }
1524
1525
1526 void fill_n_file_test(const char *mountpt, int n, int syz)
1527 {
1528         int i;
1529         int l;
1530
1531         yaffs_start_up();
1532
1533         yaffs_format(mountpt, 0, 0, 0);
1534         yaffs_mount(mountpt);
1535
1536
1537         for(i = 0; i < n; i++)
1538         {
1539                 int h;
1540                 char fname[200];
1541
1542                 sprintf(fname, "%s/%d", mountpt, i);
1543
1544                 h = yaffs_open(fname, O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE);
1545
1546                 l = syz;
1547
1548                 while(l > 0) {
1549                         yaffs_write(h, fname, sizeof(fname));
1550                         l -= sizeof(fname);
1551                 }
1552
1553                 yaffs_close(h);
1554
1555         }
1556
1557 }
1558
1559
1560 void fill_files_test(const char *mountpt)
1561 {
1562         int i;
1563         yaffs_start_up();
1564
1565         for(i = 0; i < 5; i++)
1566         {
1567                 yaffs_mount(mountpt);
1568                 fill_files(mountpt,2,3,100);
1569                 yaffs_unmount(mountpt);
1570         }
1571
1572 }
1573
1574 void fill_empty_files_test(const char *mountpt)
1575 {
1576         int i;
1577         yaffs_start_up();
1578         char name[100];
1579         int result = 0;
1580
1581         int d,f;
1582
1583         for(i = 0; i < 5; i++)
1584         {
1585                 yaffs_mount(mountpt);
1586                 for(d = 0; result >= 0 && d < 1000; d++){
1587                         sprintf(name,"%s/%d",mountpt,d);
1588                         result= yaffs_mkdir(name,0);
1589                         printf("creating directory %s result %d\n",name,result);
1590
1591                         for(f = 0; result >= 0 && f < 100; f++){
1592                                 sprintf(name,"%s/%d/%d",mountpt,d,f);
1593                                 result= yaffs_open(name,O_CREAT, 0);
1594                                 yaffs_close(result);
1595                                 printf("creating file %s result %d\n",name,result);
1596                         }
1597                 }
1598                 yaffs_unmount(mountpt);
1599         }
1600
1601 }
1602
1603 void long_name_test(const char *mountpt)
1604 {
1605         int i;
1606         yaffs_start_up();
1607         char fullName[1000];
1608         char name[300];
1609         int result = 0;
1610
1611         int f;
1612
1613         // Make a 256 byte name
1614         memset(name,0,sizeof(name));
1615         for(i = 0; i < 256; i++)
1616                 name[i] = '0' + i % 10;
1617
1618         sprintf(fullName,"%s/%s",mountpt,name);
1619
1620         for(i = 0; i < 1; i++)
1621         {
1622                 yaffs_mount(mountpt);
1623
1624                 printf("Files at start\n");
1625                 dumpDir(mountpt);
1626
1627                 printf("Creating file %s\n",fullName);
1628
1629                 f = yaffs_open(fullName,O_CREAT | O_RDWR,0);
1630                 yaffs_close(f);
1631
1632                 printf("Result %d\n",f);
1633
1634                 printf("Files\n");
1635                 dumpDir(mountpt);
1636
1637                 printf("Deleting %s\n",fullName);
1638                 result = yaffs_unlink(fullName);
1639                 printf("Result %d\n",result);
1640
1641                 printf("Files\n");
1642
1643                 dumpDir(mountpt);
1644
1645                 yaffs_unmount(mountpt);
1646         }
1647
1648 }
1649
1650
1651 void lookup_test(const char *mountpt)
1652 {
1653         int i;
1654         int h;
1655         char a[100];
1656
1657
1658         yaffs_DIR *d;
1659         struct yaffs_dirent *de;
1660
1661         yaffs_start_up();
1662
1663         yaffs_mount(mountpt);
1664
1665         d = yaffs_opendir(mountpt);
1666
1667         if(!d)
1668         {
1669                 printf("opendir failed\n");
1670         }
1671         else
1672         {
1673
1674                 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1675                 {
1676                         printf("unlinking %s\n",de->d_name);
1677                         yaffs_unlink(de->d_name);
1678                 }
1679
1680                 printf("%d files deleted\n",i);
1681         }
1682
1683
1684         for(i = 0; i < 2000; i++){
1685         sprintf(a,"%s/%d",mountpt,i);
1686                 h =  yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0);
1687                 yaffs_close(h);
1688         }
1689
1690         yaffs_rewinddir(d);
1691         for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1692         {
1693                 printf("%d  %s\n",i,de->d_name);
1694         }
1695
1696         printf("%d files listed\n\n\n",i);
1697
1698         yaffs_rewinddir(d);
1699         yaffs_readdir(d);
1700         yaffs_readdir(d);
1701         yaffs_readdir(d);
1702
1703         for(i = 0; i < 2000; i++){
1704                 sprintf(a,"%s/%d",mountpt,i);
1705                 yaffs_unlink(a);
1706         }
1707
1708
1709         yaffs_unmount(mountpt);
1710
1711 }
1712
1713 void link_test0(const char *mountpt)
1714 {
1715         char namea[300];
1716         char nameb[300];
1717         int result = 0;
1718
1719
1720         yaffs_start_up();
1721         yaffs_mount(mountpt);
1722
1723
1724         sprintf(namea,"%s/a",mountpt);
1725         sprintf(nameb,"%s/b",mountpt);
1726
1727         printf("mounted\n");
1728         dumpDir(mountpt);
1729
1730         yaffs_unlink(namea);
1731         printf("a unlinked\n");
1732         dumpDir(mountpt);
1733
1734         yaffs_unlink(nameb);
1735         printf("b unlinked\n");
1736         dumpDir(mountpt);
1737
1738         result = yaffs_open(namea,O_CREAT| O_RDWR,0666);
1739         yaffs_close(result);
1740         printf("a created\n");
1741         dumpDir(mountpt);
1742
1743         yaffs_link(namea,nameb);
1744         printf("linked\n");
1745         dumpDir(mountpt);
1746         yaffs_unlink(namea);
1747         printf("a ulinked\n");
1748         dumpDir(mountpt);
1749         yaffs_unlink(nameb);
1750         printf("b unlinked\n");
1751         dumpDir(mountpt);
1752
1753         yaffs_unmount(mountpt);
1754 }
1755
1756
1757 void link_test1(const char *mountpt)
1758 {
1759         int i;
1760         int h;
1761         char a[100];
1762         char b[100];
1763         char c[100];
1764
1765         sprintf(a,"%s/aaa",mountpt);
1766         sprintf(b,"%s/bbb",mountpt);
1767         sprintf(c,"%s/ccc",mountpt);
1768
1769         yaffs_start_up();
1770
1771         yaffs_mount(mountpt);
1772
1773
1774         h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1775         for(i = 0; i < 100; i++)
1776                 yaffs_write(h,a,100);
1777
1778         yaffs_close(h);
1779
1780         yaffs_unlink(b);
1781         yaffs_unlink(c);
1782         yaffs_link(a,b);
1783         yaffs_link(a,c);
1784         yaffs_unlink(b);
1785         yaffs_unlink(c);
1786         yaffs_unlink(a);
1787
1788
1789         yaffs_unmount(mountpt);
1790         yaffs_mount(mountpt);
1791
1792         printf("link test done\n");
1793 }
1794
1795 void handle_test(const char *mountpt)
1796 {
1797         int i;
1798         int h;
1799         int cycle;
1800         char a[100];
1801
1802         sprintf(a,"%s/aaa",mountpt);
1803
1804         yaffs_start_up();
1805
1806         yaffs_mount(mountpt);
1807
1808         for(cycle = 0; cycle < 5; cycle++){
1809         printf("Start cycle %d\n",cycle);
1810         i = 0;
1811         do {
1812         h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1813         printf("%d  handle %d\n",i,h);
1814         i++;
1815         } while(h >= 0);
1816
1817         while(i >= -1) {
1818          yaffs_close(i);
1819          i--;
1820         }
1821         }
1822
1823         yaffs_unmount(mountpt);
1824 }
1825
1826 void freespace_test(const char *mountpt)
1827 {
1828         int i;
1829         int h;
1830         char a[100];
1831
1832         int  f0;
1833         int f1;
1834         int f2;
1835         int f3;
1836         sprintf(a,"%s/aaa",mountpt);
1837
1838         yaffs_start_up();
1839
1840         yaffs_mount(mountpt);
1841
1842         f0 = yaffs_freespace(mountpt);
1843
1844         h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1845
1846         for(i = 0; i < 100; i++)
1847                 yaffs_write(h,a,100);
1848
1849         yaffs_close(h);
1850
1851         f1 = yaffs_freespace(mountpt);
1852
1853         yaffs_unlink(a);
1854
1855         f2 = yaffs_freespace(mountpt);
1856
1857
1858         yaffs_unmount(mountpt);
1859         yaffs_mount(mountpt);
1860
1861         f3 = yaffs_freespace(mountpt);
1862
1863         printf("%d\n%d\n%d\n%d\n",f0, f1,f2,f3);
1864
1865
1866 }
1867
1868 void simple_rw_test(const char *mountpt)
1869 {
1870         int i;
1871         int h;
1872         char a[100];
1873
1874         int x;
1875         int result;
1876
1877         sprintf(a,"%s/aaa",mountpt);
1878
1879         yaffs_start_up();
1880
1881         yaffs_mount(mountpt);
1882
1883         yaffs_unlink(a);
1884
1885         h = yaffs_open(a,O_CREAT| O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1886
1887         for(i = 100000;i < 200000; i++){
1888                 result = yaffs_write(h,&i,sizeof(i));
1889
1890                 if(result != 4)
1891                 {
1892                         printf("write error\n");
1893                         exit(1);
1894                 }
1895         }
1896
1897         //yaffs_close(h);
1898
1899         // h = yaffs_open(a,O_RDWR, S_IREAD | S_IWRITE);
1900
1901
1902         yaffs_lseek(h,0,SEEK_SET);
1903
1904         for(i = 100000; i < 200000; i++){
1905                 result = yaffs_read(h,&x,sizeof(x));
1906
1907                 if(result != 4 || x != i){
1908                         printf("read error %d %x %x\n",i,result,x);
1909                 }
1910         }
1911
1912         printf("Simple rw test passed\n");
1913
1914
1915
1916 }
1917
1918
1919 void scan_deleted_files_test(const char *mountpt)
1920 {
1921         char fn[100];
1922         char sub[100];
1923
1924         const char *p;
1925
1926         int i;
1927         int j;
1928         int k;
1929         int h;
1930
1931         sprintf(sub,"%s/sdir",mountpt);
1932         yaffs_start_up();
1933
1934         for(j = 0; j < 10; j++)
1935         {
1936                 printf("\n\n>>>>>>> Run %d <<<<<<<<<<<<<\n\n",j);
1937                 yaffs_mount(mountpt);
1938                 yaffs_mkdir(sub,0);
1939
1940
1941                 p = (j & 0) ? mountpt: sub;
1942
1943                 for(i = 0; i < 100; i++)
1944                 {
1945                   sprintf(fn,"%s/%d",p,i);
1946
1947                   if(i & 1)
1948                   {
1949                           h = yaffs_open(fn,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1950                           for(k = 0; k < 1000; k++)
1951                                   yaffs_write(h,fn,100);
1952                           yaffs_close(h);
1953                   }
1954                   else
1955                         yaffs_mkdir(fn,0);
1956                 }
1957
1958                 for(i = 0; i < 10; i++)
1959                 {
1960                   sprintf(fn,"%s/%d",p,i);
1961                   if(i & 1)
1962                         yaffs_unlink(fn);
1963                   else
1964                         yaffs_rmdir(fn);
1965
1966                 }
1967
1968                 yaffs_unmount(mountpt);
1969         }
1970
1971
1972
1973
1974 }
1975
1976
1977 void write_10k(int h)
1978 {
1979    int i;
1980    const char *s="0123456789";
1981    for(i = 0; i < 1000; i++)
1982      yaffs_write(h,s,10);
1983
1984 }
1985 void write_200k_file(const char *fn, const char *fdel, const char *fdel1)
1986 {
1987    int h1;
1988    int i;
1989    int offs;
1990
1991    h1 = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1992
1993    for(i = 0; i < 100000; i+= 10000)
1994    {
1995         write_10k(h1);
1996    }
1997
1998    offs = yaffs_lseek(h1,0,SEEK_CUR);
1999    if( offs != 100000)
2000    {
2001         printf("Could not write file\n");
2002    }
2003
2004    yaffs_unlink(fdel);
2005    for(i = 0; i < 100000; i+= 10000)
2006    {
2007         write_10k(h1);
2008    }
2009
2010    offs = yaffs_lseek(h1,0,SEEK_CUR);
2011    if( offs != 200000)
2012    {
2013         printf("Could not write file\n");
2014    }
2015
2016    yaffs_close(h1);
2017    yaffs_unlink(fdel1);
2018
2019 }
2020
2021
2022 void verify_200k_file(const char *fn)
2023 {
2024    int h1;
2025    int i;
2026    char x[11];
2027    const char *s="0123456789";
2028    int errCount = 0;
2029
2030    h1 = yaffs_open(fn, O_RDONLY, 0);
2031
2032    for(i = 0; i < 200000 && errCount < 10; i+= 10)
2033    {
2034         yaffs_read(h1,x,10);
2035         if(strncmp(x,s,10) != 0)
2036         {
2037                 printf("File %s verification failed at %d\n",fn,i);
2038                 errCount++;
2039         }
2040    }
2041    if(errCount >= 10)
2042         printf("Too many errors... aborted\n");
2043
2044    yaffs_close(h1);
2045
2046 }
2047
2048
2049 void check_resize_gc_bug(const char *mountpt)
2050 {
2051
2052         char a[30];
2053         char b[30];
2054         char c[30];
2055
2056         int i;
2057
2058         sprintf(a,"%s/a",mountpt);
2059         sprintf(b,"%s/b",mountpt);
2060         sprintf(c,"%s/c",mountpt);
2061
2062
2063
2064
2065         yaffs_start_up();
2066         yaffs_mount(mountpt);
2067         yaffs_unlink(a);
2068         yaffs_unlink(b);
2069
2070         for(i = 0; i < 50; i++)
2071         {
2072            printf("A\n");write_200k_file(a,"",c);
2073            printf("B\n");verify_200k_file(a);
2074            printf("C\n");write_200k_file(b,a,c);
2075            printf("D\n");verify_200k_file(b);
2076            yaffs_unmount(mountpt);
2077            yaffs_mount(mountpt);
2078            printf("E\n");verify_200k_file(a);
2079            printf("F\n");verify_200k_file(b);
2080         }
2081
2082 }
2083
2084
2085 void multi_mount_test(const char *mountpt,int nmounts)
2086 {
2087
2088         char a[30];
2089
2090         int i;
2091         int j;
2092
2093         sprintf(a,"%s/a",mountpt);
2094
2095         yaffs_start_up();
2096
2097         for(i = 0; i < nmounts; i++){
2098                 int h0;
2099                 int h1;
2100                 char xx[1000];
2101
2102                 printf("############### Iteration %d   Start\n",i);
2103                 if(1 || i == 0 || i == 5)
2104                         yaffs_mount(mountpt);
2105
2106                 dump_directory_tree(mountpt);
2107
2108
2109                 yaffs_mkdir(a,0);
2110
2111                 sprintf(xx,"%s/0",a);
2112                 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2113
2114                 sprintf(xx,"%s/1",a);
2115                 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2116
2117 #if 0
2118                 for(j = 0; j < 200; j++){
2119                    yaffs_write(h0,xx,1000);
2120                    yaffs_write(h1,xx,1000);
2121                 }
2122 #else
2123                 while(yaffs_write(h0,xx,1000) > 0){
2124
2125                    yaffs_write(h1,xx,1000);
2126                 }
2127 #endif
2128                 yaffs_lseek(h0,0,SEEK_END);
2129                 yaffs_lseek(h1,0,SEEK_END);
2130
2131                 yaffs_lseek(h0,0,SEEK_SET);
2132                 yaffs_lseek(h1,0,SEEK_SET);
2133
2134                 for(j = 0; j < 200; j++){
2135                    yaffs_read(h0,xx,1000);
2136                    yaffs_read(h1,xx,1000);
2137                 }
2138
2139
2140         //      yaffs_truncate(h0,0);
2141                 yaffs_close(h0);
2142                 yaffs_close(h1);
2143
2144                 printf("########### %d\n",i);
2145                 dump_directory_tree(mountpt);
2146
2147                 if(1 || i == 4 || i == nmounts -1)
2148                         yaffs_unmount(mountpt);
2149         }
2150 }
2151
2152
2153 void small_mount_test(const char *mountpt,int nmounts)
2154 {
2155
2156         char a[30];
2157
2158         int i;
2159         int j;
2160
2161         int h0;
2162         int h1;
2163         int nread;
2164
2165         sprintf(a,"%s/a",mountpt);
2166
2167         yaffs_start_up();
2168
2169
2170
2171         for(i = 0; i < nmounts; i++){
2172
2173                 char xx[1000];
2174
2175                 printf("############### Iteration %d   Start\n",i);
2176                 if(1 || i == 0 || i == 5)
2177                         yaffs_mount(mountpt);
2178
2179                 dump_directory_tree(mountpt);
2180
2181                 yaffs_mkdir(a,0);
2182
2183                 sprintf(xx,"%s/0",a);
2184                 if(i ==0){
2185
2186                         h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2187                         for(j = 0; j < 130; j++)
2188                                 yaffs_write(h0,xx,1000);
2189                         yaffs_close(h0);
2190                 }
2191
2192                 h0 = yaffs_open(xx,O_RDONLY,0);
2193
2194                 sprintf(xx,"%s/1",a);
2195                 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2196
2197                 while((nread = yaffs_read(h0,xx,1000)) > 0)
2198                         yaffs_write(h1,xx,nread);
2199
2200
2201                 yaffs_lseek(h0,0,SEEK_END);
2202                 yaffs_lseek(h1,0,SEEK_END);
2203
2204                 yaffs_lseek(h0,0,SEEK_SET);
2205                 yaffs_lseek(h1,0,SEEK_SET);
2206
2207                 for(j = 0; j < 200; j++){
2208                    yaffs_read(h0,xx,1000);
2209                    yaffs_read(h1,xx,1000);
2210                 }
2211
2212                 yaffs_close(h0);
2213                 yaffs_close(h1);
2214
2215                 printf("########### %d\n",i);
2216                 dump_directory_tree(mountpt);
2217
2218                 if(1 || i == 4 || i == nmounts -1)
2219                         yaffs_unmount(mountpt);
2220         }
2221 }
2222
2223
2224 int early_exit;
2225
2226 void small_overwrite_test(const char *mountpt,int nmounts)
2227 {
2228
2229         char a[30];
2230         int i;
2231         int j;
2232
2233         int h0;
2234         int h1;
2235
2236
2237         sprintf(a,"%s/a",mountpt);
2238
2239         yaffs_start_up();
2240
2241
2242
2243         for(i = 0; i < nmounts; i++){
2244
2245                 static char xx[8000];
2246
2247                 printf("############### Iteration %d   Start\n",i);
2248                 if(1)
2249                         yaffs_mount(mountpt);
2250
2251                 dump_directory_tree(mountpt);
2252
2253                 yaffs_mkdir(a,0);
2254
2255                 sprintf(xx,"%s/0",a);
2256                 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2257                 sprintf(xx,"%s/1",a);
2258                 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2259
2260                 for(j = 0; j < 1000000; j+=1000){
2261                         yaffs_ftruncate(h0,j);
2262                         yaffs_lseek(h0,j,SEEK_SET);
2263                         yaffs_write(h0,xx,7000);
2264                         yaffs_write(h1,xx,7000);
2265
2266                         if(early_exit)
2267                                 exit(0);
2268                 }
2269
2270                 yaffs_close(h0);
2271
2272                 printf("########### %d\n",i);
2273                 dump_directory_tree(mountpt);
2274
2275                 if(1)
2276                         yaffs_unmount(mountpt);
2277         }
2278 }
2279
2280
2281 void seek_overwrite_test(const char *mountpt,int nmounts)
2282 {
2283         static char xx[5000];
2284         char a[30];
2285
2286         int i;
2287         int j;
2288
2289         int h0;
2290
2291
2292         sprintf(a,"%s/f",mountpt);
2293
2294         yaffs_start_up();
2295
2296         yaffs_mount(mountpt);
2297
2298
2299         for(i = 0; i < nmounts; i++){
2300
2301                 h0 = yaffs_open(a, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2302
2303                 for(j = 0; j < 100000; j++){
2304                         yaffs_lseek(h0,0,SEEK_SET);
2305                         yaffs_write(h0,xx,5000);
2306                         yaffs_lseek(h0,0x100000,SEEK_SET);
2307                         yaffs_write(h0,xx,5000);
2308
2309                         if(early_exit)
2310                                 exit(0);
2311                 }
2312
2313                 yaffs_close(h0);
2314
2315         }
2316 }
2317
2318
2319 void yaffs_touch(const char *fn)
2320 {
2321         yaffs_chmod(fn, S_IREAD | S_IWRITE);
2322 }
2323
2324 void checkpoint_fill_test(const char *mountpt,int nmounts)
2325 {
2326
2327         char a[50];
2328         char b[50];
2329         char c[50];
2330
2331         int i;
2332         int j;
2333         int h;
2334
2335         sprintf(a,"%s/a",mountpt);
2336
2337
2338
2339
2340         yaffs_start_up();
2341
2342         for(i = 0; i < nmounts; i++){
2343                 printf("############### Iteration %d   Start\n",i);
2344                 yaffs_mount(mountpt);
2345                 dump_directory_tree(mountpt);
2346                 yaffs_mkdir(a,0);
2347
2348                 sprintf(b,"%s/zz",a);
2349
2350                 h = yaffs_open(b,O_CREAT | O_RDWR,S_IREAD |S_IWRITE);
2351
2352
2353                 while(yaffs_write(h,c,50) == 50){}
2354
2355                 yaffs_close(h);
2356
2357                 for(j = 0; j < 2; j++){
2358                         printf("touch %d\n",j);
2359                         yaffs_touch(b);
2360                         yaffs_unmount(mountpt);
2361                         yaffs_mount(mountpt);
2362                 }
2363
2364                 dump_directory_tree(mountpt);
2365                 yaffs_unmount(mountpt);
2366         }
2367 }
2368
2369
2370 int make_file2(const char *name1, const char *name2,int syz)
2371 {
2372
2373         char xx[2500];
2374         int i;
2375         int h1=-1,h2=-1;
2376         int n = 1;
2377
2378
2379         if(name1)
2380                 h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2381         if(name2)
2382                 h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2383
2384         while(syz > 0 && n > 0){
2385                 i = (syz > 2500) ? 2500 : syz;
2386                 n = yaffs_write(h1,xx,i);
2387                 n = yaffs_write(h2,xx,i);
2388                 syz -= 500;
2389         }
2390         yaffs_close(h1);
2391         yaffs_close(h2);
2392         return 0;
2393 }
2394
2395
2396 extern void SetCheckpointReservedBlocks(int n);
2397
2398 void checkpoint_upgrade_test(const char *mountpt, int nmounts)
2399 {
2400
2401         char a[50];
2402         char b[50];
2403         char c[50];
2404         char d[50];
2405
2406         int j;
2407
2408         (void) nmounts;
2409
2410         sprintf(a,"%s/a",mountpt);
2411
2412         printf("Create start condition\n");
2413         yaffs_start_up();
2414         yaffs_mount(mountpt);
2415         yaffs_mkdir(a,0);
2416         sprintf(b,"%s/zz",a);
2417         sprintf(c,"%s/xx",a);
2418         make_file2(b,c,2000000);
2419         sprintf(d,"%s/aa",a);
2420         make_file2(d,NULL,500000000);
2421         dump_directory_tree(mountpt);
2422
2423         printf("Umount/mount attempt full\n");
2424         yaffs_unmount(mountpt);
2425
2426         yaffs_mount(mountpt);
2427
2428         printf("unlink small file\n");
2429         yaffs_unlink(c);
2430         dump_directory_tree(mountpt);
2431
2432         printf("Umount/mount attempt\n");
2433         yaffs_unmount(mountpt);
2434         yaffs_mount(mountpt);
2435
2436         for(j = 0; j < 500; j++){
2437                 printf("***** touch %d\n",j);
2438                 dump_directory_tree(mountpt);
2439                 yaffs_touch(b);
2440                 yaffs_unmount(mountpt);
2441                 yaffs_mount(mountpt);
2442         }
2443
2444         for(j = 0; j < 500; j++){
2445                 printf("***** touch %d\n",j);
2446                 dump_directory_tree(mountpt);
2447                 yaffs_touch(b);
2448                 yaffs_unmount(mountpt);
2449                 yaffs_mount(mountpt);
2450         }
2451 }
2452
2453 void huge_array_test(const char *mountpt,int n)
2454 {
2455
2456         char a[50];
2457
2458
2459         int i;
2460         int space;
2461
2462         int fnum;
2463
2464         sprintf(a,"mount point %s",mountpt);
2465
2466
2467
2468         yaffs_start_up();
2469
2470         yaffs_mount(mountpt);
2471
2472         while(n>0){
2473                 n--;
2474                 fnum = 0;
2475                 printf("\n\n START run\n\n");
2476                 while((space = yaffs_freespace(mountpt)) > 25000000){
2477                         sprintf(a,"%s/file%d",mountpt,fnum);
2478                         fnum++;
2479                         printf("create file %s, free space %d\n",a,space);
2480                         create_file_of_size(a,10000000);
2481                         printf("verifying file %s\n",a);
2482                         verify_file_of_size(a,10000000);
2483                 }
2484
2485                 printf("\n\n verification/deletion\n\n");
2486
2487                 for(i = 0; i < fnum; i++){
2488                         sprintf(a,"%s/file%d",mountpt,i);
2489                         printf("verifying file %s\n",a);
2490                         verify_file_of_size(a,10000000);
2491                         printf("deleting file %s\n",a);
2492                         yaffs_unlink(a);
2493                 }
2494                 printf("\n\n done \n\n");
2495
2496
2497         }
2498 }
2499
2500
2501 void random_write(int h)
2502 {
2503         static char buffer[12000];
2504         int n;
2505
2506         n = random() & 0x1FFF;
2507         yaffs_write(h,buffer,n);
2508 }
2509
2510 void random_seek(int h)
2511 {
2512         int n;
2513         n = random() & 0xFFFFF;
2514         yaffs_lseek(h,n,SEEK_SET);
2515 }
2516
2517 void random_truncate(int h, char *name)
2518 {
2519         int n;
2520         int flen;
2521
2522         (void) name;
2523
2524         n = random() & 0xFFFFF;
2525         flen = yaffs_lseek(h,0,SEEK_END);
2526         if(n > flen)
2527                 n = flen / 2;
2528         yaffs_ftruncate(h,n);
2529         yaffs_lseek(h,n,SEEK_SET);
2530 }
2531
2532
2533 #define NSMALLFILES 10
2534 void random_small_file_test(const char *mountpt,int iterations)
2535 {
2536
2537         char a[NSMALLFILES][50];
2538
2539
2540         int i;
2541         int n;
2542         int h[NSMALLFILES];
2543         int r;
2544
2545
2546         yaffs_start_up();
2547
2548         yaffs_mount(mountpt);
2549
2550         for(i = 0; i < NSMALLFILES; i++){
2551                 h[i]=-1;
2552                 strcpy(a[i],"");
2553         }
2554
2555         for(n = 0; n < iterations; n++){
2556
2557                 for(i = 0; i < NSMALLFILES; i++) {
2558                         r = random();
2559
2560                         if(strlen(a[i]) == 0){
2561                                 sprintf(a[i],"%s/%dx%d",mountpt,n,i);
2562                                 h[i] = yaffs_open(a[i],O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2563                         }
2564
2565                         if(h[i] < -1)
2566                                 printf("Could not open yaffs file %d %d error %d\n",n,i,h[i]);
2567                         else {
2568                                 r = r & 7;
2569                                 switch(r){
2570                                         case 0:
2571                                         case 1:
2572                                         case 2:
2573                                                 random_write(h[i]);
2574                                                 break;
2575                                         case 3:
2576                                                 random_truncate(h[i],a[i]);
2577                                                 break;
2578                                         case 4:
2579                                         case 5: random_seek(h[i]);
2580                                                 break;
2581                                         case 6:
2582                                                 yaffs_close(h[i]);
2583                                                 h[i] = -1;
2584                                                 break;
2585                                         case 7:
2586                                                 yaffs_close(h[i]);
2587                                                 yaffs_unlink(a[i]);
2588                                                 strcpy(a[i],"");
2589                                                 h[i] = -1;
2590                                 }
2591                         }
2592                 }
2593
2594         }
2595
2596         for(i = 0; i < NSMALLFILES; i++)
2597                 yaffs_close(h[i]);
2598
2599         yaffs_unmount(mountpt);
2600 }
2601
2602 void rmdir_test(const char *mountpt)
2603 {
2604         char name[100];
2605         yaffs_start_up();
2606
2607         yaffs_mount(mountpt);
2608
2609         strcpy(name,mountpt);
2610         strcat(name,"/");
2611         strcat(name,"hello");
2612         yaffs_mkdir(name,0666);
2613         yaffs_rmdir(name);
2614         yaffs_unmount(mountpt);
2615 }
2616
2617
2618
2619 static void print_xattrib_val(const char *path, const char *name)
2620 {
2621         char buffer[1000];
2622         int n;
2623
2624         n = yaffs_getxattr(path,name,buffer,sizeof(buffer));
2625         if(n >= 0){
2626                 u8 *b = (u8 *)buffer;
2627
2628                 printf("%d bytes:",n);
2629                 if(n > 10)
2630                         n = 10;
2631                 while(n > 0){
2632                         printf("[%02X]",*b);
2633                         b++;
2634                         n--;
2635                 }
2636                 printf("\n");
2637         } else
2638                 printf(" Novalue result %d\n",n);
2639 }
2640
2641 static void list_xattr(const char *path)
2642 {
2643         char list[1000];
2644         int n=0;
2645         int list_len;
2646         int len;
2647
2648         list_len = yaffs_listxattr(path,list,sizeof(list));
2649         printf("xattribs for %s, result is %d\n",path,list_len);
2650         while(n < list_len){
2651                 len = strlen(list + n);
2652                 printf("\"%s\" value ",list+n);
2653                 print_xattrib_val(path,list + n);
2654                 n += (len + 1);
2655         }
2656         printf("end\n");
2657 }
2658
2659 void basic_utime_test(const char *mountpt)
2660 {
2661         char name[100];
2662         int h;
2663         int result;
2664         struct yaffs_utimbuf utb;
2665         struct yaffs_stat st;
2666
2667         //setup
2668         yaffs_start_up();
2669
2670         yaffs_mount(mountpt);
2671
2672         strcpy(name,mountpt);
2673         strcat(name,"/");
2674         strcat(name,"xfile");
2675
2676         yaffs_unlink(name);
2677
2678         printf("created\n");
2679         h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2680
2681         yaffs_fstat(h,&st);
2682         printf(" times before %llu %llu %llu\n",
2683                         ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2684
2685         //here are the last access and modification times.
2686         utb.actime = 1000;
2687         utb.modtime = 2000;
2688
2689         //futime sets the last modification and access time of the file
2690         result = yaffs_futime(h,&utb);
2691         printf("setting times using the futime function to a 1000 m 2000 result  %d\n",result);
2692
2693         //read the times from the file header
2694         yaffs_fstat(h,&st);
2695         printf(" times %llu %llu %llu\n",
2696                         ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2697
2698
2699         utb.actime = 5000;
2700         utb.modtime = 8000;
2701         result = yaffs_utime(name, &utb);
2702         printf("utime to a 5000 m 8000 result %d\n",result);
2703         yaffs_fstat(h,&st);
2704         printf(" times %llu %llu %llu\n",
2705                         ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2706
2707         result = yaffs_utime(name, NULL);
2708         printf("utime to NULL result %d\n",result);
2709         yaffs_fstat(h,&st);
2710         printf(" times %llu %llu %llu\n",
2711                         ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2712
2713
2714 }
2715
2716 void print_binary(u64 val){
2717         int count = 0;
2718         for (int i= 63; i>=0; i --) {
2719                 if (count == 0){
2720                         printf(" ");
2721                 }
2722                 if ((((u64)1) << i) & val) {
2723                         printf("1");
2724                 } else {
2725                         printf("0");
2726                 }
2727                 count = (count +1) % 8;
2728         }
2729 }
2730
2731 void testing_swap_u64() {
2732         int numberOfFailedTests = 0;
2733         for (int i =0; i < 8; i ++) {
2734                 u64 startingNumber = (0xffLLu << (i*8));
2735                 u64 expected = (0xffLLu << (64 - (i*8) -8));
2736                 u64 converted = swap_u64(startingNumber);
2737                 if (converted != expected) {
2738                         numberOfFailedTests ++;
2739                         printf("numbers do not match.\n");
2740                         printf("0xff\t\t\t");
2741                         print_binary(0xff);
2742                         printf("\nStarting Number \t");
2743             print_binary(startingNumber);
2744                         printf("\nExpecting \t\t");
2745                         print_binary(expected);
2746                         printf("\nConverted \t\t");
2747                         print_binary(converted);
2748
2749                         printf("\n");
2750                 }
2751         }
2752         if (numberOfFailedTests){
2753                 printf("testing_swap failed %d tests\n", numberOfFailedTests);
2754         } else {
2755                 printf("testing_swap_u64 passed all tests\n");
2756         }
2757 }
2758
2759
2760 void size_utime_test(const char *mountpt)
2761 {
2762         char name[100];
2763         int h;
2764         int result;
2765         struct yaffs_utimbuf utb;
2766         struct yaffs_stat st;
2767
2768         //setup
2769         yaffs_start_up();
2770
2771         yaffs_mount(mountpt);
2772
2773         strcpy(name,mountpt);
2774         strcat(name,"/");
2775         strcat(name,"xfile");
2776
2777         yaffs_unlink(name);
2778
2779         printf("created\n");
2780         h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2781
2782         yaffs_fstat(h,&st);
2783         printf(" times before %llu %llu %llu\n",
2784                           ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2785
2786         //first lets get the yaffs_object.
2787
2788         //then check that yaffs_stat also works.
2789         //yaffs_stat already uses 64 bits for both wince and unix times.
2790         //To see if we are using 32 or 64 bit time, save a large number into the time and
2791         //see if it overflows.
2792         long bitsInTime = 8*sizeof(st.yst_ctime);
2793         printf("the times are %ld bits long\n", bitsInTime);
2794
2795         //two testcases
2796         if (bitsInTime == 64) {
2797                 //no need to test the overflow. Just check that it can be retrieved intact.
2798
2799                         //use u64 variables in case utb truncates the values to 32 bit time by accident.
2800                         u64 start = 0xfffff;
2801                         u64 end =       0xffffff;
2802
2803                 utb.actime =  start;
2804                 utb.modtime = end;
2805
2806                 result = yaffs_futime(h,&utb);
2807                 yaffs_fstat(h,&st);
2808                 if (st.yst_atime == start && st.yst_mtime == end) {
2809                         printf("successfully stored and retrevied a 64 bit number for atime and modtime\n");
2810                 } else {
2811                         printf("failed to store and retrieve a 64 bit number for atime and modtime\n");
2812
2813                 }
2814         } else {
2815                 //it is a 32 bit number. Check to see that it overflowed.
2816
2817         }
2818
2819
2820         //here are the last access and modification times.
2821         utb.actime = 1000;
2822         utb.modtime = 2000;
2823
2824         //futime sets the last modification and access time of the file
2825         result = yaffs_futime(h,&utb);
2826         printf("setting times using the futime function to a 1000 m 2000 result  %d\n",result);
2827
2828         //read the times from the file header
2829         yaffs_fstat(h,&st);
2830         printf(" times %llu %llu %llu\n",
2831                    ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2832
2833
2834         utb.actime = 5000;
2835         utb.modtime = 8000;
2836         result = yaffs_utime(name, &utb);
2837         printf("utime to a 5000 m 8000 result %d\n",result);
2838         yaffs_fstat(h,&st);
2839         printf(" times %llu %llu %llu\n",
2840                    ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2841
2842         result = yaffs_utime(name, NULL);
2843         printf("utime to NULL result %d\n",result);
2844         yaffs_fstat(h,&st);
2845         printf(" times %llu %llu %llu\n",
2846                    ( u64) st.yst_atime, ( u64) st.yst_ctime, ( u64) st.yst_mtime);
2847
2848
2849 }
2850
2851
2852 void basic_xattr_test(const char *mountpt)
2853 {
2854         char name[100];
2855         int h;
2856         int result;
2857         int val1;
2858
2859         yaffs_start_up();
2860
2861         yaffs_mount(mountpt);
2862
2863         strcpy(name,mountpt);
2864         strcat(name,"/");
2865         strcat(name,"xfile");
2866
2867         yaffs_unlink(name);
2868         h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2869         yaffs_close(h);
2870
2871         printf("Start\n");
2872         list_xattr(name);
2873
2874         printf("Add an attribute\n");
2875         val1 = 0x123456;
2876         result = yaffs_setxattr(name,"foo",&val1,sizeof(val1),0);
2877         printf("wrote attribute foo: result %d\n",result);
2878         list_xattr(name);
2879         printf("Add an attribute\n");
2880         val1 = 0x7890;
2881         result = yaffs_setxattr(name,"bar",&val1,sizeof(val1),0);
2882         printf("wrote attribute bar: result %d\n",result);
2883         list_xattr(name);
2884
2885         printf("Get non-existanrt attribute\n");
2886         print_xattrib_val(name,"not here");
2887
2888         printf("Delete non existing attribute\n");
2889         yaffs_removexattr(name,"not here");
2890         list_xattr(name);
2891
2892         printf("Remove foo\n");
2893         yaffs_removexattr(name,"foo");
2894         list_xattr(name);
2895
2896         printf("Remove bar\n");
2897         yaffs_removexattr(name,"bar");
2898         list_xattr(name);
2899
2900 }
2901
2902 void big_xattr_test(const char *mountpt)
2903 {
2904         char name[100];
2905         int h;
2906         int result;
2907         char val[1000];
2908
2909         yaffs_start_up();
2910
2911         yaffs_mount(mountpt);
2912
2913         strcpy(name,mountpt);
2914         strcat(name,"/");
2915         strcat(name,"xfile");
2916
2917         yaffs_unlink(name);
2918         h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2919         yaffs_close(h);
2920
2921         printf("Start\n");
2922         list_xattr(name);
2923
2924         printf("Add a large  attribute\n");
2925         memset(val,0x1,sizeof(val));
2926         result = yaffs_setxattr(name,"aaa",val,200,0);
2927         printf("wrote attribute aaa: result %d\n",result);
2928         list_xattr(name);
2929
2930         printf("Add a large  attribute\n");
2931         memset(val,0x2,sizeof(val));
2932         result = yaffs_setxattr(name,"bbb",val,1000,0);
2933         printf("wrote attribute bbb: result %d\n",result);
2934         list_xattr(name);
2935
2936         printf("Replace attribute\n");
2937         memset(val,0x3,sizeof(val));
2938         result = yaffs_setxattr(name,"aaa",val,1000,0);
2939         printf("wrote attribute aaa: result %d\n",result);
2940         list_xattr(name);
2941
2942 }
2943
2944
2945 void dump_dev_stats(struct yaffs_dev *dev, const char * str)
2946 {
2947         printf("%s\n",str);
2948         printf( "space free %d erased %d "
2949                 "nand reads %d writes %d erases %d "
2950                 "gc all %d passive %d oldestdirty %d blocks %d copies %d \n",
2951                 dev->n_free_chunks, dev->n_erased_blocks * dev->param.chunks_per_block,
2952                 dev->n_page_reads, dev->n_page_writes, dev->n_erasures,
2953                 dev->all_gcs, dev->passive_gc_count, dev->oldest_dirty_gc_count, dev->n_gc_blocks, dev->n_gc_copies);
2954 }
2955
2956 void test_flash_traffic(const char *mountpt)
2957 {
2958         char name0[100];
2959         char name1[100];
2960         int i;
2961         struct yaffs_dev *dev;
2962
2963         yaffs_trace_mask = 0;
2964
2965         yaffs_start_up();
2966
2967         yaffs_mount(mountpt);
2968
2969         dev = yaffs_getdev(mountpt);
2970
2971         strcpy(name0,mountpt);
2972         strcat(name0,"/x");
2973
2974         strcpy(name1,mountpt);
2975         strcat(name1,"/y");
2976
2977         dump_dev_stats(dev,"start");
2978         create_file_of_size(name0,32 * 1024 * 1024);
2979         dump_dev_stats(dev,"32MB written");
2980         for(i = 0; i < 20; i++)
2981                 create_file_of_size(name1,1024 * 1024);
2982         dump_dev_stats(dev,"20x 1MB files written");
2983
2984 }
2985
2986 void link_follow_test(const char *mountpt)
2987 {
2988         char fn[100];
2989         char sn[100];
2990         char hn[100];
2991         int result;
2992         int h;
2993
2994         yaffs_trace_mask = 0;
2995
2996         yaffs_start_up();
2997
2998         yaffs_mount(mountpt);
2999
3000         sprintf(fn,"%s/file",mountpt);
3001         sprintf(sn,"%s/sym",mountpt);
3002         sprintf(hn,"%s/hl-sym",mountpt);
3003
3004         h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
3005         result = yaffs_close(h);
3006
3007         result = yaffs_symlink(fn,sn);
3008         result = yaffs_link(sn,hn);
3009
3010         if (result < 0)
3011                 printf("At line %d result is %d\n", __LINE__, result);
3012
3013         h =yaffs_open(hn,O_RDWR,0);
3014
3015 }
3016
3017 void max_files_test(const char *mountpt)
3018 {
3019         char fn[100];
3020
3021         int result;
3022         int h;
3023         int i;
3024
3025         yaffs_trace_mask = 0;
3026
3027         yaffs_start_up();
3028
3029         yaffs_mount(mountpt);
3030
3031         for(i = 0; i < 5000; i++) {
3032                 sprintf(fn,"%s/file%d", mountpt, i);
3033                 yaffs_unlink(fn);
3034                 h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
3035                 if(h < 0)
3036                         printf("File %s not created\n", fn);
3037                 yaffs_write(h,fn,100);
3038                 result = yaffs_close(h);
3039         }
3040         for(i = 0; i < 5; i++){
3041                 sprintf(fn,"%s/file%d",mountpt, i);
3042                 yaffs_unlink(fn);
3043         }
3044
3045         for(i = 1000; i < 1010; i++){
3046                 sprintf(fn,"%s/file%d",mountpt, i);
3047                 h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
3048                 yaffs_write(h,fn,100);
3049                 if(h < 0)
3050                         printf("File %s not created\n", fn);
3051                 result = yaffs_close(h);
3052         }
3053
3054         if (result < 0)
3055                 printf("At line %d result is %d\n", __LINE__, result);
3056
3057         yaffs_unmount(mountpt);
3058 }
3059
3060 void case_insensitive_test(const char *mountpt)
3061 {
3062         char fn[100];
3063         char fn2[100];
3064         char buffer[100];
3065         int ret;
3066         struct yaffs_stat s;
3067         int h;
3068         char *x;
3069
3070         yaffs_trace_mask = 0;
3071
3072         yaffs_start_up();
3073
3074         yaffs_mount(mountpt);
3075         dump_directory_tree(mountpt);
3076
3077         sprintf(fn,"%s/Abc.Txt",mountpt);
3078         yaffs_unlink(fn);
3079         h = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
3080
3081         ret = yaffs_write(h,fn, strlen(fn) + 1);
3082
3083         ret = yaffs_close(h);
3084
3085         dump_directory_tree(mountpt);
3086
3087
3088         strcpy(fn2, fn);
3089         x = fn2;
3090         while(*x) {
3091                 *x = toupper(*x);
3092                 x++;
3093         }
3094
3095         h = yaffs_open(fn2, O_RDONLY, 0);
3096         ret = yaffs_read(h, buffer, 100);
3097
3098         if (ret != (int)(strlen(fn) + 1) || memcmp(buffer, fn, ret)){
3099                 printf("wrong file read\n");
3100         } else {
3101                 printf("File %s is the same as file %s\n", fn, fn2);
3102         }
3103
3104         ret = yaffs_stat(fn2, &s);
3105
3106         printf("renaming\n");
3107
3108         ret = yaffs_rename(fn, fn2);
3109         dump_directory_tree(mountpt);
3110
3111 }
3112
3113 void start_twice(const char *mountpt)
3114 {
3115          printf("About to do first yaffs_start\n");
3116          yaffs_start_up();
3117          printf("started\n");
3118          printf("First mount returns %d\n", yaffs_mount(mountpt));
3119          printf("About to do second yaffs_start\n");
3120          yaffs_start_up();
3121          printf("started\n");
3122          printf("Second mount returns %d\n", yaffs_mount(mountpt));
3123 }
3124
3125 #define N_WRITES 2000
3126 #define STRIDE   2000
3127
3128 #define BUFFER_N 1100
3129 unsigned  xxbuffer[BUFFER_N];
3130
3131 void set_buffer(int n)
3132 {
3133         int i;
3134         for(i = 0; i < BUFFER_N; i++)
3135                 xxbuffer[i] = i + n;
3136 }
3137
3138 void write_big_sparse_file(int h)
3139 {
3140         int i;
3141         loff_t offset = 0;
3142         loff_t pos;
3143         int n = sizeof(xxbuffer);
3144         int wrote;
3145
3146         for(i = 0; i < N_WRITES; i++) {
3147                 printf("writing at %d\n", (int)offset);
3148                 set_buffer(i);
3149                 pos = yaffs_lseek(h, offset, SEEK_SET);
3150                 if(pos != offset) {
3151                         printf("mismatched seek pos %d offset %d\n",
3152                                 (int)pos, (int)offset);
3153                         perror("lseek64");
3154                         exit(1);
3155                 }
3156                 wrote = yaffs_write(h, xxbuffer, n);
3157
3158                 if(wrote != n) {
3159                         printf("mismatched write wrote %d n %d\n", wrote, n);
3160                         exit(1);
3161                 }
3162
3163                 offset += (STRIDE * sizeof(xxbuffer));
3164         }
3165
3166         yaffs_ftruncate(h, offset);
3167
3168 }
3169
3170 void verify_big_sparse_file(int h)
3171 {
3172         unsigned check_buffer[BUFFER_N];
3173         int i;
3174         loff_t offset = 0;
3175         loff_t pos;
3176         int n = sizeof(check_buffer);
3177         int result;
3178         int checks_failed = 0;
3179         int checks_passed = 0;
3180
3181         for(i = 0; i < N_WRITES * STRIDE; i++) {
3182                 if(i % STRIDE) {
3183                         memset(xxbuffer,0, n);
3184                 } else {
3185                         set_buffer(i/STRIDE);
3186                 }
3187                 pos = yaffs_lseek(h, offset, SEEK_SET);
3188                 if(pos != offset) {
3189                         printf("mismatched seek pos %d offset %d\n",
3190                                 (int)pos, (int)offset);
3191                         perror("lseek64");
3192                         exit(1);
3193                 }
3194                 result = yaffs_read(h, check_buffer, n);
3195
3196                 if(result != n) {
3197                         printf("mismatched read result %d n %d\n", result, n);
3198                         exit(1);
3199                 }
3200
3201                 if(memcmp(xxbuffer, check_buffer, n)) {
3202                         int j;
3203
3204                         printf("buffer at %d mismatches\n", (int)pos);
3205                         printf("xxbuffer ");
3206                         for(j = 0; j < 20; j++)
3207                                 printf(" %d",xxbuffer[j]);
3208                         printf("\n");
3209                         printf("check_buffer ");
3210                         for(j = 0; j < 20; j++)
3211                                 printf(" %d",check_buffer[j]);
3212                         printf("\n");
3213
3214                         checks_failed++;
3215                 } else {
3216                         checks_passed++;
3217                 }
3218
3219                 offset += sizeof(xxbuffer);
3220         }
3221
3222         printf("%d checks passed, %d checks failed\n", checks_passed, checks_failed);
3223
3224 }
3225
3226
3227 void large_file_test(const char *mountpt)
3228 {
3229         char xx_buffer[1000];
3230         int i;
3231         int handle;
3232         char fullname[100];
3233         loff_t file_end;
3234
3235         yaffs_trace_mask = 0;
3236
3237         yaffs_start_up();
3238
3239         yaffs_mount(mountpt);
3240         printf("mounted\n");
3241         dumpDir(mountpt);
3242
3243         sprintf(fullname, "%s/%s", mountpt, "big-test-file");
3244
3245         handle = yaffs_open(fullname, O_RDONLY, 0);
3246
3247         handle = yaffs_open(fullname, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
3248
3249         if(handle < 0) {
3250                 perror("opening file");
3251                 exit(1);
3252         }
3253
3254         write_big_sparse_file(handle);
3255         verify_big_sparse_file(handle);
3256
3257         yaffs_close(handle);
3258
3259         printf("Job done\n");
3260         yaffs_unmount(mountpt);
3261
3262         yaffs_mount(mountpt);
3263         printf("mounted again\n");
3264         dumpDir(mountpt);
3265         handle = yaffs_open(fullname, O_RDONLY, 0);
3266         verify_big_sparse_file(handle);
3267         yaffs_unmount(mountpt);
3268
3269
3270         yaffs_mount3(mountpt, 0, 1);
3271         printf("mounted with no checkpt\n");
3272         dumpDir(mountpt);
3273         handle = yaffs_open(fullname, O_RDONLY, 0);
3274         verify_big_sparse_file(handle);
3275         yaffs_unmount(mountpt);
3276
3277         /* Check resize by adding to the end, resizing back and verifying. */
3278         yaffs_mount3(mountpt, 0, 1);
3279         printf("checking resize\n");
3280         dumpDir(mountpt);
3281         handle = yaffs_open(fullname, O_RDWR, 0);
3282
3283         file_end = yaffs_lseek(handle, 0, SEEK_END);
3284         printf("file_end %d\n", (int)file_end);
3285         for(i = 0; i < 10000; i++)
3286                 yaffs_write(handle, xx_buffer, sizeof(xx_buffer));
3287         yaffs_ftruncate(handle, file_end);
3288
3289         verify_big_sparse_file(handle);
3290         yaffs_unmount(mountpt);
3291
3292 }
3293
3294
3295 int  mk_dir(const char *mp, const char *name)
3296 {
3297         char full_name[100];
3298
3299         sprintf(full_name, "%s/%s", mp, name);
3300
3301         return yaffs_mkdir(full_name, S_IREAD| S_IWRITE);
3302 }
3303
3304 int  mk_file(const char *mp, const char *name)
3305 {
3306         char full_name[100];
3307         int h;
3308
3309         sprintf(full_name, "%s/%s", mp, name);
3310
3311         h = yaffs_open(full_name, O_RDWR | O_CREAT | O_TRUNC, S_IREAD| S_IWRITE);
3312
3313         yaffs_write(h, name, strlen(name));
3314
3315         yaffs_close(h);
3316         return 0;
3317 }
3318
3319 void xx_test(const char *mountpt)
3320 {
3321         yaffs_start_up();
3322
3323         yaffs_format(mountpt,0,0,0);
3324
3325         yaffs_mount(mountpt);
3326         printf("mounted\n");
3327         dumpDir(mountpt);
3328
3329         printf("create files\n");
3330
3331         mk_dir(mountpt, "foo");
3332         mk_file(mountpt, "foo/f1");
3333         mk_file(mountpt, "foo/f2");
3334         mk_file(mountpt, "foo/f3");
3335         mk_file(mountpt, "foo/f4");
3336         dump_directory_tree(mountpt);
3337
3338         printf("unmount and remount\n");
3339
3340         /* Unmount/remount */
3341         yaffs_unmount(mountpt);
3342         yaffs_mount(mountpt);
3343         dump_directory_tree(mountpt);
3344 }
3345
3346 void yy_test(const char *mountpt)
3347 {
3348         yaffs_start_up();
3349
3350         yaffs_mount(mountpt);
3351         dump_directory_tree(mountpt);
3352 }
3353
3354
3355 void readdir_test(const char *mountpt)
3356 {
3357         int i;
3358         yaffs_DIR *dirs[100];
3359
3360         yaffs_trace_mask = 0;
3361
3362         yaffs_start_up();
3363
3364         yaffs_mount(mountpt);
3365
3366         for(i = 0; i < 100; i++) {
3367                  dirs[i] = yaffs_opendir(mountpt);
3368                  printf("%2d %p,", i, dirs[i]);
3369         }
3370
3371         printf("\n");
3372
3373         for(i = 0; i < 100; i++) {
3374                  if(dirs[i])
3375                           yaffs_closedir(dirs[i]);
3376         }
3377
3378
3379         for(i = 0; i < 100; i++) {
3380                  dirs[i] = yaffs_opendir(mountpt);
3381                  printf("%2d %p,", i, dirs[i]);
3382         }
3383
3384         yaffs_unmount(mountpt);
3385
3386 }
3387
3388 void format_test(const char *mountpt)
3389 {
3390         int ret;
3391
3392         yaffs_start_up();
3393
3394         ret = yaffs_format(mountpt, 0, 0, 0);
3395         printf("yaffs_format(...,0, 0, 0) of unmounted returned %d."
3396                 " Should return 0\n\n\n", ret);
3397
3398         yaffs_mount(mountpt);
3399
3400         ret = yaffs_format(mountpt, 0, 0, 0);
3401         printf("yaffs_format(...,0, 0, 0) of mounted returned %d."
3402                 " Should return -1 (busy)\n\n\n", ret);
3403
3404         ret = yaffs_format(mountpt, 1, 0, 0);
3405         printf("yaffs_format(...,1, 0, 0) of mounted returned %d."
3406                 " Should return 0.\n\n\n", ret);
3407
3408         ret = yaffs_mount(mountpt);
3409         printf("mount should return 0 returned %d\n\n\n", ret);
3410
3411         ret = yaffs_format(mountpt, 1, 0, 1);
3412         printf("yaffs_format(...,1, 0, 1) of mounted returned %d."
3413                 " Should return 0.\n\n\n", ret);
3414
3415         ret = yaffs_mount(mountpt);
3416         printf("mount should return -1 returned %d\n", ret);
3417 }
3418
3419 void dir_rename_test(const char *mountpt)
3420 {
3421          char fname[100];
3422          char dname[100];
3423          int h;
3424          int ret;
3425
3426          yaffs_start_up();
3427          yaffs_mount(mountpt);
3428
3429          sprintf(fname,"%s/file",mountpt);
3430          sprintf(dname,"%s/directory",mountpt);
3431
3432          h = yaffs_open(fname,O_CREAT | O_RDWR | O_TRUNC, 0666);
3433          yaffs_close(h);
3434
3435          yaffs_mkdir(dname, 0666);
3436
3437          dump_directory_tree(mountpt);
3438
3439          printf("Try to rename %s to %s\n", fname, dname);
3440          ret = yaffs_rename(fname, dname);
3441          printf("result %d, %d\n", ret, yaffs_get_error());
3442
3443          printf("Try to rename %s to %s\n", dname, fname);
3444          ret = yaffs_rename(dname, fname);
3445          printf("result %d, %d\n", ret, yaffs_get_error());
3446
3447
3448 }
3449
3450
3451 void dir_fd_test(const char *mountpt)
3452 {
3453         char name[100];
3454         int h;
3455         int i;
3456
3457         yaffs_start_up();
3458         yaffs_mount(mountpt);
3459
3460         sprintf(name,"%s/directory",mountpt);
3461         yaffs_mkdir(name, 0666);
3462         for(i=0; i < 20; i++) {
3463                 sprintf(name,"%s/directory/file%d",mountpt, i);
3464
3465                 h = yaffs_open(name, O_CREAT | O_TRUNC | O_RDWR, 0666);
3466                 yaffs_write(h, name, strlen(name));
3467                 yaffs_close(h);
3468         }
3469         sprintf(name,"%s/dddd",mountpt);
3470         yaffs_mkdir(name, 0666);
3471         for(i=0; i < 20; i++) {
3472                 sprintf(name,"%s/dddd/filezzz%d",mountpt, i);
3473
3474                 h = yaffs_open(name, O_CREAT | O_TRUNC | O_RDWR, 0666);
3475                 yaffs_write(h, name, strlen(name));
3476                 yaffs_close(h);
3477         }
3478
3479
3480         dump_directory_tree(mountpt);
3481         dump_directory_tree_fd(mountpt);
3482         dump_directory_tree_fd(mountpt);
3483
3484 }
3485
3486 void create_delete_many_files_test(const char *mountpt)
3487 {
3488
3489         char fn[100];
3490         int i;
3491         int fsize;
3492         char buffer[1000];
3493         int h;
3494         int wrote;
3495
3496
3497         yaffs_start_up();
3498         yaffs_mount(mountpt);
3499
3500         for(i = 1; i < 2000; i++) {
3501                 sprintf(fn,"%s/f%d",mountpt, i);
3502                 fsize = (i%10) * 10000 + 20000;
3503                 h = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, 0666);
3504                 while (fsize > 0) {
3505                         wrote = yaffs_write(h, buffer, sizeof(buffer));
3506                         if (wrote != sizeof(buffer)) {
3507                                 printf("Writing file %s, only wrote %d bytes\n", fn, wrote);
3508                                 break;
3509                         }
3510                         fsize -= wrote;
3511                 }
3512                 yaffs_unlink(fn);
3513                 yaffs_close(h);
3514         }
3515
3516 }
3517
3518 void find_device_check(void)
3519 {
3520         yaffs_start_up();
3521         yaffs_mount("/nand");
3522         yaffs_mount("/");
3523         yaffs_mkdir("/nandxxx", 0666);
3524         yaffs_mkdir("/nand/xxx", 0666);
3525 }
3526
3527
3528 void try_opendir(const char *str)
3529 {
3530         yaffs_DIR *d;
3531
3532         d = yaffs_opendir(str);
3533
3534         printf("%s --> %p\n", str, d);
3535
3536         if (d)
3537                 yaffs_closedir(d);
3538 }
3539
3540 void opendir_test(void)
3541 {
3542         yaffs_start_up();
3543         yaffs_mount("/nand/");
3544         yaffs_symlink("x", "/nand/sym");
3545         yaffs_mkdir("/nand/x",0666);
3546         yaffs_mkdir("/nand/y",0666);
3547         yaffs_mkdir("/nand/x/r",0666);
3548         yaffs_mkdir("/nand/x/s",0666);
3549         yaffs_mkdir("/nand/x/t",0666);
3550
3551         try_opendir("nand/x/.");
3552         try_opendir("nand/x/r/..");
3553         try_opendir("nand/x/./");
3554         try_opendir("nand/x/r/../");
3555         try_opendir("/nand/x");
3556         try_opendir("/nand/x/");
3557         try_opendir("nand/x");
3558         try_opendir("nand/sym");
3559         try_opendir("nand/sym/");
3560
3561 }
3562
3563 void try_rmdir(const char *str)
3564 {
3565         int ret;
3566
3567         ret= yaffs_rmdir(str);
3568
3569         printf("rmdir(\"%s\") --> %d, errno %d\n", str, ret, yaffs_get_error());
3570
3571 }
3572
3573 void rmdir_test2(void)
3574 {
3575         yaffs_start_up();
3576
3577         yaffs_mount("/nand/");
3578         yaffs_mkdir("/nand/z",0666);
3579         try_rmdir("/nand/z");
3580         yaffs_mkdir("/nand/z",0666);
3581         try_rmdir("/nand/z/");
3582 }
3583
3584
3585 void dump_yaffs_malloc_usage(void)
3586 {
3587         unsigned current;
3588         unsigned high_water;
3589
3590         yaffsfs_get_malloc_values(&current, &high_water);
3591
3592         printf("\n"
3593                "***************************************\n"
3594                "Dump of yaffs malloc usage during run\n"
3595                "Currently allocated : %u bytes\n"
3596                "High water allocated : %u bytes\n"
3597                "Note, this is not accurate on all platforms\n",
3598                 current, high_water);
3599
3600 }
3601
3602
3603 int random_seed;
3604 int simulate_power_failure;
3605
3606 int main(int argc, char *argv[])
3607 {
3608
3609         //unlink("emfile-nand");
3610
3611
3612         atexit(dump_yaffs_malloc_usage);
3613
3614         (void) argc;
3615         (void) argv;
3616
3617         random_seed = time(NULL);
3618         //return long_test(argc,argv);
3619
3620         //return cache_read_test();
3621
3622         // resize_stress_test_no_grow("/flash/flash",20);
3623         //root_perm_remount("/flash/flash");
3624
3625         //huge_directory_test_on_path("/ram2k");
3626
3627          //yaffs_backward_scan_test("/flash/flash");
3628         // yaffs_device_flush_test("/flash/flash");
3629
3630         //rename_over_test("//////////////////flash///////////////////yaffs1///////////");
3631
3632         //fill_empty_files_test("/nand/");
3633         //resize_stress_test("/nand");
3634         //overwrite_test("/nand");
3635
3636         //long_name_test("/nand");
3637         //link_test0("/nand");
3638         //link_test1("yaffs2");
3639          //scan_pattern_test("/flash",10000,10);
3640         //short_scan_test("/yflash2",40000,200);
3641         //short_scan_test("/nand128MB",40000,200);
3642           //small_mount_test("/flash/flash",1000);
3643           //small_overwrite_test("/flash/flash",1000);
3644           //seek_overwrite_test("/flash/flash",1000);
3645          //checkpoint_fill_test("/flash/flash",20);
3646          //checkpoint_upgrade_test("/flash/flash",20);
3647           //small_overwrite_test("/flash/flash",1000);
3648           //checkpoint_fill_test("/flash/flash",20);
3649         //random_small_file_test("/flash/flash",10000);
3650          // huge_array_test("/flash/flash",10);
3651
3652
3653         // handle_test("yaffs2/");
3654
3655         //long_test_on_path("/ram2k");
3656         // long_test_on_path("/flash");
3657         //simple_rw_test("/flash/flash");
3658         //fill_n_file_test("/nand128MB", 50, 128000000/50);
3659         // rename_over_test("/flash");
3660         //lookup_test("/flash");
3661         //freespace_test("/flash/flash");
3662
3663         //link_test("/flash/flash");
3664
3665         // cache_bypass_bug_test();
3666
3667          //free_space_check();
3668
3669          //check_resize_gc_bug("/flash");
3670
3671          //basic_xattr_test("/nand");
3672          //big_xattr_test("/nand");
3673
3674          //null_name_test("yaffs2");
3675
3676          //test_flash_traffic("yaffs2");
3677          // link_follow_test("/nand");
3678          //basic_utime_test("/nand");
3679
3680
3681         //format_test("/nand");
3682
3683         //max_files_test("/nand");
3684
3685          //start_twice("/nand");
3686
3687          //large_file_test("/nand");
3688          //readdir_test("/nand");
3689
3690          basic_utime_test("/nand");
3691          testing_swap_u64();
3692          size_utime_test("/nand");
3693          //case_insensitive_test("/nand");
3694
3695          //yy_test("/nand");
3696          //dir_rename_test("/nand");
3697
3698         //dir_fd_test("/nand");
3699
3700         //format_test("/nand");
3701
3702         //opendir_test();
3703         //rmdir_test2();
3704
3705         //create_delete_many_files_test("/nand");
3706          return 0;
3707
3708 }