fd4f9666dd4fb6adb44754da61dc9743dbd77568
[yaffs2.git] / direct / dtest.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
3  *
4  * Copyright (C) 2002 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
6  *
7  * Created by Charles Manning <charles@aleph1.co.uk>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  */
14
15
16
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22
23 #include "yaffsfs.h"
24
25 #include "nor_stress.h"
26
27 void dumpDir(const char *dname);
28
29 char xx[600];
30
31 void copy_in_a_file(char *yaffsName,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(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
124
125
126 int dump_file_data(char *fn)
127 {
128         int h;
129         int i = 0;
130         int ok = 1;
131         unsigned char b;
132         
133         h = yaffs_open(fn, O_RDWR,0);
134
135                                 
136         printf("%s\n",fn);
137         while(yaffs_read(h,&b,1)> 0)
138         {
139                 printf("%02x",b);
140                 i++;
141                 if(i > 32) 
142                 {
143                    printf("\n");
144                    i = 0;;
145                  }
146         }
147         printf("\n");
148         yaffs_close(h);
149         return ok;
150 }
151
152
153
154 void dump_file(const char *fn)
155 {
156         int i;
157         int size;
158         int h;
159         
160         h = yaffs_open(fn,O_RDONLY,0);
161         if(h < 0)
162         {
163                 printf("*****\nDump file %s does not exist\n",fn);
164         }
165         else
166         {
167                 size = yaffs_lseek(h,0,SEEK_SET);
168                 printf("*****\nDump file %s size %d\n",fn,size);
169                 for(i = 0; i < size; i++)
170                 {
171                         
172                 }
173         }
174 }
175
176 void create_file_of_size(const char *fn,int syze)
177 {
178         int h;
179         int n;
180         int result;
181         
182         char xx[200];
183         
184         int iterations = (syze + strlen(fn) -1)/ strlen(fn);
185         
186         h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
187                 
188         while (iterations > 0)
189         {
190                 sprintf(xx,"%s %8d",fn,iterations);
191                 n = strlen(xx);
192                 result = yaffs_write(h,xx,n);
193                 if(result != n)
194                         printf("Wrote %d, should have been %d\n",result,n);
195                 iterations--;
196         }
197         yaffs_close (h);
198 }
199
200 void verify_file_of_size(const char *fn,int syze)
201 {
202         int h;
203         int result;
204         
205         char xx[200];
206         char yy[200];
207         int l;
208         
209         int iterations = (syze + strlen(fn) -1)/ strlen(fn);
210         
211         h = yaffs_open(fn, O_RDONLY, S_IREAD | S_IWRITE);
212                 
213         while (iterations > 0)
214         {
215                 sprintf(xx,"%s %8d",fn,iterations);
216                 l = strlen(xx);
217                 
218                 result = yaffs_read(h,yy,l);
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_StartUp();        
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 char xxzz[2000];
297
298
299 void yaffs_device_flush_test(const char *path)
300 {
301         char fn[100];
302         int h;
303         int i;
304         
305         yaffs_StartUp();        
306         
307         yaffs_mount(path);
308         
309         do_some_file_stuff(path);
310         
311         // Open and add some data to a few files
312         for(i = 0; i < 10; i++) {
313         
314                 sprintf(fn,"%s/ff%d",path,i);
315
316                 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IWRITE | S_IREAD);
317                 yaffs_write(h,xxzz,2000);
318                 yaffs_write(h,xxzz,2000);
319         }
320         yaffs_unmount(path);
321         
322         yaffs_mount(path);
323 }
324
325
326
327 void short_scan_test(const char *path, int fsize, int niterations)
328 {
329         int i;
330         char fn[100];
331         
332         sprintf(fn,"%s/%s",path,"f1");
333         
334         yaffs_StartUp();
335         for(i = 0; i < niterations; i++)
336         {
337                 printf("\n*****************\nIteration %d\n",i);
338                 yaffs_mount(path);
339                 printf("\nmount: Directory look-up of %s\n",path);
340                 dumpDir(path);
341                 make_a_file(fn,1,fsize);
342                 yaffs_unmount(path);
343         }
344 }
345
346
347
348 void scan_pattern_test(const char *path, int fsize, int niterations)
349 {
350         int i;
351         int j;
352         char fn[3][100];
353         int result;
354         
355         sprintf(fn[0],"%s/%s",path,"f0");
356         sprintf(fn[1],"%s/%s",path,"f1");
357         sprintf(fn[2],"%s/%s",path,"f2");
358         
359         yaffs_StartUp();
360         
361         for(i = 0; i < niterations; i++)
362         {
363                 printf("\n*****************\nIteration %d\n",i);
364                 yaffs_mount(path);
365                 printf("\nmount: Directory look-up of %s\n",path);
366                 dumpDir(path);
367                 for(j = 0; j < 3; j++)
368                 {
369                         result = dump_file_data(fn[j]);
370                         result = check_pattern_file(fn[j]);
371                         make_pattern_file(fn[j],fsize); 
372                         result = dump_file_data(fn[j]);
373                         result = check_pattern_file(fn[j]);
374                 }
375                 yaffs_unmount(path);
376         }
377 }
378
379 void fill_disk(const char *path,int nfiles)
380 {
381         int h;
382         int n;
383         int result;
384         int f;
385         
386         char str[50];
387         
388         for(n = 0; n < nfiles; n++)
389         {
390                 sprintf(str,"%s/%d",path,n);
391                 
392                 h = yaffs_open(str, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
393                 
394                 printf("writing file %s handle %d ",str, h);
395                 
396                 while ((result = yaffs_write(h,xx,600)) == 600)
397                 {
398                         f = yaffs_freespace(path);
399                 }
400                 result = yaffs_close(h);
401                 printf(" close %d\n",result);
402         }
403 }
404
405 void fill_disk_and_delete(const char *path, int nfiles, int ncycles)
406 {
407         int i,j;
408         char str[50];
409         int result;
410         
411         for(i = 0; i < ncycles; i++)
412         {
413                 printf("@@@@@@@@@@@@@@ cycle %d\n",i);
414                 fill_disk(path,nfiles);
415                 
416                 for(j = 0; j < nfiles; j++)
417                 {
418                         sprintf(str,"%s/%d",path,j);
419                         result = yaffs_unlink(str);
420                         printf("unlinking file %s, result %d\n",str,result);
421                 }
422         }
423 }
424
425
426 void fill_files(char *path,int flags, int maxIterations,int siz)
427 {
428         int i;
429         int j;
430         char str[50];
431         int h;
432         
433         i = 0;
434         
435         do{
436                 sprintf(str,"%s/%d",path,i);
437                 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
438                 yaffs_close(h);
439
440                 if(h >= 0)
441                 {
442                         for(j = 0; j < siz; j++)
443                         {
444                                 yaffs_write(h,str,1);
445                         }
446                 }
447                 
448                 if( flags & 1)
449                 {
450                         yaffs_unlink(str);
451                 }
452                 i++;
453         } while(h >= 0 && i < maxIterations);
454         
455         if(flags & 2)
456         {
457                 i = 0;
458                 do{
459                         sprintf(str,"%s/%d",path,i);
460                         printf("unlink %s\n",str);
461                         i++;
462                 } while(yaffs_unlink(str) >= 0);
463         }
464 }
465
466 void leave_unlinked_file(char *path,int maxIterations,int siz)
467 {
468         int i;
469         char str[50];
470         int h;
471         
472         i = 0;
473         
474         do{
475                 sprintf(str,"%s/%d",path,i);
476                 printf("create %s\n",str);
477                 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
478                 if(h >= 0)
479                 {
480                         yaffs_unlink(str);
481                 }
482                 i++;
483         } while(h < 0 && i < maxIterations);
484         
485         if(h >= 0)
486         {
487                 for(i = 0; i < siz; i++)
488                 {
489                         yaffs_write(h,str,1);
490                 }
491         }
492         
493         printf("Leaving file %s open\n",str);
494
495 }
496
497 void dumpDirFollow(const char *dname)
498 {
499         yaffs_DIR *d;
500         yaffs_dirent *de;
501         struct yaffs_stat s;
502         char str[100];
503                         
504         d = yaffs_opendir(dname);
505         
506         if(!d)
507         {
508                 printf("opendir failed\n");
509         }
510         else
511         {
512                 while((de = yaffs_readdir(d)) != NULL)
513                 {
514                         sprintf(str,"%s/%s",dname,de->d_name);
515                         
516                         yaffs_stat(str,&s);
517                         
518                         printf("%s ino %d length %d mode %X ",de->d_name,(int)s.st_ino,(int)s.st_size,s.st_mode);
519                         switch(s.st_mode & S_IFMT)
520                         {
521                                 case S_IFREG: printf("data file"); break;
522                                 case S_IFDIR: printf("directory"); break;
523                                 case S_IFLNK: printf("symlink -->");
524                                                           if(yaffs_readlink(str,str,100) < 0)
525                                                                 printf("no alias");
526                                                           else
527                                                                 printf("\"%s\"",str);    
528                                                           break;
529                                 default: printf("unknown"); break;
530                         }
531                         
532                         printf("\n");           
533                 }
534                 
535                 yaffs_closedir(d);
536         }
537         printf("\n");
538         
539         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
540
541 }
542
543
544 void dump_directory_tree_worker(const char *dname,int recursive)
545 {
546         yaffs_DIR *d;
547         yaffs_dirent *de;
548         struct yaffs_stat s;
549         char str[1000];
550                         
551         d = yaffs_opendir(dname);
552         
553         if(!d)
554         {
555                 printf("opendir failed\n");
556         }
557         else
558         {
559                 while((de = yaffs_readdir(d)) != NULL)
560                 {
561                         sprintf(str,"%s/%s",dname,de->d_name);
562                         
563                         yaffs_lstat(str,&s);
564                         
565                         printf("%s inode %d obj %x length %d mode %X ",str,s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);
566                         switch(s.st_mode & S_IFMT)
567                         {
568                                 case S_IFREG: printf("data file"); break;
569                                 case S_IFDIR: printf("directory"); break;
570                                 case S_IFLNK: printf("symlink -->");
571                                                           if(yaffs_readlink(str,str,100) < 0)
572                                                                 printf("no alias");
573                                                           else
574                                                                 printf("\"%s\"",str);    
575                                                           break;
576                                 default: printf("unknown"); break;
577                         }
578                         
579                         printf("\n");
580
581                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
582                                 dump_directory_tree_worker(str,1);
583                                                         
584                 }
585                 
586                 yaffs_closedir(d);
587         }
588
589 }
590
591 static void dump_directory_tree(const char *dname)
592 {
593         dump_directory_tree_worker(dname,1);
594         printf("\n");
595         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
596 }
597
598 void dumpDir(const char *dname)
599 {       dump_directory_tree_worker(dname,0);
600         printf("\n");
601         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
602 }
603
604
605 static void PermissionsCheck(const char *path, mode_t tmode, int tflags,int expectedResult)
606 {
607         int fd;
608         
609         if(yaffs_chmod(path,tmode)< 0) printf("chmod failed\n");
610         
611         fd = yaffs_open(path,tflags,0);
612         
613         if((fd >= 0) != (expectedResult > 0))
614         {
615                 printf("Permissions check %x %x %d failed\n",tmode,tflags,expectedResult);
616         }
617         else
618         {
619                 printf("Permissions check %x %x %d OK\n",tmode,tflags,expectedResult);
620         }
621         
622         
623         yaffs_close(fd);
624         
625         
626 }
627
628 int long_test(int argc, char *argv[])
629 {
630
631         int f;
632         int r;
633         char buffer[20];
634         
635         char str[100];
636         
637         int h;
638         mode_t temp_mode;
639         struct yaffs_stat ystat;
640         
641         yaffs_StartUp();
642         
643         yaffs_mount("/boot");
644         yaffs_mount("/data");
645         yaffs_mount("/flash");
646         yaffs_mount("/ram");
647         
648         printf("\nDirectory look-up of /boot\n");
649         dumpDir("/boot");
650         printf("\nDirectory look-up of /data\n");
651         dumpDir("/data");
652         printf("\nDirectory look-up of /flash\n");
653         dumpDir("/flash");
654
655         //leave_unlinked_file("/flash",20000,0);
656         //leave_unlinked_file("/data",20000,0);
657         
658         leave_unlinked_file("/ram",20,0);
659         
660
661         f = yaffs_open("/boot/b1", O_RDONLY,0);
662         
663         printf("open /boot/b1 readonly, f=%d\n",f);
664         
665         f = yaffs_open("/boot/b1", O_CREAT,S_IREAD | S_IWRITE);
666         
667         printf("open /boot/b1 O_CREAT, f=%d\n",f);
668         
669         
670         r = yaffs_write(f,"hello",1);
671         printf("write %d attempted to write to a read-only file\n",r);
672         
673         r = yaffs_close(f);
674         
675         printf("close %d\n",r);
676
677         f = yaffs_open("/boot/b1", O_RDWR,0);
678         
679         printf("open /boot/b1 O_RDWR,f=%d\n",f);
680         
681         
682         r = yaffs_write(f,"hello",2);
683         printf("write %d attempted to write to a writeable file\n",r);
684         r = yaffs_write(f,"world",3);
685         printf("write %d attempted to write to a writeable file\n",r);
686         
687         r= yaffs_lseek(f,0,SEEK_END);
688         printf("seek end %d\n",r);
689         memset(buffer,0,20);
690         r = yaffs_read(f,buffer,10);
691         printf("read %d \"%s\"\n",r,buffer);
692         r= yaffs_lseek(f,0,SEEK_SET);
693         printf("seek set %d\n",r);
694         memset(buffer,0,20);
695         r = yaffs_read(f,buffer,10);
696         printf("read %d \"%s\"\n",r,buffer);
697         memset(buffer,0,20);
698         r = yaffs_read(f,buffer,10);
699         printf("read %d \"%s\"\n",r,buffer);
700
701         // Check values reading at end.
702         // A read past end of file should return 0 for 0 bytes read.
703                 
704         r= yaffs_lseek(f,0,SEEK_END);
705         r = yaffs_read(f,buffer,10);
706         printf("read at end returned  %d\n",r); 
707         r= yaffs_lseek(f,500,SEEK_END);
708         r = yaffs_read(f,buffer,10);
709         printf("read past end returned  %d\n",r);       
710         
711         r = yaffs_close(f);
712         
713         printf("close %d\n",r);
714         
715         copy_in_a_file("/boot/yyfile","xxx");
716         
717         // Create a file with a long name
718         
719         copy_in_a_file("/boot/file with a long name","xxx");
720         
721         
722         printf("\nDirectory look-up of /boot\n");
723         dumpDir("/boot");
724
725         // Check stat
726         r = yaffs_stat("/boot/file with a long name",&ystat);
727         
728         // Check rename
729         
730         r = yaffs_rename("/boot/file with a long name","/boot/r1");
731         
732         printf("\nDirectory look-up of /boot\n");
733         dumpDir("/boot");
734         
735         // Check unlink
736         r = yaffs_unlink("/boot/r1");
737         
738         printf("\nDirectory look-up of /boot\n");
739         dumpDir("/boot");
740
741         // Check mkdir
742         
743         r = yaffs_mkdir("/boot/directory1",0);
744         
745         printf("\nDirectory look-up of /boot\n");
746         dumpDir("/boot");
747         printf("\nDirectory look-up of /boot/directory1\n");
748         dumpDir("/boot/directory1");
749
750         // add a file to the directory                  
751         copy_in_a_file("/boot/directory1/file with a long name","xxx");
752         
753         printf("\nDirectory look-up of /boot\n");
754         dumpDir("/boot");
755         printf("\nDirectory look-up of /boot/directory1\n");
756         dumpDir("/boot/directory1");
757         
758         //  Attempt to delete directory (should fail)
759         
760         r = yaffs_rmdir("/boot/directory1");
761         
762         printf("\nDirectory look-up of /boot\n");
763         dumpDir("/boot");
764         printf("\nDirectory look-up of /boot/directory1\n");
765         dumpDir("/boot/directory1");
766         
767         // Delete file first, then rmdir should work
768         r = yaffs_unlink("/boot/directory1/file with a long name");
769         r = yaffs_rmdir("/boot/directory1");
770         
771         
772         printf("\nDirectory look-up of /boot\n");
773         dumpDir("/boot");
774         printf("\nDirectory look-up of /boot/directory1\n");
775         dumpDir("/boot/directory1");
776
777 #if 0
778         fill_disk_and_delete("/boot",20,20);
779                         
780         printf("\nDirectory look-up of /boot\n");
781         dumpDir("/boot");
782 #endif
783
784         yaffs_symlink("yyfile","/boot/slink");
785         
786         yaffs_readlink("/boot/slink",str,100);
787         printf("symlink alias is %s\n",str);
788         
789         
790         
791         
792         printf("\nDirectory look-up of /boot\n");
793         dumpDir("/boot");
794         printf("\nDirectory look-up of /boot (using stat instead of lstat)\n");
795         dumpDirFollow("/boot");
796         printf("\nDirectory look-up of /boot/directory1\n");
797         dumpDir("/boot/directory1");
798
799         h = yaffs_open("/boot/slink",O_RDWR,0);
800         
801         printf("file length is %d\n",(int)yaffs_lseek(h,0,SEEK_END));
802         
803         yaffs_close(h);
804         
805         yaffs_unlink("/boot/slink");
806
807         
808         printf("\nDirectory look-up of /boot\n");
809         dumpDir("/boot");
810         
811         // Check chmod
812         
813         yaffs_stat("/boot/yyfile",&ystat);
814         temp_mode = ystat.st_mode;
815         
816         yaffs_chmod("/boot/yyfile",0x55555);
817         printf("\nDirectory look-up of /boot\n");
818         dumpDir("/boot");
819         
820         yaffs_chmod("/boot/yyfile",temp_mode);
821         printf("\nDirectory look-up of /boot\n");
822         dumpDir("/boot");
823         
824         // Permission checks...
825         PermissionsCheck("/boot/yyfile",0, O_WRONLY,0);
826         PermissionsCheck("/boot/yyfile",0, O_RDONLY,0);
827         PermissionsCheck("/boot/yyfile",0, O_RDWR,0);
828
829         PermissionsCheck("/boot/yyfile",S_IREAD, O_WRONLY,0);
830         PermissionsCheck("/boot/yyfile",S_IREAD, O_RDONLY,1);
831         PermissionsCheck("/boot/yyfile",S_IREAD, O_RDWR,0);
832
833         PermissionsCheck("/boot/yyfile",S_IWRITE, O_WRONLY,1);
834         PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDONLY,0);
835         PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDWR,0);
836         
837         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_WRONLY,1);
838         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDONLY,1);
839         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDWR,1);
840
841         yaffs_chmod("/boot/yyfile",temp_mode);
842         
843         //create a zero-length file and unlink it (test for scan bug)
844         
845         h = yaffs_open("/boot/zlf",O_CREAT | O_TRUNC | O_RDWR,0);
846         yaffs_close(h);
847         
848         yaffs_unlink("/boot/zlf");
849         
850         
851         yaffs_DumpDevStruct("/boot");
852         
853         fill_disk_and_delete("/boot",20,20);
854         
855         yaffs_DumpDevStruct("/boot");
856         
857         fill_files("/boot",1,10000,0);
858         fill_files("/boot",1,10000,5000);
859         fill_files("/boot",2,10000,0);
860         fill_files("/boot",2,10000,5000);
861         
862         leave_unlinked_file("/data",20000,0);
863         leave_unlinked_file("/data",20000,5000);
864         leave_unlinked_file("/data",20000,5000);
865         leave_unlinked_file("/data",20000,5000);
866         leave_unlinked_file("/data",20000,5000);
867         leave_unlinked_file("/data",20000,5000);
868         
869         yaffs_DumpDevStruct("/boot");
870         yaffs_DumpDevStruct("/data");
871         
872                 
873                 
874         return 0;
875
876 }
877
878 int huge_directory_test_on_path(char *path)
879 {
880
881         yaffs_DIR *d;
882         yaffs_dirent *de;
883         struct yaffs_stat s;
884
885         int f;
886         int i;
887
888         int total = 0;
889         int lastTotal = 0;
890         
891         char str[100];
892
893         
894         yaffs_StartUp();
895         
896         yaffs_mount(path);
897         
898         // Create a large number of files
899         
900         for(i = 0; i < 2000; i++)
901         {
902           sprintf(str,"%s/%d",path,i);
903           
904            f = yaffs_open(str,O_CREAT,S_IREAD | S_IWRITE);
905            yaffs_close(f);
906         }
907         
908         
909         
910         d = yaffs_opendir(path);
911         i = 0;
912         if (d) {
913         while((de = yaffs_readdir(d)) != NULL) {
914         if (total >lastTotal+100*9*1024||(i & 1023)==0){
915         printf("files = %d, total = %d\n",i, total);
916         lastTotal = total;
917         }
918                 i++;
919                 sprintf(str,"%s/%s",path,de->d_name);
920                 yaffs_lstat(str,&s);
921                 switch(s.st_mode & S_IFMT){
922                 case S_IFREG:
923         //printf("data file");
924         total += s.st_size;
925         break;
926         }
927         }
928         
929         yaffs_closedir(d);
930         }
931         
932         return 0;
933 }
934
935 int yaffs_scan_test(const char *path)
936 {
937         return 0;
938 }
939
940
941 void rename_over_test(const char *mountpt)
942 {
943         int i;
944         char a[100];
945         char b[100];
946         char c[100];
947         
948         sprintf(a,"%s/a",mountpt);
949         sprintf(b,"%s/b",mountpt);
950         sprintf(c,"%s/c",mountpt);
951         
952         yaffs_StartUp();
953         
954         yaffs_mount(mountpt);
955         
956         printf("Existing files\n");
957         dumpDirFollow(mountpt);
958         
959         
960         
961         i = yaffs_open(c,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
962         printf("File c handle is %d\n",i);
963         yaffs_close(i);
964         i = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE); 
965         yaffs_close(i);
966         i = yaffs_open(b,O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE);
967         yaffs_close(i);
968         yaffs_rename(a,b); // rename over
969         yaffs_rename(b,a); // rename back again (not renaimng over)
970         yaffs_rename(a,b); // rename back again (not renaimng over)
971         
972         
973         yaffs_unmount(mountpt);
974         
975 }
976
977
978 int resize_stress_test(const char *path)
979 {
980    int a,b,i,j;
981    int x;
982    int r;
983    char aname[100];
984    char bname[100];
985    
986    char abuffer[1000];
987    char bbuffer[1000];
988    
989    yaffs_StartUp();
990    
991    yaffs_mount(path);
992    
993    sprintf(aname,"%s%s",path,"/a");
994    sprintf(bname,"%s%s",path,"/b");
995    
996    memset(abuffer,'a',1000);
997    memset(bbuffer,'b',1000);
998    
999    a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1000    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1001    
1002    printf(" %s %d %s %d\n",aname,a,bname,b);
1003   
1004    x = 0;
1005    
1006    for(j = 0; j < 100; j++)
1007    {
1008                 yaffs_lseek(a,0,SEEK_END);
1009
1010                 
1011                 for(i = 0; i <20000; i++)
1012                 {
1013                    //r =        yaffs_lseek(b,i,SEEK_SET);
1014                         //r = yaffs_write(b,bbuffer,1000);
1015                         
1016                         if(x & 0x16)
1017                         {
1018                                 // shrink
1019                                 int syz = yaffs_lseek(a,0,SEEK_END);
1020                                 
1021                                 syz -= 500;
1022                                 if(syz < 0) syz = 0;
1023                                 yaffs_ftruncate(a,syz);
1024                                 
1025                         }
1026                         else
1027                         {
1028                                 //expand
1029                                 r = yaffs_lseek(a,i * 500,SEEK_SET);
1030                                 r = yaffs_write(a,abuffer,1000);
1031                         }
1032                         x++;
1033                         
1034                 }
1035    }
1036    
1037    return 0;
1038    
1039 }
1040
1041 int root_perm_remount(const char *path)
1042 {
1043    struct yaffs_stat s;
1044    
1045    yaffs_StartUp();
1046    
1047    yaffs_mount(path);
1048    
1049    yaffs_stat(path,&s);
1050    printf("root perms after mount %x\n",s.st_mode);
1051    
1052    yaffs_chmod(path, 0777);
1053
1054    yaffs_stat(path,&s);
1055    printf("root perms after setting to 0777 is  %x\n",s.st_mode);
1056    
1057    yaffs_unmount(path);
1058       
1059    return 0;
1060    
1061 }
1062
1063
1064 int resize_stress_test_no_grow_complex(const char *path,int iters)
1065 {
1066    int a,b,i,j;
1067    int x;
1068    int r;
1069    char aname[100];
1070    char bname[100];
1071    
1072    char abuffer[1000];
1073    char bbuffer[1000];
1074
1075    
1076    yaffs_StartUp();
1077    
1078    yaffs_mount(path);
1079    
1080    sprintf(aname,"%s%s",path,"/a");
1081    sprintf(bname,"%s%s",path,"/b");
1082    
1083    memset(abuffer,'a',1000);
1084    memset(bbuffer,'b',1000);
1085    
1086    a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1087    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1088    
1089    printf(" %s %d %s %d\n",aname,a,bname,b);
1090   
1091    x = 0;
1092    
1093    for(j = 0; j < iters; j++)
1094    {
1095                 yaffs_lseek(a,0,SEEK_END);
1096
1097                 
1098                 for(i = 0; i <20000; i++)
1099                 {
1100                    //r =        yaffs_lseek(b,i,SEEK_SET);
1101                         //r = yaffs_write(b,bbuffer,1000);
1102                         
1103                         if(!(x%20))
1104                         {
1105                                 // shrink
1106                                 int syz = yaffs_lseek(a,0,SEEK_END);
1107                                 
1108                                 while(syz > 4000)
1109                                 {
1110                                 
1111                                         syz -= 2050;
1112                                         if(syz < 0) syz = 0;
1113                                         yaffs_ftruncate(a,syz);
1114                                         syz = yaffs_lseek(a,0,SEEK_END);
1115                                         printf("shrink to %d\n",syz);
1116                                 }
1117                                 
1118                                 
1119                         }
1120                         else
1121                         {
1122                                 //expand
1123                                 r = yaffs_lseek(a,500,SEEK_END);
1124                                 r = yaffs_write(a,abuffer,1000);
1125                         }
1126                         x++;
1127                         
1128                                         
1129                 }
1130                 
1131                 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1132
1133    }
1134    
1135    return 0;
1136    
1137 }
1138
1139 int resize_stress_test_no_grow(const char *path,int iters)
1140 {
1141    int a,b,i,j;
1142    int x;
1143    int r;
1144    char aname[100];
1145    char bname[100];
1146    
1147    char abuffer[1000];
1148    char bbuffer[1000];
1149    
1150    yaffs_StartUp();
1151    
1152    yaffs_mount(path);
1153    
1154    sprintf(aname,"%s%s",path,"/a");
1155    sprintf(bname,"%s%s",path,"/b");
1156    
1157    memset(abuffer,'a',1000);
1158    memset(bbuffer,'b',1000);
1159    
1160    a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1161    b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1162    
1163    printf(" %s %d %s %d\n",aname,a,bname,b);
1164   
1165    x = 0;
1166    
1167    for(j = 0; j < iters; j++)
1168    {
1169                 yaffs_lseek(a,0,SEEK_END);
1170
1171                 
1172                 for(i = 0; i <20000; i++)
1173                 {
1174                    //r =        yaffs_lseek(b,i,SEEK_SET);
1175                         //r = yaffs_write(b,bbuffer,1000);
1176                         
1177                         if(!(x%20))
1178                         {
1179                                 // shrink
1180                                 int syz = yaffs_lseek(a,0,SEEK_END);
1181                                 
1182                                 while(syz > 4000)
1183                                 {
1184                                 
1185                                         syz -= 2050;
1186                                         if(syz < 0) syz = 0;
1187                                         yaffs_ftruncate(a,syz);
1188                                         syz = yaffs_lseek(a,0,SEEK_END);
1189                                         printf("shrink to %d\n",syz);
1190                                 }
1191                                 
1192                                 
1193                         }
1194                         else
1195                         {
1196                                 //expand
1197                                 r = yaffs_lseek(a,-500,SEEK_END);
1198                                 r = yaffs_write(a,abuffer,1000);
1199                         }
1200                         x++;
1201                         
1202                                         
1203                 }
1204                 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1205
1206    }
1207    
1208    return 0;
1209    
1210 }
1211
1212 int directory_rename_test(void)
1213 {
1214         int r;
1215         yaffs_StartUp();
1216         
1217         yaffs_mount("/ram");
1218         yaffs_mkdir("/ram/a",0);
1219         yaffs_mkdir("/ram/a/b",0);
1220         yaffs_mkdir("/ram/c",0);
1221         
1222         printf("\nDirectory look-up of /ram\n");
1223         dumpDir("/ram");
1224         dumpDir("/ram/a");
1225         dumpDir("/ram/a/b");
1226
1227         printf("Do rename (should fail)\n");
1228                 
1229         r = yaffs_rename("/ram/a","/ram/a/b/d");
1230         printf("\nDirectory look-up of /ram\n");
1231         dumpDir("/ram");
1232         dumpDir("/ram/a");
1233         dumpDir("/ram/a/b");
1234
1235         printf("Do rename (should not fail)\n");
1236                 
1237         r = yaffs_rename("/ram/c","/ram/a/b/d");
1238         printf("\nDirectory look-up of /ram\n");
1239         dumpDir("/ram");
1240         dumpDir("/ram/a");
1241         dumpDir("/ram/a/b");
1242         
1243         
1244         return 1;
1245         
1246 }
1247
1248 int cache_read_test(void)
1249 {
1250         int a,b,c;
1251         int i;
1252         int sizeOfFiles = 500000;
1253         char buffer[100];
1254         
1255         yaffs_StartUp();
1256         
1257         yaffs_mount("/boot");
1258         
1259         make_a_file("/boot/a",'a',sizeOfFiles);
1260         make_a_file("/boot/b",'b',sizeOfFiles);
1261
1262         a = yaffs_open("/boot/a",O_RDONLY,0);
1263         b = yaffs_open("/boot/b",O_RDONLY,0);
1264         c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
1265
1266         do{
1267                 i = sizeOfFiles;
1268                 if (i > 100) i = 100;
1269                 sizeOfFiles  -= i;
1270                 yaffs_read(a,buffer,i);
1271                 yaffs_read(b,buffer,i);
1272                 yaffs_write(c,buffer,i);
1273         } while(sizeOfFiles > 0);
1274         
1275         
1276         
1277         return 1;
1278         
1279 }
1280
1281 int cache_bypass_bug_test(void)
1282 {
1283         // This test reporoduces a bug whereby YAFFS caching *was* buypassed
1284         // resulting in erroneous reads after writes.
1285         // This bug has been fixed.
1286         
1287         int a;
1288         char buffer1[1000];
1289         char buffer2[1000];
1290         
1291         memset(buffer1,0,sizeof(buffer1));
1292         memset(buffer2,0,sizeof(buffer2));
1293                 
1294         yaffs_StartUp();
1295         
1296         yaffs_mount("/boot");
1297         
1298         // Create a file of 2000 bytes.
1299         make_a_file("/boot/a",'X',2000);
1300
1301         a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE);
1302         
1303         // Write a short sequence to the file.
1304         // This will go into the cache.
1305         yaffs_lseek(a,0,SEEK_SET);
1306         yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20); 
1307
1308         // Read a short sequence from the file.
1309         // This will come from the cache.
1310         yaffs_lseek(a,0,SEEK_SET);
1311         yaffs_read(a,buffer1,30); 
1312
1313         // Read a page size sequence from the file.
1314         yaffs_lseek(a,0,SEEK_SET);
1315         yaffs_read(a,buffer2,512); 
1316         
1317         printf("buffer 1 %s\n",buffer1);
1318         printf("buffer 2 %s\n",buffer2);
1319         
1320         if(strncmp(buffer1,buffer2,20))
1321         {
1322                 printf("Cache bypass bug detected!!!!!\n");
1323         }
1324         
1325         
1326         return 1;
1327 }
1328
1329
1330 int free_space_check(void)
1331 {
1332         int f;
1333         
1334                 yaffs_StartUp();
1335                 yaffs_mount("/boot");
1336             fill_disk("/boot/",2);
1337             f = yaffs_freespace("/boot");
1338             
1339             printf("%d free when disk full\n",f);           
1340             return 1;
1341 }
1342
1343 int truncate_test(void)
1344 {
1345         int a;
1346         int r;
1347         int i;
1348         int l;
1349
1350         char y[10];
1351
1352         yaffs_StartUp();
1353         yaffs_mount("/boot");
1354
1355         yaffs_unlink("/boot/trunctest");
1356         
1357         a = yaffs_open("/boot/trunctest", O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE);
1358         
1359         yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26);
1360         
1361         yaffs_ftruncate(a,3);
1362         l= yaffs_lseek(a,0,SEEK_END);
1363         
1364         printf("truncated length is %d\n",l);
1365
1366         yaffs_lseek(a,5,SEEK_SET);
1367         yaffs_write(a,"1",1);
1368
1369         yaffs_lseek(a,0,SEEK_SET);
1370         
1371         r = yaffs_read(a,y,10);
1372
1373         printf("read %d bytes:",r);
1374
1375         for(i = 0; i < r; i++) printf("[%02X]",y[i]);
1376
1377         printf("\n");
1378
1379         return 0;
1380
1381 }
1382
1383
1384
1385
1386
1387 void fill_disk_test(const char *mountpt)
1388 {
1389         int i;
1390         yaffs_StartUp();
1391         
1392         for(i = 0; i < 5; i++)
1393         {
1394                 yaffs_mount(mountpt);
1395                 fill_disk_and_delete(mountpt,100,i+1);
1396                 yaffs_unmount(mountpt);
1397         }
1398         
1399 }
1400
1401
1402
1403 void lookup_test(const char *mountpt)
1404 {
1405         int i;
1406         int h;
1407         char a[100];
1408         
1409
1410         yaffs_DIR *d;
1411         yaffs_dirent *de;
1412
1413         yaffs_StartUp();
1414         
1415         yaffs_mount(mountpt);
1416                                 
1417         d = yaffs_opendir(mountpt);
1418         
1419         if(!d)
1420         {
1421                 printf("opendir failed\n");
1422         }
1423         else
1424         {
1425                 
1426                 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1427                 {
1428                         printf("unlinking %s\n",de->d_name);
1429                         yaffs_unlink(de->d_name);
1430                 }
1431                 
1432                 printf("%d files deleted\n",i);
1433         }
1434         
1435         
1436         for(i = 0; i < 2000; i++){
1437         sprintf(a,"%s/%d",mountpt,i);
1438                 h =  yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0);
1439                 yaffs_close(h);
1440         }
1441
1442         yaffs_rewinddir(d);
1443         for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1444         {
1445                 printf("%d  %s\n",i,de->d_name);
1446         }       
1447         
1448         printf("%d files listed\n\n\n",i);
1449         
1450         yaffs_rewinddir(d);
1451         yaffs_readdir(d);
1452         yaffs_readdir(d);
1453         yaffs_readdir(d);
1454         
1455         for(i = 0; i < 2000; i++){
1456                 sprintf(a,"%s/%d",mountpt,i);
1457                 yaffs_unlink(a);
1458         }
1459         
1460                 
1461         yaffs_unmount(mountpt);
1462         
1463 }
1464
1465 void link_test(const char *mountpt)
1466 {
1467         int i;
1468         int h;
1469         char a[100];
1470         char b[100];
1471         char c[100];
1472
1473         sprintf(a,"%s/aaa",mountpt);
1474         sprintf(b,"%s/bbb",mountpt);
1475         sprintf(c,"%s/ccc",mountpt);
1476         
1477         yaffs_StartUp();
1478         
1479         yaffs_mount(mountpt);
1480         
1481         
1482         h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1483         for(i = 0; i < 100; i++)
1484                 yaffs_write(h,a,100);
1485         
1486         yaffs_close(h);
1487         
1488         yaffs_unlink(b);
1489         yaffs_unlink(c);
1490         yaffs_link(a,b);
1491         yaffs_link(a,c);
1492         yaffs_unlink(b);
1493         yaffs_unlink(c);
1494         yaffs_unlink(a);
1495         
1496         
1497         yaffs_unmount(mountpt);
1498         yaffs_mount(mountpt);
1499         
1500         printf("link test done\n");     
1501         
1502 }
1503
1504 void freespace_test(const char *mountpt)
1505 {
1506         int i;
1507         int h;
1508         char a[100];
1509         
1510         int  f0;
1511         int f1;
1512         int f2;
1513         int f3;
1514         sprintf(a,"%s/aaa",mountpt);
1515         
1516         yaffs_StartUp();
1517         
1518         yaffs_mount(mountpt);
1519         
1520         f0 = yaffs_freespace(mountpt);
1521         
1522         h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1523         
1524         for(i = 0; i < 100; i++)
1525                 yaffs_write(h,a,100);
1526         
1527         yaffs_close(h);
1528         
1529         f1 = yaffs_freespace(mountpt);
1530         
1531         yaffs_unlink(a);
1532         
1533         f2 = yaffs_freespace(mountpt);
1534         
1535                 
1536         yaffs_unmount(mountpt);
1537         yaffs_mount(mountpt);
1538         
1539         f3 = yaffs_freespace(mountpt);
1540         
1541         printf("%d\n%d\n%d\n%d\n",f0, f1,f2,f3);
1542         
1543         
1544 }
1545
1546 void simple_rw_test(const char *mountpt)
1547 {
1548         int i;
1549         int h;
1550         char a[100];
1551         
1552         int x;
1553         int result;
1554
1555         sprintf(a,"%s/aaa",mountpt);
1556         
1557         yaffs_StartUp();
1558         
1559         yaffs_mount(mountpt);
1560         
1561         yaffs_unlink(a);
1562         
1563         h = yaffs_open(a,O_CREAT| O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1564         
1565         for(i = 100000;i < 200000; i++){
1566                 result = yaffs_write(h,&i,sizeof(i));
1567                 
1568                 if(result != 4)
1569                 {
1570                         printf("write error\n");
1571                         exit(1);
1572                 }
1573         }
1574         
1575         //yaffs_close(h);
1576         
1577         // h = yaffs_open(a,O_RDWR, S_IREAD | S_IWRITE);
1578         
1579         
1580         yaffs_lseek(h,0,SEEK_SET);
1581         
1582         for(i = 100000; i < 200000; i++){
1583                 result = yaffs_read(h,&x,sizeof(x));
1584                 
1585                 if(result != 4 || x != i){
1586                         printf("read error %d %x %x\n",i,result,x);
1587                 }
1588         }
1589         
1590         printf("Simple rw test passed\n");
1591         
1592         
1593         
1594 }
1595
1596
1597 void scan_deleted_files_test(const char *mountpt)
1598 {
1599         char fn[100];
1600         char sub[100];
1601         
1602         const char *p;
1603         
1604         int i;
1605         int j;
1606         int k;
1607         int h;
1608         
1609         sprintf(sub,"%s/sdir",mountpt);
1610         yaffs_StartUp();
1611         
1612         for(j = 0; j < 10; j++)
1613         {
1614                 printf("\n\n>>>>>>> Run %d <<<<<<<<<<<<<\n\n",j);
1615                 yaffs_mount(mountpt);
1616                 yaffs_mkdir(sub,0);
1617                 
1618                 
1619                 p = (j & 0) ? mountpt: sub;
1620         
1621                 for(i = 0; i < 100; i++)
1622                 {
1623                   sprintf(fn,"%s/%d",p,i);  
1624                   
1625                   if(i & 1)
1626                   {
1627                           h = yaffs_open(fn,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1628                           for(k = 0; k < 1000; k++)
1629                                   yaffs_write(h,fn,100);
1630                           yaffs_close(h);
1631                   }
1632                   else
1633                         yaffs_mkdir(fn,0);
1634                 }
1635                 
1636                 for(i = 0; i < 10; i++)
1637                 {
1638                   sprintf(fn,"%s/%d",p,i);  
1639                   if(i & 1) 
1640                         yaffs_unlink(fn);
1641                   else
1642                         yaffs_rmdir(fn);
1643                   
1644                 }
1645                                 
1646                 yaffs_unmount(mountpt);
1647         }
1648         
1649         
1650         
1651
1652 }
1653
1654
1655 void write_10k(int h)
1656 {
1657    int i;
1658    const char *s="0123456789";
1659    for(i = 0; i < 1000; i++)
1660      yaffs_write(h,s,10);
1661
1662 }
1663 void write_200k_file(const char *fn, const char *fdel, const char *fdel1)
1664 {
1665    int h1;
1666    int i;
1667    int offs;
1668    
1669    h1 = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1670    
1671    for(i = 0; i < 100000; i+= 10000)
1672    {
1673         write_10k(h1);
1674    }
1675    
1676    offs = yaffs_lseek(h1,0,SEEK_CUR);
1677    if( offs != 100000)
1678    {
1679         printf("Could not write file\n");
1680    }
1681    
1682    yaffs_unlink(fdel);
1683    for(i = 0; i < 100000; i+= 10000)
1684    {
1685         write_10k(h1);
1686    }
1687    
1688    offs = yaffs_lseek(h1,0,SEEK_CUR);
1689    if( offs != 200000)
1690    {
1691         printf("Could not write file\n");
1692    }
1693    
1694    yaffs_close(h1);
1695    yaffs_unlink(fdel1);
1696    
1697 }
1698
1699
1700 void verify_200k_file(const char *fn)
1701 {
1702    int h1;
1703    int i;
1704    char x[11];
1705    const char *s="0123456789";
1706    int errCount = 0;
1707    
1708    h1 = yaffs_open(fn, O_RDONLY, 0);
1709    
1710    for(i = 0; i < 200000 && errCount < 10; i+= 10)
1711    {
1712         yaffs_read(h1,x,10);
1713         if(strncmp(x,s,10) != 0)
1714         {
1715                 printf("File %s verification failed at %d\n",fn,i);
1716                 errCount++;
1717         }
1718    }
1719    if(errCount >= 10)
1720         printf("Too many errors... aborted\n");
1721       
1722    yaffs_close(h1);        
1723         
1724 }
1725
1726
1727 void check_resize_gc_bug(const char *mountpt)
1728 {
1729
1730         char a[30];
1731         char b[30];
1732         char c[30];
1733         
1734         int i;
1735         
1736         sprintf(a,"%s/a",mountpt);
1737         sprintf(b,"%s/b",mountpt);
1738         sprintf(c,"%s/c",mountpt);
1739         
1740
1741         
1742         
1743         yaffs_StartUp();
1744         yaffs_mount(mountpt);
1745         yaffs_unlink(a);
1746         yaffs_unlink(b);
1747         
1748         for(i = 0; i < 50; i++)
1749         {  
1750            printf("A\n");write_200k_file(a,"",c);
1751            printf("B\n");verify_200k_file(a);
1752            printf("C\n");write_200k_file(b,a,c);
1753            printf("D\n");verify_200k_file(b);
1754            yaffs_unmount(mountpt);
1755            yaffs_mount(mountpt);
1756            printf("E\n");verify_200k_file(a);
1757            printf("F\n");verify_200k_file(b);
1758         }
1759                 
1760 }
1761
1762
1763 void multi_mount_test(const char *mountpt,int nmounts)
1764 {
1765
1766         char a[30];
1767         
1768         int i;
1769         int j;
1770         
1771         sprintf(a,"%s/a",mountpt);
1772
1773         yaffs_StartUp();
1774         
1775         for(i = 0; i < nmounts; i++){
1776                 int h0;
1777                 int h1;
1778                 int len0;
1779                 int len1;
1780                 
1781                 static char xx[1000];
1782                 
1783                 printf("############### Iteration %d   Start\n",i);
1784                 if(1 || i == 0 || i == 5) 
1785                         yaffs_mount(mountpt);
1786
1787                 dump_directory_tree(mountpt);
1788                 
1789                 
1790                 yaffs_mkdir(a,0);
1791                 
1792                 sprintf(xx,"%s/0",a);
1793                 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1794                 
1795                 sprintf(xx,"%s/1",a);
1796                 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1797
1798 #if 0           
1799                 for(j = 0; j < 200; j++){
1800                    yaffs_write(h0,xx,1000);
1801                    yaffs_write(h1,xx,1000);
1802                 }
1803 #else
1804                 while(yaffs_write(h0,xx,1000) > 0){
1805                    
1806                    yaffs_write(h1,xx,1000);
1807                 }
1808 #endif
1809                 len0 = yaffs_lseek(h0,0,SEEK_END);
1810                 len1 = yaffs_lseek(h1,0,SEEK_END);
1811                 
1812                 yaffs_lseek(h0,0,SEEK_SET);
1813                 yaffs_lseek(h1,0,SEEK_SET);
1814
1815                 for(j = 0; j < 200; j++){
1816                    yaffs_read(h0,xx,1000);
1817                    yaffs_read(h1,xx,1000);
1818                 }
1819                 
1820                 
1821         //      yaffs_truncate(h0,0);
1822                 yaffs_close(h0);
1823                 yaffs_close(h1);
1824                 
1825                 printf("########### %d\n",i);
1826                 dump_directory_tree(mountpt);
1827
1828                 if(1 || i == 4 || i == nmounts -1)
1829                         yaffs_unmount(mountpt);
1830         }
1831 }
1832
1833
1834 void small_mount_test(const char *mountpt,int nmounts)
1835 {
1836
1837         char a[30];
1838         
1839         int i;
1840         int j;
1841
1842         int h0;
1843         int h1;
1844         int len0;
1845         int len1;
1846         int nread;
1847         
1848         sprintf(a,"%s/a",mountpt);
1849
1850         yaffs_StartUp();
1851         
1852         
1853         
1854         for(i = 0; i < nmounts; i++){
1855                 
1856                 static char xx[1000];
1857                 
1858                 printf("############### Iteration %d   Start\n",i);
1859                 if(1 || i == 0 || i == 5) 
1860                         yaffs_mount(mountpt);
1861
1862                 dump_directory_tree(mountpt);
1863                 
1864                 yaffs_mkdir(a,0);
1865                 
1866                 sprintf(xx,"%s/0",a);
1867                 if(i ==0){
1868                 
1869                         h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1870                         for(j = 0; j < 130; j++)
1871                                 yaffs_write(h0,xx,1000);
1872                         yaffs_close(h0);
1873                 }
1874                 
1875                 h0 = yaffs_open(xx,O_RDONLY,0);
1876                 
1877                 sprintf(xx,"%s/1",a);
1878                 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1879                 
1880                 while((nread = yaffs_read(h0,xx,1000)) > 0)
1881                         yaffs_write(h1,xx,nread);
1882                 
1883                 
1884                 len0 = yaffs_lseek(h0,0,SEEK_END);
1885                 len1 = yaffs_lseek(h1,0,SEEK_END);
1886                 
1887                 yaffs_lseek(h0,0,SEEK_SET);
1888                 yaffs_lseek(h1,0,SEEK_SET);
1889
1890                 for(j = 0; j < 200; j++){
1891                    yaffs_read(h0,xx,1000);
1892                    yaffs_read(h1,xx,1000);
1893                 }
1894                 
1895                 yaffs_close(h0);
1896                 yaffs_close(h1);
1897                 
1898                 printf("########### %d\n",i);
1899                 dump_directory_tree(mountpt);
1900
1901                 if(1 || i == 4 || i == nmounts -1)
1902                         yaffs_unmount(mountpt);
1903         }
1904 }
1905
1906
1907 int early_exit;
1908
1909 void small_overwrite_test(const char *mountpt,int nmounts)
1910 {
1911
1912         char a[30];
1913         int i;
1914         int j;
1915
1916         int h0;
1917         int h1;
1918
1919         
1920         sprintf(a,"%s/a",mountpt);
1921
1922         yaffs_StartUp();
1923         
1924         
1925         
1926         for(i = 0; i < nmounts; i++){
1927                 
1928                 static char xx[8000];
1929                 
1930                 printf("############### Iteration %d   Start\n",i);
1931                 if(1)
1932                         yaffs_mount(mountpt);
1933
1934                 dump_directory_tree(mountpt);
1935                 
1936                 yaffs_mkdir(a,0);
1937                 
1938                 sprintf(xx,"%s/0",a);
1939                 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1940                 sprintf(xx,"%s/1",a);
1941                 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1942                 
1943                 for(j = 0; j < 1000000; j+=1000){
1944                         yaffs_ftruncate(h0,j);
1945                         yaffs_lseek(h0,j,SEEK_SET);
1946                         yaffs_write(h0,xx,7000);
1947                         yaffs_write(h1,xx,7000);
1948                         
1949                         if(early_exit)
1950                                 exit(0);
1951                 }
1952                 
1953                 yaffs_close(h0);
1954                 
1955                 printf("########### %d\n",i);
1956                 dump_directory_tree(mountpt);
1957
1958                 if(1)
1959                         yaffs_unmount(mountpt);
1960         }
1961 }
1962
1963
1964 void seek_overwrite_test(const char *mountpt,int nmounts)
1965 {
1966
1967         char a[30];
1968         
1969         int i;
1970         int j;
1971
1972         int h0;
1973
1974         
1975         sprintf(a,"%s/f",mountpt);
1976
1977         yaffs_StartUp();
1978         
1979         yaffs_mount(mountpt);
1980         
1981         
1982         for(i = 0; i < nmounts; i++){
1983                 
1984                 h0 = yaffs_open(a, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1985                         
1986                 for(j = 0; j < 100000; j++){
1987                         yaffs_lseek(h0,0,SEEK_SET);
1988                         yaffs_write(h0,xx,5000);
1989                         yaffs_lseek(h0,0x100000,SEEK_SET);
1990                         yaffs_write(h0,xx,5000);
1991                         
1992                         if(early_exit)
1993                                 exit(0);
1994                 }
1995                 
1996                 yaffs_close(h0);
1997                 
1998         }
1999 }
2000
2001
2002 void yaffs_touch(const char *fn)
2003 {
2004         yaffs_chmod(fn, S_IREAD | S_IWRITE);
2005 }
2006
2007 void checkpoint_fill_test(const char *mountpt,int nmounts)
2008 {
2009
2010         char a[50];
2011         char b[50];
2012         char c[50];
2013         
2014         int i;
2015         int j;
2016         int h;
2017         
2018         sprintf(a,"%s/a",mountpt);
2019         
2020
2021         
2022         
2023         yaffs_StartUp();
2024         
2025         for(i = 0; i < nmounts; i++){
2026                 printf("############### Iteration %d   Start\n",i);
2027                 yaffs_mount(mountpt);
2028                 dump_directory_tree(mountpt);
2029                 yaffs_mkdir(a,0);
2030                 
2031                 sprintf(b,"%s/zz",a);
2032                 
2033                 h = yaffs_open(b,O_CREAT | O_RDWR,S_IREAD |S_IWRITE);
2034                 
2035                 
2036                 while(yaffs_write(h,c,50) == 50){}
2037                 
2038                 yaffs_close(h);
2039                 
2040                 for(j = 0; j < 2; j++){
2041                         printf("touch %d\n",j);
2042                         yaffs_touch(b);
2043                         yaffs_unmount(mountpt);
2044                         yaffs_mount(mountpt);
2045                 }
2046
2047                 dump_directory_tree(mountpt);           
2048                 yaffs_unmount(mountpt);
2049         }
2050 }
2051
2052
2053 int make_file2(const char *name1, const char *name2,int syz)
2054 {
2055
2056         char xx[2500];
2057         int i;
2058         int h1=-1,h2=-1;
2059         int n = 1;
2060
2061
2062         if(name1)
2063                 h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2064         if(name2)
2065                 h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2066         
2067         while(syz > 0 && n > 0){
2068                 i = (syz > 2500) ? 2500 : syz;
2069                 n = yaffs_write(h1,xx,i);
2070                 n = yaffs_write(h2,xx,i);
2071                 syz -= 500;
2072         }
2073         yaffs_close(h1);
2074         yaffs_close(h2);
2075         return 0;
2076 }
2077
2078
2079 extern void SetCheckpointReservedBlocks(int n);
2080
2081 void checkpoint_upgrade_test(const char *mountpt,int nmounts)
2082 {
2083
2084         char a[50];
2085         char b[50];
2086         char c[50];
2087         char d[50];
2088
2089         int j;
2090         
2091         sprintf(a,"%s/a",mountpt);
2092         
2093
2094         
2095         
2096         printf("Create start condition\n");
2097         yaffs_StartUp();
2098         SetCheckpointReservedBlocks(0);
2099         yaffs_mount(mountpt);
2100         yaffs_mkdir(a,0);
2101         sprintf(b,"%s/zz",a);
2102         sprintf(c,"%s/xx",a);
2103         make_file2(b,c,2000000);
2104         sprintf(d,"%s/aa",a);
2105         make_file2(d,NULL,500000000);
2106         dump_directory_tree(mountpt);
2107         
2108         printf("Umount/mount attempt full\n");
2109         yaffs_unmount(mountpt);
2110         
2111         SetCheckpointReservedBlocks(10);
2112         yaffs_mount(mountpt);
2113         
2114         printf("unlink small file\n");
2115         yaffs_unlink(c);
2116         dump_directory_tree(mountpt);
2117                 
2118         printf("Umount/mount attempt\n");
2119         yaffs_unmount(mountpt);
2120         yaffs_mount(mountpt);
2121         
2122         for(j = 0; j < 500; j++){
2123                 printf("***** touch %d\n",j);
2124                 dump_directory_tree(mountpt);
2125                 yaffs_touch(b);
2126                 yaffs_unmount(mountpt);
2127                 yaffs_mount(mountpt);
2128         }
2129
2130         for(j = 0; j < 500; j++){
2131                 printf("***** touch %d\n",j);
2132                 dump_directory_tree(mountpt);
2133                 yaffs_touch(b);
2134                 yaffs_unmount(mountpt);
2135                 yaffs_mount(mountpt);
2136         }
2137 }
2138         
2139 void huge_array_test(const char *mountpt,int n)
2140 {
2141
2142         char a[50];
2143
2144         
2145         int i;
2146         int space;
2147         
2148         int fnum;
2149         
2150         sprintf(a,"mount point %s",mountpt);
2151         
2152
2153         
2154         yaffs_StartUp();
2155
2156         yaffs_mount(mountpt);
2157         
2158         while(n>0){
2159                 n--;
2160                 fnum = 0;
2161                 printf("\n\n START run\n\n");
2162                 while((space = yaffs_freespace(mountpt)) > 25000000){
2163                         sprintf(a,"%s/file%d",mountpt,fnum);
2164                         fnum++;
2165                         printf("create file %s, free space %d\n",a,space);
2166                         create_file_of_size(a,10000000);
2167                         printf("verifying file %s\n",a);
2168                         verify_file_of_size(a,10000000);
2169                 }
2170                 
2171                 printf("\n\n verification/deletion\n\n");
2172                 
2173                 for(i = 0; i < fnum; i++){
2174                         sprintf(a,"%s/file%d",mountpt,i);
2175                         printf("verifying file %s\n",a);
2176                         verify_file_of_size(a,10000000);
2177                         printf("deleting file %s\n",a);
2178                         yaffs_unlink(a);
2179                 }
2180                 printf("\n\n done \n\n");
2181                         
2182                    
2183         }
2184 }
2185
2186
2187 void random_write(int h)
2188 {
2189         static char buffer[12000];
2190         int n;
2191         
2192         n = random() & 0x1FFF;
2193         yaffs_write(h,buffer,n);
2194 }
2195
2196 void random_seek(int h)
2197 {
2198         int n;
2199         n = random() & 0xFFFFF;
2200         yaffs_lseek(h,n,SEEK_SET);
2201 }
2202
2203 void random_truncate(int h, char * name)
2204 {
2205         int n;
2206         int flen;
2207         n = random() & 0xFFFFF;
2208         flen = yaffs_lseek(h,0,SEEK_END);
2209         if(n > flen)
2210                 n = flen / 2;
2211         yaffs_ftruncate(h,n);
2212         yaffs_lseek(h,n,SEEK_SET);
2213 }
2214
2215
2216 #define NSMALLFILES 10  
2217 void random_small_file_test(const char *mountpt,int iterations)
2218 {
2219
2220         char a[NSMALLFILES][50];
2221
2222         
2223         int i;
2224         int n;
2225         int h[NSMALLFILES];
2226         int r;
2227         
2228         
2229         yaffs_StartUp();
2230
2231         yaffs_mount(mountpt);
2232         
2233         for(i = 0; i < NSMALLFILES; i++){
2234                 h[i]=-1;
2235                 strcpy(a[i],"");
2236         }
2237         
2238         for(n = 0; n < iterations; n++){
2239                                 
2240                 for(i = 0; i < NSMALLFILES; i++) {
2241                         r = random();
2242                         
2243                         if(strlen(a[i]) == 0){
2244                                 sprintf(a[i],"%s/%dx%d",mountpt,n,i);
2245                                 h[i] = yaffs_open(a[i],O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2246                         }
2247                         
2248                         if(h[i] < -1)
2249                                 printf("Could not open yaffs file %d %d error %d\n",n,i,h[i]);
2250                         else {
2251                                 r = r & 7;
2252                                 switch(r){
2253                                         case 0:
2254                                         case 1:
2255                                         case 2:
2256                                                 random_write(h[i]);
2257                                                 break;
2258                                         case 3:
2259                                                 random_truncate(h[i],a[i]);
2260                                                 break;
2261                                         case 4:
2262                                         case 5: random_seek(h[i]);
2263                                                 break;
2264                                         case 6:
2265                                                 yaffs_close(h[i]);
2266                                                 h[i] = -1;
2267                                                 break;
2268                                         case 7:
2269                                                 yaffs_close(h[i]);
2270                                                 yaffs_unlink(a[i]);
2271                                                 strcpy(a[i],"");
2272                                                 h[i] = -1;
2273                                 }
2274                         }
2275                 }
2276                    
2277         }
2278         
2279         for(i = 0; i < NSMALLFILES; i++)
2280                 yaffs_close(h[i]);
2281                 
2282         yaffs_unmount(mountpt);
2283 }
2284         
2285
2286
2287 int main(int argc, char *argv[])
2288 {
2289
2290         //return long_test(argc,argv);
2291         
2292         //return cache_read_test();
2293         
2294         // resize_stress_test_no_grow("/flash/flash",20);
2295         //root_perm_remount("/flash/flash");
2296         
2297         //huge_directory_test_on_path("/ram2k");
2298         
2299          //yaffs_backward_scan_test("/flash/flash");
2300         // yaffs_device_flush_test("/flash/flash");
2301
2302         rename_over_test("//////////////////flash///////////////////yaffs1///////////");
2303         
2304          //scan_pattern_test("/flash",10000,10);
2305         //short_scan_test("/flash/flash",40000,200);
2306           //small_mount_test("/flash/flash",1000);
2307           //small_overwrite_test("/flash/flash",1000);
2308           //seek_overwrite_test("/flash/flash",1000);
2309          //checkpoint_fill_test("/flash/flash",20);
2310          //checkpoint_upgrade_test("/flash/flash",20);
2311           //small_overwrite_test("/flash/flash",1000);
2312           //checkpoint_fill_test("/flash/flash",20);
2313         // random_small_file_test("/flash/flash",10000);
2314          // huge_array_test("/flash/flash",10);
2315
2316
2317
2318         
2319         //long_test_on_path("/ram2k");
2320         // long_test_on_path("/flash");
2321         //simple_rw_test("/flash/flash");
2322         //fill_disk_test("/flash/flash");
2323         // rename_over_test("/flash");
2324         //lookup_test("/flash");
2325         //freespace_test("/flash/flash");
2326         
2327         //link_test("/flash/flash");
2328         
2329         
2330         
2331         
2332         // cache_bypass_bug_test();
2333         
2334          //free_space_check();
2335          
2336          //check_resize_gc_bug("/flash");
2337          
2338          return 0;
2339         
2340 }