2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
4 * Copyright (C) 2002 Aleph One Ltd.
5 * for Toby Churchill Ltd and Brightstar Engineering
7 * Created by Charles Manning <charles@aleph1.co.uk>
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.
25 #include "nor_stress.h"
27 void dumpDir(const char *dname);
31 void copy_in_a_file(char *yaffsName,char *inName)
34 unsigned char buffer[100];
36 inh = open(inName,O_RDONLY);
37 outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
39 while((ni = read(inh,buffer,100)) > 0)
41 no = yaffs_write(outh,buffer,ni);
44 printf("problem writing yaffs file\n");
53 void make_a_file(char *yaffsName,char bval,int sizeOfFile)
57 unsigned char buffer[100];
59 outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
61 memset(buffer,bval,100);
68 yaffs_write(outh,buffer,i);
70 } while (sizeOfFile > 0);
77 void make_pattern_file(char *fn,int size)
82 outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
83 yaffs_lseek(outh,size-1,SEEK_SET);
84 yaffs_write(outh,"A",1);
86 for(i = 0; i < size; i+=256)
89 yaffs_lseek(outh,i,SEEK_SET);
90 yaffs_write(outh,&marker,sizeof(marker));
96 int check_pattern_file(char *fn)
104 h = yaffs_open(fn, O_RDWR,0);
105 size = yaffs_lseek(h,0,SEEK_END);
107 for(i = 0; i < size; i+=256)
109 yaffs_lseek(h,i,SEEK_SET);
110 yaffs_read(h,&marker,sizeof(marker));
114 printf("pattern check failed on file %s, size %d at position %d. Got %x instead of %x\n",
115 fn,size,i,marker,~i);
126 int dump_file_data(char *fn)
133 h = yaffs_open(fn, O_RDWR,0);
137 while(yaffs_read(h,&b,1)> 0)
154 void dump_file(const char *fn)
160 h = yaffs_open(fn,O_RDONLY,0);
163 printf("*****\nDump file %s does not exist\n",fn);
167 size = yaffs_lseek(h,0,SEEK_SET);
168 printf("*****\nDump file %s size %d\n",fn,size);
169 for(i = 0; i < size; i++)
176 void create_file_of_size(const char *fn,int syze)
184 int iterations = (syze + strlen(fn) -1)/ strlen(fn);
186 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
188 while (iterations > 0)
190 sprintf(xx,"%s %8d",fn,iterations);
192 result = yaffs_write(h,xx,n);
194 printf("Wrote %d, should have been %d\n",result,n);
200 void verify_file_of_size(const char *fn,int syze)
209 int iterations = (syze + strlen(fn) -1)/ strlen(fn);
211 h = yaffs_open(fn, O_RDONLY, S_IREAD | S_IWRITE);
213 while (iterations > 0)
215 sprintf(xx,"%s %8d",fn,iterations);
218 result = yaffs_read(h,yy,l);
222 printf("=====>>>>> verification of file %s failed near position %lld\n",fn,(long long)yaffs_lseek(h,0,SEEK_CUR));
229 void create_resized_file_of_size(const char *fn,int syze1,int reSyze, int syze2)
235 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
237 iterations = (syze1 + strlen(fn) -1)/ strlen(fn);
238 while (iterations > 0)
240 yaffs_write(h,fn,strlen(fn));
244 yaffs_ftruncate(h,reSyze);
246 yaffs_lseek(h,0,SEEK_SET);
247 iterations = (syze2 + strlen(fn) -1)/ strlen(fn);
248 while (iterations > 0)
250 yaffs_write(h,fn,strlen(fn));
258 void do_some_file_stuff(const char *path)
263 sprintf(fn,"%s/%s",path,"f1");
264 create_file_of_size(fn,10000);
266 sprintf(fn,"%s/%s",path,"fdel");
267 create_file_of_size(fn,10000);
270 sprintf(fn,"%s/%s",path,"f2");
272 create_resized_file_of_size(fn,10000,3000,4000);
275 void yaffs_backward_scan_test(const char *path)
283 do_some_file_stuff(path);
285 sprintf(fn,"%s/ddd",path);
289 do_some_file_stuff(fn);
299 void yaffs_device_flush_test(const char *path)
309 do_some_file_stuff(path);
311 // Open and add some data to a few files
312 for(i = 0; i < 10; i++) {
314 sprintf(fn,"%s/ff%d",path,i);
316 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IWRITE | S_IREAD);
317 yaffs_write(h,xxzz,2000);
318 yaffs_write(h,xxzz,2000);
327 void short_scan_test(const char *path, int fsize, int niterations)
332 sprintf(fn,"%s/%s",path,"f1");
335 for(i = 0; i < niterations; i++)
337 printf("\n*****************\nIteration %d\n",i);
339 printf("\nmount: Directory look-up of %s\n",path);
341 make_a_file(fn,1,fsize);
348 void scan_pattern_test(const char *path, int fsize, int niterations)
355 sprintf(fn[0],"%s/%s",path,"f0");
356 sprintf(fn[1],"%s/%s",path,"f1");
357 sprintf(fn[2],"%s/%s",path,"f2");
361 for(i = 0; i < niterations; i++)
363 printf("\n*****************\nIteration %d\n",i);
365 printf("\nmount: Directory look-up of %s\n",path);
367 for(j = 0; j < 3; j++)
369 result = dump_file_data(fn[j]);
370 result = check_pattern_file(fn[j]);
371 make_pattern_file(fn[j],fsize);
372 result = dump_file_data(fn[j]);
373 result = check_pattern_file(fn[j]);
379 void fill_disk(const char *path,int nfiles)
388 for(n = 0; n < nfiles; n++)
390 sprintf(str,"%s/%d",path,n);
392 h = yaffs_open(str, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
394 printf("writing file %s handle %d ",str, h);
396 while ((result = yaffs_write(h,xx,600)) == 600)
398 f = yaffs_freespace(path);
400 result = yaffs_close(h);
401 printf(" close %d\n",result);
405 void fill_disk_and_delete(const char *path, int nfiles, int ncycles)
411 for(i = 0; i < ncycles; i++)
413 printf("@@@@@@@@@@@@@@ cycle %d\n",i);
414 fill_disk(path,nfiles);
416 for(j = 0; j < nfiles; j++)
418 sprintf(str,"%s/%d",path,j);
419 result = yaffs_unlink(str);
420 printf("unlinking file %s, result %d\n",str,result);
426 void fill_files(char *path,int flags, int maxIterations,int siz)
436 sprintf(str,"%s/%d",path,i);
437 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
442 for(j = 0; j < siz; j++)
444 yaffs_write(h,str,1);
453 } while(h >= 0 && i < maxIterations);
459 sprintf(str,"%s/%d",path,i);
460 printf("unlink %s\n",str);
462 } while(yaffs_unlink(str) >= 0);
466 void leave_unlinked_file(char *path,int maxIterations,int siz)
475 sprintf(str,"%s/%d",path,i);
476 printf("create %s\n",str);
477 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
483 } while(h < 0 && i < maxIterations);
487 for(i = 0; i < siz; i++)
489 yaffs_write(h,str,1);
493 printf("Leaving file %s open\n",str);
497 void dumpDirFollow(const char *dname)
504 d = yaffs_opendir(dname);
508 printf("opendir failed\n");
512 while((de = yaffs_readdir(d)) != NULL)
514 sprintf(str,"%s/%s",dname,de->d_name);
518 printf("%s ino %d length %d mode %X ",de->d_name,(int)s.st_ino,(int)s.st_size,s.st_mode);
519 switch(s.st_mode & S_IFMT)
521 case S_IFREG: printf("data file"); break;
522 case S_IFDIR: printf("directory"); break;
523 case S_IFLNK: printf("symlink -->");
524 if(yaffs_readlink(str,str,100) < 0)
527 printf("\"%s\"",str);
529 default: printf("unknown"); break;
539 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
544 void dump_directory_tree_worker(const char *dname,int recursive)
551 d = yaffs_opendir(dname);
555 printf("opendir failed\n");
559 while((de = yaffs_readdir(d)) != NULL)
561 sprintf(str,"%s/%s",dname,de->d_name);
565 printf("%s inode %d obj %x length %d mode %X ",str,s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);
566 switch(s.st_mode & S_IFMT)
568 case S_IFREG: printf("data file"); break;
569 case S_IFDIR: printf("directory"); break;
570 case S_IFLNK: printf("symlink -->");
571 if(yaffs_readlink(str,str,100) < 0)
574 printf("\"%s\"",str);
576 default: printf("unknown"); break;
581 if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
582 dump_directory_tree_worker(str,1);
591 static void dump_directory_tree(const char *dname)
593 dump_directory_tree_worker(dname,1);
595 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
598 void dumpDir(const char *dname)
599 { dump_directory_tree_worker(dname,0);
601 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
605 static void PermissionsCheck(const char *path, mode_t tmode, int tflags,int expectedResult)
609 if(yaffs_chmod(path,tmode)< 0) printf("chmod failed\n");
611 fd = yaffs_open(path,tflags,0);
613 if((fd >= 0) != (expectedResult > 0))
615 printf("Permissions check %x %x %d failed\n",tmode,tflags,expectedResult);
619 printf("Permissions check %x %x %d OK\n",tmode,tflags,expectedResult);
628 int long_test(int argc, char *argv[])
639 struct yaffs_stat ystat;
643 yaffs_mount("/boot");
644 yaffs_mount("/data");
645 yaffs_mount("/flash");
648 printf("\nDirectory look-up of /boot\n");
650 printf("\nDirectory look-up of /data\n");
652 printf("\nDirectory look-up of /flash\n");
655 //leave_unlinked_file("/flash",20000,0);
656 //leave_unlinked_file("/data",20000,0);
658 leave_unlinked_file("/ram",20,0);
661 f = yaffs_open("/boot/b1", O_RDONLY,0);
663 printf("open /boot/b1 readonly, f=%d\n",f);
665 f = yaffs_open("/boot/b1", O_CREAT,S_IREAD | S_IWRITE);
667 printf("open /boot/b1 O_CREAT, f=%d\n",f);
670 r = yaffs_write(f,"hello",1);
671 printf("write %d attempted to write to a read-only file\n",r);
675 printf("close %d\n",r);
677 f = yaffs_open("/boot/b1", O_RDWR,0);
679 printf("open /boot/b1 O_RDWR,f=%d\n",f);
682 r = yaffs_write(f,"hello",2);
683 printf("write %d attempted to write to a writeable file\n",r);
684 r = yaffs_write(f,"world",3);
685 printf("write %d attempted to write to a writeable file\n",r);
687 r= yaffs_lseek(f,0,SEEK_END);
688 printf("seek end %d\n",r);
690 r = yaffs_read(f,buffer,10);
691 printf("read %d \"%s\"\n",r,buffer);
692 r= yaffs_lseek(f,0,SEEK_SET);
693 printf("seek set %d\n",r);
695 r = yaffs_read(f,buffer,10);
696 printf("read %d \"%s\"\n",r,buffer);
698 r = yaffs_read(f,buffer,10);
699 printf("read %d \"%s\"\n",r,buffer);
701 // Check values reading at end.
702 // A read past end of file should return 0 for 0 bytes read.
704 r= yaffs_lseek(f,0,SEEK_END);
705 r = yaffs_read(f,buffer,10);
706 printf("read at end returned %d\n",r);
707 r= yaffs_lseek(f,500,SEEK_END);
708 r = yaffs_read(f,buffer,10);
709 printf("read past end returned %d\n",r);
713 printf("close %d\n",r);
715 copy_in_a_file("/boot/yyfile","xxx");
717 // Create a file with a long name
719 copy_in_a_file("/boot/file with a long name","xxx");
722 printf("\nDirectory look-up of /boot\n");
726 r = yaffs_stat("/boot/file with a long name",&ystat);
730 r = yaffs_rename("/boot/file with a long name","/boot/r1");
732 printf("\nDirectory look-up of /boot\n");
736 r = yaffs_unlink("/boot/r1");
738 printf("\nDirectory look-up of /boot\n");
743 r = yaffs_mkdir("/boot/directory1",0);
745 printf("\nDirectory look-up of /boot\n");
747 printf("\nDirectory look-up of /boot/directory1\n");
748 dumpDir("/boot/directory1");
750 // add a file to the directory
751 copy_in_a_file("/boot/directory1/file with a long name","xxx");
753 printf("\nDirectory look-up of /boot\n");
755 printf("\nDirectory look-up of /boot/directory1\n");
756 dumpDir("/boot/directory1");
758 // Attempt to delete directory (should fail)
760 r = yaffs_rmdir("/boot/directory1");
762 printf("\nDirectory look-up of /boot\n");
764 printf("\nDirectory look-up of /boot/directory1\n");
765 dumpDir("/boot/directory1");
767 // Delete file first, then rmdir should work
768 r = yaffs_unlink("/boot/directory1/file with a long name");
769 r = yaffs_rmdir("/boot/directory1");
772 printf("\nDirectory look-up of /boot\n");
774 printf("\nDirectory look-up of /boot/directory1\n");
775 dumpDir("/boot/directory1");
778 fill_disk_and_delete("/boot",20,20);
780 printf("\nDirectory look-up of /boot\n");
784 yaffs_symlink("yyfile","/boot/slink");
786 yaffs_readlink("/boot/slink",str,100);
787 printf("symlink alias is %s\n",str);
792 printf("\nDirectory look-up of /boot\n");
794 printf("\nDirectory look-up of /boot (using stat instead of lstat)\n");
795 dumpDirFollow("/boot");
796 printf("\nDirectory look-up of /boot/directory1\n");
797 dumpDir("/boot/directory1");
799 h = yaffs_open("/boot/slink",O_RDWR,0);
801 printf("file length is %d\n",(int)yaffs_lseek(h,0,SEEK_END));
805 yaffs_unlink("/boot/slink");
808 printf("\nDirectory look-up of /boot\n");
813 yaffs_stat("/boot/yyfile",&ystat);
814 temp_mode = ystat.st_mode;
816 yaffs_chmod("/boot/yyfile",0x55555);
817 printf("\nDirectory look-up of /boot\n");
820 yaffs_chmod("/boot/yyfile",temp_mode);
821 printf("\nDirectory look-up of /boot\n");
824 // Permission checks...
825 PermissionsCheck("/boot/yyfile",0, O_WRONLY,0);
826 PermissionsCheck("/boot/yyfile",0, O_RDONLY,0);
827 PermissionsCheck("/boot/yyfile",0, O_RDWR,0);
829 PermissionsCheck("/boot/yyfile",S_IREAD, O_WRONLY,0);
830 PermissionsCheck("/boot/yyfile",S_IREAD, O_RDONLY,1);
831 PermissionsCheck("/boot/yyfile",S_IREAD, O_RDWR,0);
833 PermissionsCheck("/boot/yyfile",S_IWRITE, O_WRONLY,1);
834 PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDONLY,0);
835 PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDWR,0);
837 PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_WRONLY,1);
838 PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDONLY,1);
839 PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDWR,1);
841 yaffs_chmod("/boot/yyfile",temp_mode);
843 //create a zero-length file and unlink it (test for scan bug)
845 h = yaffs_open("/boot/zlf",O_CREAT | O_TRUNC | O_RDWR,0);
848 yaffs_unlink("/boot/zlf");
851 yaffs_DumpDevStruct("/boot");
853 fill_disk_and_delete("/boot",20,20);
855 yaffs_DumpDevStruct("/boot");
857 fill_files("/boot",1,10000,0);
858 fill_files("/boot",1,10000,5000);
859 fill_files("/boot",2,10000,0);
860 fill_files("/boot",2,10000,5000);
862 leave_unlinked_file("/data",20000,0);
863 leave_unlinked_file("/data",20000,5000);
864 leave_unlinked_file("/data",20000,5000);
865 leave_unlinked_file("/data",20000,5000);
866 leave_unlinked_file("/data",20000,5000);
867 leave_unlinked_file("/data",20000,5000);
869 yaffs_DumpDevStruct("/boot");
870 yaffs_DumpDevStruct("/data");
878 int huge_directory_test_on_path(char *path)
898 // Create a large number of files
900 for(i = 0; i < 2000; i++)
902 sprintf(str,"%s/%d",path,i);
904 f = yaffs_open(str,O_CREAT,S_IREAD | S_IWRITE);
910 d = yaffs_opendir(path);
913 while((de = yaffs_readdir(d)) != NULL) {
914 if (total >lastTotal+100*9*1024||(i & 1023)==0){
915 printf("files = %d, total = %d\n",i, total);
919 sprintf(str,"%s/%s",path,de->d_name);
921 switch(s.st_mode & S_IFMT){
923 //printf("data file");
935 int yaffs_scan_test(const char *path)
941 void rename_over_test(const char *mountpt)
948 sprintf(a,"%s/a",mountpt);
949 sprintf(b,"%s/b",mountpt);
950 sprintf(c,"%s/c",mountpt);
954 yaffs_mount(mountpt);
956 printf("Existing files\n");
957 dumpDirFollow(mountpt);
961 i = yaffs_open(c,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
962 printf("File c handle is %d\n",i);
964 i = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
966 i = yaffs_open(b,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
968 yaffs_rename(a,b); // rename over
969 yaffs_rename(b,a); // rename back again (not renaimng over)
970 yaffs_rename(a,b); // rename back again (not renaimng over)
973 yaffs_unmount(mountpt);
978 int resize_stress_test(const char *path)
993 sprintf(aname,"%s%s",path,"/a");
994 sprintf(bname,"%s%s",path,"/b");
996 memset(abuffer,'a',1000);
997 memset(bbuffer,'b',1000);
999 a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1000 b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1002 printf(" %s %d %s %d\n",aname,a,bname,b);
1006 for(j = 0; j < 100; j++)
1008 yaffs_lseek(a,0,SEEK_END);
1011 for(i = 0; i <20000; i++)
1013 //r = yaffs_lseek(b,i,SEEK_SET);
1014 //r = yaffs_write(b,bbuffer,1000);
1019 int syz = yaffs_lseek(a,0,SEEK_END);
1022 if(syz < 0) syz = 0;
1023 yaffs_ftruncate(a,syz);
1029 r = yaffs_lseek(a,i * 500,SEEK_SET);
1030 r = yaffs_write(a,abuffer,1000);
1041 int root_perm_remount(const char *path)
1043 struct yaffs_stat s;
1049 yaffs_stat(path,&s);
1050 printf("root perms after mount %x\n",s.st_mode);
1052 yaffs_chmod(path, 0777);
1054 yaffs_stat(path,&s);
1055 printf("root perms after setting to 0777 is %x\n",s.st_mode);
1057 yaffs_unmount(path);
1064 int resize_stress_test_no_grow_complex(const char *path,int iters)
1080 sprintf(aname,"%s%s",path,"/a");
1081 sprintf(bname,"%s%s",path,"/b");
1083 memset(abuffer,'a',1000);
1084 memset(bbuffer,'b',1000);
1086 a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1087 b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1089 printf(" %s %d %s %d\n",aname,a,bname,b);
1093 for(j = 0; j < iters; j++)
1095 yaffs_lseek(a,0,SEEK_END);
1098 for(i = 0; i <20000; i++)
1100 //r = yaffs_lseek(b,i,SEEK_SET);
1101 //r = yaffs_write(b,bbuffer,1000);
1106 int syz = yaffs_lseek(a,0,SEEK_END);
1112 if(syz < 0) syz = 0;
1113 yaffs_ftruncate(a,syz);
1114 syz = yaffs_lseek(a,0,SEEK_END);
1115 printf("shrink to %d\n",syz);
1123 r = yaffs_lseek(a,500,SEEK_END);
1124 r = yaffs_write(a,abuffer,1000);
1131 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1139 int resize_stress_test_no_grow(const char *path,int iters)
1154 sprintf(aname,"%s%s",path,"/a");
1155 sprintf(bname,"%s%s",path,"/b");
1157 memset(abuffer,'a',1000);
1158 memset(bbuffer,'b',1000);
1160 a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1161 b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1163 printf(" %s %d %s %d\n",aname,a,bname,b);
1167 for(j = 0; j < iters; j++)
1169 yaffs_lseek(a,0,SEEK_END);
1172 for(i = 0; i <20000; i++)
1174 //r = yaffs_lseek(b,i,SEEK_SET);
1175 //r = yaffs_write(b,bbuffer,1000);
1180 int syz = yaffs_lseek(a,0,SEEK_END);
1186 if(syz < 0) syz = 0;
1187 yaffs_ftruncate(a,syz);
1188 syz = yaffs_lseek(a,0,SEEK_END);
1189 printf("shrink to %d\n",syz);
1197 r = yaffs_lseek(a,-500,SEEK_END);
1198 r = yaffs_write(a,abuffer,1000);
1204 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1212 int directory_rename_test(void)
1217 yaffs_mount("/ram");
1218 yaffs_mkdir("/ram/a",0);
1219 yaffs_mkdir("/ram/a/b",0);
1220 yaffs_mkdir("/ram/c",0);
1222 printf("\nDirectory look-up of /ram\n");
1225 dumpDir("/ram/a/b");
1227 printf("Do rename (should fail)\n");
1229 r = yaffs_rename("/ram/a","/ram/a/b/d");
1230 printf("\nDirectory look-up of /ram\n");
1233 dumpDir("/ram/a/b");
1235 printf("Do rename (should not fail)\n");
1237 r = yaffs_rename("/ram/c","/ram/a/b/d");
1238 printf("\nDirectory look-up of /ram\n");
1241 dumpDir("/ram/a/b");
1248 int cache_read_test(void)
1252 int sizeOfFiles = 500000;
1257 yaffs_mount("/boot");
1259 make_a_file("/boot/a",'a',sizeOfFiles);
1260 make_a_file("/boot/b",'b',sizeOfFiles);
1262 a = yaffs_open("/boot/a",O_RDONLY,0);
1263 b = yaffs_open("/boot/b",O_RDONLY,0);
1264 c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
1268 if (i > 100) i = 100;
1270 yaffs_read(a,buffer,i);
1271 yaffs_read(b,buffer,i);
1272 yaffs_write(c,buffer,i);
1273 } while(sizeOfFiles > 0);
1281 int cache_bypass_bug_test(void)
1283 // This test reporoduces a bug whereby YAFFS caching *was* buypassed
1284 // resulting in erroneous reads after writes.
1285 // This bug has been fixed.
1291 memset(buffer1,0,sizeof(buffer1));
1292 memset(buffer2,0,sizeof(buffer2));
1296 yaffs_mount("/boot");
1298 // Create a file of 2000 bytes.
1299 make_a_file("/boot/a",'X',2000);
1301 a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE);
1303 // Write a short sequence to the file.
1304 // This will go into the cache.
1305 yaffs_lseek(a,0,SEEK_SET);
1306 yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20);
1308 // Read a short sequence from the file.
1309 // This will come from the cache.
1310 yaffs_lseek(a,0,SEEK_SET);
1311 yaffs_read(a,buffer1,30);
1313 // Read a page size sequence from the file.
1314 yaffs_lseek(a,0,SEEK_SET);
1315 yaffs_read(a,buffer2,512);
1317 printf("buffer 1 %s\n",buffer1);
1318 printf("buffer 2 %s\n",buffer2);
1320 if(strncmp(buffer1,buffer2,20))
1322 printf("Cache bypass bug detected!!!!!\n");
1330 int free_space_check(void)
1335 yaffs_mount("/boot");
1336 fill_disk("/boot/",2);
1337 f = yaffs_freespace("/boot");
1339 printf("%d free when disk full\n",f);
1343 int truncate_test(void)
1353 yaffs_mount("/boot");
1355 yaffs_unlink("/boot/trunctest");
1357 a = yaffs_open("/boot/trunctest", O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1359 yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26);
1361 yaffs_ftruncate(a,3);
1362 l= yaffs_lseek(a,0,SEEK_END);
1364 printf("truncated length is %d\n",l);
1366 yaffs_lseek(a,5,SEEK_SET);
1367 yaffs_write(a,"1",1);
1369 yaffs_lseek(a,0,SEEK_SET);
1371 r = yaffs_read(a,y,10);
1373 printf("read %d bytes:",r);
1375 for(i = 0; i < r; i++) printf("[%02X]",y[i]);
1387 void fill_disk_test(const char *mountpt)
1392 for(i = 0; i < 5; i++)
1394 yaffs_mount(mountpt);
1395 fill_disk_and_delete(mountpt,100,i+1);
1396 yaffs_unmount(mountpt);
1403 void lookup_test(const char *mountpt)
1415 yaffs_mount(mountpt);
1417 d = yaffs_opendir(mountpt);
1421 printf("opendir failed\n");
1426 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1428 printf("unlinking %s\n",de->d_name);
1429 yaffs_unlink(de->d_name);
1432 printf("%d files deleted\n",i);
1436 for(i = 0; i < 2000; i++){
1437 sprintf(a,"%s/%d",mountpt,i);
1438 h = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0);
1443 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1445 printf("%d %s\n",i,de->d_name);
1448 printf("%d files listed\n\n\n",i);
1455 for(i = 0; i < 2000; i++){
1456 sprintf(a,"%s/%d",mountpt,i);
1461 yaffs_unmount(mountpt);
1465 void link_test(const char *mountpt)
1473 sprintf(a,"%s/aaa",mountpt);
1474 sprintf(b,"%s/bbb",mountpt);
1475 sprintf(c,"%s/ccc",mountpt);
1479 yaffs_mount(mountpt);
1482 h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1483 for(i = 0; i < 100; i++)
1484 yaffs_write(h,a,100);
1497 yaffs_unmount(mountpt);
1498 yaffs_mount(mountpt);
1500 printf("link test done\n");
1504 void freespace_test(const char *mountpt)
1514 sprintf(a,"%s/aaa",mountpt);
1518 yaffs_mount(mountpt);
1520 f0 = yaffs_freespace(mountpt);
1522 h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1524 for(i = 0; i < 100; i++)
1525 yaffs_write(h,a,100);
1529 f1 = yaffs_freespace(mountpt);
1533 f2 = yaffs_freespace(mountpt);
1536 yaffs_unmount(mountpt);
1537 yaffs_mount(mountpt);
1539 f3 = yaffs_freespace(mountpt);
1541 printf("%d\n%d\n%d\n%d\n",f0, f1,f2,f3);
1546 void simple_rw_test(const char *mountpt)
1555 sprintf(a,"%s/aaa",mountpt);
1559 yaffs_mount(mountpt);
1563 h = yaffs_open(a,O_CREAT| O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1565 for(i = 100000;i < 200000; i++){
1566 result = yaffs_write(h,&i,sizeof(i));
1570 printf("write error\n");
1577 // h = yaffs_open(a,O_RDWR, S_IREAD | S_IWRITE);
1580 yaffs_lseek(h,0,SEEK_SET);
1582 for(i = 100000; i < 200000; i++){
1583 result = yaffs_read(h,&x,sizeof(x));
1585 if(result != 4 || x != i){
1586 printf("read error %d %x %x\n",i,result,x);
1590 printf("Simple rw test passed\n");
1597 void scan_deleted_files_test(const char *mountpt)
1609 sprintf(sub,"%s/sdir",mountpt);
1612 for(j = 0; j < 10; j++)
1614 printf("\n\n>>>>>>> Run %d <<<<<<<<<<<<<\n\n",j);
1615 yaffs_mount(mountpt);
1619 p = (j & 0) ? mountpt: sub;
1621 for(i = 0; i < 100; i++)
1623 sprintf(fn,"%s/%d",p,i);
1627 h = yaffs_open(fn,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1628 for(k = 0; k < 1000; k++)
1629 yaffs_write(h,fn,100);
1636 for(i = 0; i < 10; i++)
1638 sprintf(fn,"%s/%d",p,i);
1646 yaffs_unmount(mountpt);
1655 void write_10k(int h)
1658 const char *s="0123456789";
1659 for(i = 0; i < 1000; i++)
1660 yaffs_write(h,s,10);
1663 void write_200k_file(const char *fn, const char *fdel, const char *fdel1)
1669 h1 = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1671 for(i = 0; i < 100000; i+= 10000)
1676 offs = yaffs_lseek(h1,0,SEEK_CUR);
1679 printf("Could not write file\n");
1683 for(i = 0; i < 100000; i+= 10000)
1688 offs = yaffs_lseek(h1,0,SEEK_CUR);
1691 printf("Could not write file\n");
1695 yaffs_unlink(fdel1);
1700 void verify_200k_file(const char *fn)
1705 const char *s="0123456789";
1708 h1 = yaffs_open(fn, O_RDONLY, 0);
1710 for(i = 0; i < 200000 && errCount < 10; i+= 10)
1712 yaffs_read(h1,x,10);
1713 if(strncmp(x,s,10) != 0)
1715 printf("File %s verification failed at %d\n",fn,i);
1720 printf("Too many errors... aborted\n");
1727 void check_resize_gc_bug(const char *mountpt)
1736 sprintf(a,"%s/a",mountpt);
1737 sprintf(b,"%s/b",mountpt);
1738 sprintf(c,"%s/c",mountpt);
1744 yaffs_mount(mountpt);
1748 for(i = 0; i < 50; i++)
1750 printf("A\n");write_200k_file(a,"",c);
1751 printf("B\n");verify_200k_file(a);
1752 printf("C\n");write_200k_file(b,a,c);
1753 printf("D\n");verify_200k_file(b);
1754 yaffs_unmount(mountpt);
1755 yaffs_mount(mountpt);
1756 printf("E\n");verify_200k_file(a);
1757 printf("F\n");verify_200k_file(b);
1763 void multi_mount_test(const char *mountpt,int nmounts)
1771 sprintf(a,"%s/a",mountpt);
1775 for(i = 0; i < nmounts; i++){
1781 static char xx[1000];
1783 printf("############### Iteration %d Start\n",i);
1784 if(1 || i == 0 || i == 5)
1785 yaffs_mount(mountpt);
1787 dump_directory_tree(mountpt);
1792 sprintf(xx,"%s/0",a);
1793 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1795 sprintf(xx,"%s/1",a);
1796 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1799 for(j = 0; j < 200; j++){
1800 yaffs_write(h0,xx,1000);
1801 yaffs_write(h1,xx,1000);
1804 while(yaffs_write(h0,xx,1000) > 0){
1806 yaffs_write(h1,xx,1000);
1809 len0 = yaffs_lseek(h0,0,SEEK_END);
1810 len1 = yaffs_lseek(h1,0,SEEK_END);
1812 yaffs_lseek(h0,0,SEEK_SET);
1813 yaffs_lseek(h1,0,SEEK_SET);
1815 for(j = 0; j < 200; j++){
1816 yaffs_read(h0,xx,1000);
1817 yaffs_read(h1,xx,1000);
1821 // yaffs_truncate(h0,0);
1825 printf("########### %d\n",i);
1826 dump_directory_tree(mountpt);
1828 if(1 || i == 4 || i == nmounts -1)
1829 yaffs_unmount(mountpt);
1834 void small_mount_test(const char *mountpt,int nmounts)
1848 sprintf(a,"%s/a",mountpt);
1854 for(i = 0; i < nmounts; i++){
1856 static char xx[1000];
1858 printf("############### Iteration %d Start\n",i);
1859 if(1 || i == 0 || i == 5)
1860 yaffs_mount(mountpt);
1862 dump_directory_tree(mountpt);
1866 sprintf(xx,"%s/0",a);
1869 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1870 for(j = 0; j < 130; j++)
1871 yaffs_write(h0,xx,1000);
1875 h0 = yaffs_open(xx,O_RDONLY,0);
1877 sprintf(xx,"%s/1",a);
1878 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1880 while((nread = yaffs_read(h0,xx,1000)) > 0)
1881 yaffs_write(h1,xx,nread);
1884 len0 = yaffs_lseek(h0,0,SEEK_END);
1885 len1 = yaffs_lseek(h1,0,SEEK_END);
1887 yaffs_lseek(h0,0,SEEK_SET);
1888 yaffs_lseek(h1,0,SEEK_SET);
1890 for(j = 0; j < 200; j++){
1891 yaffs_read(h0,xx,1000);
1892 yaffs_read(h1,xx,1000);
1898 printf("########### %d\n",i);
1899 dump_directory_tree(mountpt);
1901 if(1 || i == 4 || i == nmounts -1)
1902 yaffs_unmount(mountpt);
1909 void small_overwrite_test(const char *mountpt,int nmounts)
1920 sprintf(a,"%s/a",mountpt);
1926 for(i = 0; i < nmounts; i++){
1928 static char xx[8000];
1930 printf("############### Iteration %d Start\n",i);
1932 yaffs_mount(mountpt);
1934 dump_directory_tree(mountpt);
1938 sprintf(xx,"%s/0",a);
1939 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1940 sprintf(xx,"%s/1",a);
1941 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1943 for(j = 0; j < 1000000; j+=1000){
1944 yaffs_ftruncate(h0,j);
1945 yaffs_lseek(h0,j,SEEK_SET);
1946 yaffs_write(h0,xx,7000);
1947 yaffs_write(h1,xx,7000);
1955 printf("########### %d\n",i);
1956 dump_directory_tree(mountpt);
1959 yaffs_unmount(mountpt);
1964 void seek_overwrite_test(const char *mountpt,int nmounts)
1975 sprintf(a,"%s/f",mountpt);
1979 yaffs_mount(mountpt);
1982 for(i = 0; i < nmounts; i++){
1984 h0 = yaffs_open(a, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1986 for(j = 0; j < 100000; j++){
1987 yaffs_lseek(h0,0,SEEK_SET);
1988 yaffs_write(h0,xx,5000);
1989 yaffs_lseek(h0,0x100000,SEEK_SET);
1990 yaffs_write(h0,xx,5000);
2002 void yaffs_touch(const char *fn)
2004 yaffs_chmod(fn, S_IREAD | S_IWRITE);
2007 void checkpoint_fill_test(const char *mountpt,int nmounts)
2018 sprintf(a,"%s/a",mountpt);
2025 for(i = 0; i < nmounts; i++){
2026 printf("############### Iteration %d Start\n",i);
2027 yaffs_mount(mountpt);
2028 dump_directory_tree(mountpt);
2031 sprintf(b,"%s/zz",a);
2033 h = yaffs_open(b,O_CREAT | O_RDWR,S_IREAD |S_IWRITE);
2036 while(yaffs_write(h,c,50) == 50){}
2040 for(j = 0; j < 2; j++){
2041 printf("touch %d\n",j);
2043 yaffs_unmount(mountpt);
2044 yaffs_mount(mountpt);
2047 dump_directory_tree(mountpt);
2048 yaffs_unmount(mountpt);
2053 int make_file2(const char *name1, const char *name2,int syz)
2063 h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2065 h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2067 while(syz > 0 && n > 0){
2068 i = (syz > 2500) ? 2500 : syz;
2069 n = yaffs_write(h1,xx,i);
2070 n = yaffs_write(h2,xx,i);
2079 extern void SetCheckpointReservedBlocks(int n);
2081 void checkpoint_upgrade_test(const char *mountpt,int nmounts)
2091 sprintf(a,"%s/a",mountpt);
2096 printf("Create start condition\n");
2098 SetCheckpointReservedBlocks(0);
2099 yaffs_mount(mountpt);
2101 sprintf(b,"%s/zz",a);
2102 sprintf(c,"%s/xx",a);
2103 make_file2(b,c,2000000);
2104 sprintf(d,"%s/aa",a);
2105 make_file2(d,NULL,500000000);
2106 dump_directory_tree(mountpt);
2108 printf("Umount/mount attempt full\n");
2109 yaffs_unmount(mountpt);
2111 SetCheckpointReservedBlocks(10);
2112 yaffs_mount(mountpt);
2114 printf("unlink small file\n");
2116 dump_directory_tree(mountpt);
2118 printf("Umount/mount attempt\n");
2119 yaffs_unmount(mountpt);
2120 yaffs_mount(mountpt);
2122 for(j = 0; j < 500; j++){
2123 printf("***** touch %d\n",j);
2124 dump_directory_tree(mountpt);
2126 yaffs_unmount(mountpt);
2127 yaffs_mount(mountpt);
2130 for(j = 0; j < 500; j++){
2131 printf("***** touch %d\n",j);
2132 dump_directory_tree(mountpt);
2134 yaffs_unmount(mountpt);
2135 yaffs_mount(mountpt);
2139 void huge_array_test(const char *mountpt,int n)
2150 sprintf(a,"mount point %s",mountpt);
2156 yaffs_mount(mountpt);
2161 printf("\n\n START run\n\n");
2162 while((space = yaffs_freespace(mountpt)) > 25000000){
2163 sprintf(a,"%s/file%d",mountpt,fnum);
2165 printf("create file %s, free space %d\n",a,space);
2166 create_file_of_size(a,10000000);
2167 printf("verifying file %s\n",a);
2168 verify_file_of_size(a,10000000);
2171 printf("\n\n verification/deletion\n\n");
2173 for(i = 0; i < fnum; i++){
2174 sprintf(a,"%s/file%d",mountpt,i);
2175 printf("verifying file %s\n",a);
2176 verify_file_of_size(a,10000000);
2177 printf("deleting file %s\n",a);
2180 printf("\n\n done \n\n");
2187 void random_write(int h)
2189 static char buffer[12000];
2192 n = random() & 0x1FFF;
2193 yaffs_write(h,buffer,n);
2196 void random_seek(int h)
2199 n = random() & 0xFFFFF;
2200 yaffs_lseek(h,n,SEEK_SET);
2203 void random_truncate(int h, char * name)
2207 n = random() & 0xFFFFF;
2208 flen = yaffs_lseek(h,0,SEEK_END);
2211 yaffs_ftruncate(h,n);
2212 yaffs_lseek(h,n,SEEK_SET);
2216 #define NSMALLFILES 10
2217 void random_small_file_test(const char *mountpt,int iterations)
2220 char a[NSMALLFILES][50];
2231 yaffs_mount(mountpt);
2233 for(i = 0; i < NSMALLFILES; i++){
2238 for(n = 0; n < iterations; n++){
2240 for(i = 0; i < NSMALLFILES; i++) {
2243 if(strlen(a[i]) == 0){
2244 sprintf(a[i],"%s/%dx%d",mountpt,n,i);
2245 h[i] = yaffs_open(a[i],O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2249 printf("Could not open yaffs file %d %d error %d\n",n,i,h[i]);
2259 random_truncate(h[i],a[i]);
2262 case 5: random_seek(h[i]);
2279 for(i = 0; i < NSMALLFILES; i++)
2282 yaffs_unmount(mountpt);
2285 void rmdir_test(const char *mountpt)
2290 yaffs_mount(mountpt);
2292 strcpy(name,mountpt);
2294 strcat(name,"hello");
2295 yaffs_mkdir(name,0666);
2297 yaffs_unmount(mountpt);
2302 int simulate_power_failure;
2304 int main(int argc, char *argv[])
2306 random_seed = time(NULL);
2307 //return long_test(argc,argv);
2309 //return cache_read_test();
2311 // resize_stress_test_no_grow("/flash/flash",20);
2312 //root_perm_remount("/flash/flash");
2314 //huge_directory_test_on_path("/ram2k");
2316 //yaffs_backward_scan_test("/flash/flash");
2317 // yaffs_device_flush_test("/flash/flash");
2319 //rename_over_test("//////////////////flash///////////////////yaffs1///////////");
2321 rmdir_test("/M18-1");
2323 //scan_pattern_test("/flash",10000,10);
2324 //short_scan_test("/flash/flash",40000,200);
2325 //small_mount_test("/flash/flash",1000);
2326 //small_overwrite_test("/flash/flash",1000);
2327 //seek_overwrite_test("/flash/flash",1000);
2328 //checkpoint_fill_test("/flash/flash",20);
2329 //checkpoint_upgrade_test("/flash/flash",20);
2330 //small_overwrite_test("/flash/flash",1000);
2331 //checkpoint_fill_test("/flash/flash",20);
2332 // random_small_file_test("/flash/flash",10000);
2333 // huge_array_test("/flash/flash",10);
2338 //long_test_on_path("/ram2k");
2339 // long_test_on_path("/flash");
2340 //simple_rw_test("/flash/flash");
2341 //fill_disk_test("/flash/flash");
2342 // rename_over_test("/flash");
2343 //lookup_test("/flash");
2344 //freespace_test("/flash/flash");
2346 //link_test("/flash/flash");
2351 // cache_bypass_bug_test();
2353 //free_space_check();
2355 //check_resize_gc_bug("/flash");