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