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