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