2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2007 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.
16 * Test code for the "direct" interface.
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)
135 h = yaffs_open(fn, O_RDWR,0);
139 while(yaffs_read(h,&b,1)> 0)
156 void dump_file(const char *fn)
162 h = yaffs_open(fn,O_RDONLY,0);
165 printf("*****\nDump file %s does not exist\n",fn);
169 size = yaffs_lseek(h,0,SEEK_SET);
170 printf("*****\nDump file %s size %d\n",fn,size);
171 for(i = 0; i < size; i++)
178 void create_file_of_size(const char *fn,int syze)
185 int iterations = (syze + strlen(fn) -1)/ strlen(fn);
187 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
189 while (iterations > 0)
191 sprintf(xx,"%s %8d",fn,iterations);
192 yaffs_write(h,xx,strlen(xx));
198 void verify_file_of_size(const char *fn,int syze)
207 int iterations = (syze + strlen(fn) -1)/ strlen(fn);
209 h = yaffs_open(fn, O_RDONLY, S_IREAD | S_IWRITE);
211 while (iterations > 0)
213 sprintf(xx,"%s %8d",fn,iterations);
220 printf("=====>>>>> verification of file %s failed near position %d\n",fn,yaffs_lseek(h,0,SEEK_CUR));
227 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_truncate(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(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(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 length %d mode %X ",de->d_name,(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 struct yaffs_stat ystat;
904 // Create a large number of files
906 for(i = 0; i < 2000; i++)
908 sprintf(str,"%s/%d",path,i);
910 f = yaffs_open(str,O_CREAT,S_IREAD | S_IWRITE);
916 d = yaffs_opendir(path);
919 while((de = yaffs_readdir(d)) != NULL) {
920 if (total >lastTotal+100*9*1024||(i & 1023)==0){
921 printf("files = %d, total = %d\n",i, total);
925 sprintf(str,"%s/%s",path,de->d_name);
927 switch(s.st_mode & S_IFMT){
929 //printf("data file");
941 int yaffs_scan_test(const char *path)
946 void rename_over_test(const char *mountpt)
952 sprintf(a,"%s/a",mountpt);
953 sprintf(b,"%s/b",mountpt);
957 yaffs_mount(mountpt);
958 i = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0);
960 i = yaffs_open(b,O_CREAT | O_TRUNC | O_RDWR, 0);
962 yaffs_rename(a,b); // rename over
963 yaffs_rename(b,a); // rename back again (not renaimng over)
964 yaffs_rename(a,b); // rename back again (not renaimng over)
967 yaffs_unmount(mountpt);
971 int resize_stress_test(const char *path)
986 sprintf(aname,"%s%s",path,"/a");
987 sprintf(bname,"%s%s",path,"/b");
989 memset(abuffer,'a',1000);
990 memset(bbuffer,'b',1000);
992 a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
993 b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
995 printf(" %s %d %s %d\n",aname,a,bname,b);
999 for(j = 0; j < 100; j++)
1001 yaffs_lseek(a,0,SEEK_END);
1004 for(i = 0; i <20000; i++)
1006 //r = yaffs_lseek(b,i,SEEK_SET);
1007 //r = yaffs_write(b,bbuffer,1000);
1012 int syz = yaffs_lseek(a,0,SEEK_END);
1015 if(syz < 0) syz = 0;
1016 yaffs_truncate(a,syz);
1022 r = yaffs_lseek(a,i * 500,SEEK_SET);
1023 r = yaffs_write(a,abuffer,1000);
1035 int resize_stress_test_no_grow_complex(const char *path,int iters)
1050 sprintf(aname,"%s%s",path,"/a");
1051 sprintf(bname,"%s%s",path,"/b");
1053 memset(abuffer,'a',1000);
1054 memset(bbuffer,'b',1000);
1056 a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1057 b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1059 printf(" %s %d %s %d\n",aname,a,bname,b);
1063 for(j = 0; j < iters; j++)
1065 yaffs_lseek(a,0,SEEK_END);
1068 for(i = 0; i <20000; i++)
1070 //r = yaffs_lseek(b,i,SEEK_SET);
1071 //r = yaffs_write(b,bbuffer,1000);
1076 int syz = yaffs_lseek(a,0,SEEK_END);
1082 if(syz < 0) syz = 0;
1083 yaffs_truncate(a,syz);
1084 syz = yaffs_lseek(a,0,SEEK_END);
1085 printf("shrink to %d\n",syz);
1093 r = yaffs_lseek(a,500,SEEK_END);
1094 r = yaffs_write(a,abuffer,1000);
1100 printf("file size is %d\n",yaffs_lseek(a,0,SEEK_END));
1108 int resize_stress_test_no_grow(const char *path,int iters)
1123 sprintf(aname,"%s%s",path,"/a");
1124 sprintf(bname,"%s%s",path,"/b");
1126 memset(abuffer,'a',1000);
1127 memset(bbuffer,'b',1000);
1129 a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1130 b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1132 printf(" %s %d %s %d\n",aname,a,bname,b);
1136 for(j = 0; j < iters; j++)
1138 yaffs_lseek(a,0,SEEK_END);
1141 for(i = 0; i <20000; i++)
1143 //r = yaffs_lseek(b,i,SEEK_SET);
1144 //r = yaffs_write(b,bbuffer,1000);
1149 int syz = yaffs_lseek(a,0,SEEK_END);
1155 if(syz < 0) syz = 0;
1156 yaffs_truncate(a,syz);
1157 syz = yaffs_lseek(a,0,SEEK_END);
1158 printf("shrink to %d\n",syz);
1166 r = yaffs_lseek(a,-500,SEEK_END);
1167 r = yaffs_write(a,abuffer,1000);
1173 printf("file size is %d\n",yaffs_lseek(a,0,SEEK_END));
1181 int directory_rename_test(void)
1186 yaffs_mount("/ram");
1187 yaffs_mkdir("/ram/a",0);
1188 yaffs_mkdir("/ram/a/b",0);
1189 yaffs_mkdir("/ram/c",0);
1191 printf("\nDirectory look-up of /ram\n");
1194 dumpDir("/ram/a/b");
1196 printf("Do rename (should fail)\n");
1198 r = yaffs_rename("/ram/a","/ram/a/b/d");
1199 printf("\nDirectory look-up of /ram\n");
1202 dumpDir("/ram/a/b");
1204 printf("Do rename (should not fail)\n");
1206 r = yaffs_rename("/ram/c","/ram/a/b/d");
1207 printf("\nDirectory look-up of /ram\n");
1210 dumpDir("/ram/a/b");
1217 int cache_read_test(void)
1221 int sizeOfFiles = 500000;
1226 yaffs_mount("/boot");
1228 make_a_file("/boot/a",'a',sizeOfFiles);
1229 make_a_file("/boot/b",'b',sizeOfFiles);
1231 a = yaffs_open("/boot/a",O_RDONLY,0);
1232 b = yaffs_open("/boot/b",O_RDONLY,0);
1233 c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
1237 if (i > 100) i = 100;
1239 yaffs_read(a,buffer,i);
1240 yaffs_read(b,buffer,i);
1241 yaffs_write(c,buffer,i);
1242 } while(sizeOfFiles > 0);
1250 int cache_bypass_bug_test(void)
1252 // This test reporoduces a bug whereby YAFFS caching *was* buypassed
1253 // resulting in erroneous reads after writes.
1254 // This bug has been fixed.
1261 memset(buffer1,0,sizeof(buffer1));
1262 memset(buffer2,0,sizeof(buffer2));
1266 yaffs_mount("/boot");
1268 // Create a file of 2000 bytes.
1269 make_a_file("/boot/a",'X',2000);
1271 a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE);
1273 // Write a short sequence to the file.
1274 // This will go into the cache.
1275 yaffs_lseek(a,0,SEEK_SET);
1276 yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20);
1278 // Read a short sequence from the file.
1279 // This will come from the cache.
1280 yaffs_lseek(a,0,SEEK_SET);
1281 yaffs_read(a,buffer1,30);
1283 // Read a page size sequence from the file.
1284 yaffs_lseek(a,0,SEEK_SET);
1285 yaffs_read(a,buffer2,512);
1287 printf("buffer 1 %s\n",buffer1);
1288 printf("buffer 2 %s\n",buffer2);
1290 if(strncmp(buffer1,buffer2,20))
1292 printf("Cache bypass bug detected!!!!!\n");
1300 int free_space_check(void)
1305 yaffs_mount("/boot");
1306 fill_disk("/boot/",2);
1307 f = yaffs_freespace("/boot");
1309 printf("%d free when disk full\n",f);
1313 int truncate_test(void)
1323 yaffs_mount("/boot");
1325 yaffs_unlink("/boot/trunctest");
1327 a = yaffs_open("/boot/trunctest", O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1329 yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26);
1331 yaffs_truncate(a,3);
1332 l= yaffs_lseek(a,0,SEEK_END);
1334 printf("truncated length is %d\n",l);
1336 yaffs_lseek(a,5,SEEK_SET);
1337 yaffs_write(a,"1",1);
1339 yaffs_lseek(a,0,SEEK_SET);
1341 r = yaffs_read(a,y,10);
1343 printf("read %d bytes:",r);
1345 for(i = 0; i < r; i++) printf("[%02X]",y[i]);
1357 void fill_disk_test(const char *mountpt)
1362 for(i = 0; i < 5; i++)
1364 yaffs_mount(mountpt);
1365 fill_disk_and_delete(mountpt,100,i+1);
1366 yaffs_unmount(mountpt);
1373 void lookup_test(const char *mountpt)
1383 struct yaffs_stat s;
1388 yaffs_mount(mountpt);
1390 d = yaffs_opendir(mountpt);
1394 printf("opendir failed\n");
1399 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1401 printf("unlinking %s\n",de->d_name);
1402 yaffs_unlink(de->d_name);
1405 printf("%d files deleted\n",i);
1409 for(i = 0; i < 2000; i++){
1410 sprintf(a,"%s/%d",mountpt,i);
1411 h = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0);
1416 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1418 printf("%d %s\n",i,de->d_name);
1421 printf("%d files listed\n\n\n",i);
1428 for(i = 0; i < 2000; i++){
1429 sprintf(a,"%s/%d",mountpt,i);
1434 yaffs_unmount(mountpt);
1438 void link_test(const char *mountpt)
1450 sprintf(a,"%s/aaa",mountpt);
1451 sprintf(b,"%s/bbb",mountpt);
1452 sprintf(c,"%s/ccc",mountpt);
1456 yaffs_mount(mountpt);
1459 h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1460 for(i = 0; i < 100; i++)
1461 yaffs_write(h,a,100);
1474 yaffs_unmount(mountpt);
1475 yaffs_mount(mountpt);
1477 printf("link test done\n");
1481 void freespace_test(const char *mountpt)
1492 sprintf(a,"%s/aaa",mountpt);
1496 yaffs_mount(mountpt);
1498 f0 = yaffs_freespace(mountpt);
1500 h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1502 for(i = 0; i < 100; i++)
1503 yaffs_write(h,a,100);
1507 f1 = yaffs_freespace(mountpt);
1511 f2 = yaffs_freespace(mountpt);
1514 yaffs_unmount(mountpt);
1515 yaffs_mount(mountpt);
1517 f3 = yaffs_freespace(mountpt);
1519 printf("%d\n%d\n%d\n%d\n",f0, f1,f2,f3);
1524 void simple_rw_test(const char *mountpt)
1533 sprintf(a,"%s/aaa",mountpt);
1537 yaffs_mount(mountpt);
1541 h = yaffs_open(a,O_CREAT| O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1543 for(i = 100000;i < 200000; i++){
1544 result = yaffs_write(h,&i,sizeof(i));
1548 printf("write error\n");
1555 // h = yaffs_open(a,O_RDWR, S_IREAD | S_IWRITE);
1558 yaffs_lseek(h,0,SEEK_SET);
1560 for(i = 100000; i < 200000; i++){
1561 result = yaffs_read(h,&x,sizeof(x));
1563 if(result != 4 || x != i){
1564 printf("read error %d %x %x\n",i,result,x);
1568 printf("Simple rw test passed\n");
1575 void scan_deleted_files_test(const char *mountpt)
1587 sprintf(sub,"%s/sdir",mountpt);
1590 for(j = 0; j < 10; j++)
1592 printf("\n\n>>>>>>> Run %d <<<<<<<<<<<<<\n\n",j);
1593 yaffs_mount(mountpt);
1597 p = (j & 0) ? mountpt: sub;
1599 for(i = 0; i < 100; i++)
1601 sprintf(fn,"%s/%d",p,i);
1605 h = yaffs_open(fn,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1606 for(k = 0; k < 1000; k++)
1607 yaffs_write(h,fn,100);
1614 for(i = 0; i < 10; i++)
1616 sprintf(fn,"%s/%d",p,i);
1624 yaffs_unmount(mountpt);
1633 void write_10k(int h)
1636 const char *s="0123456789";
1637 for(i = 0; i < 1000; i++)
1638 yaffs_write(h,s,10);
1641 void write_200k_file(const char *fn, const char *fdel, const char *fdel1)
1647 h1 = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1649 for(i = 0; i < 100000; i+= 10000)
1654 offs = yaffs_lseek(h1,0,SEEK_CUR);
1657 printf("Could not write file\n");
1661 for(i = 0; i < 100000; i+= 10000)
1666 offs = yaffs_lseek(h1,0,SEEK_CUR);
1669 printf("Could not write file\n");
1673 yaffs_unlink(fdel1);
1678 void verify_200k_file(const char *fn)
1683 const char *s="0123456789";
1686 h1 = yaffs_open(fn, O_RDONLY, 0);
1688 for(i = 0; i < 200000 && errCount < 10; i+= 10)
1690 yaffs_read(h1,x,10);
1691 if(strncmp(x,s,10) != 0)
1693 printf("File %s verification failed at %d\n",fn,i);
1698 printf("Too many errors... aborted\n");
1705 void check_resize_gc_bug(const char *mountpt)
1714 sprintf(a,"%s/a",mountpt);
1715 sprintf(b,"%s/b",mountpt);
1716 sprintf(c,"%s/c",mountpt);
1722 yaffs_mount(mountpt);
1726 for(i = 0; i < 50; i++)
1728 printf("A\n");write_200k_file(a,"",c);
1729 printf("B\n");verify_200k_file(a);
1730 printf("C\n");write_200k_file(b,a,c);
1731 printf("D\n");verify_200k_file(b);
1732 yaffs_unmount(mountpt);
1733 yaffs_mount(mountpt);
1734 printf("E\n");verify_200k_file(a);
1735 printf("F\n");verify_200k_file(b);
1741 void multi_mount_test(const char *mountpt,int nmounts)
1751 sprintf(a,"%s/a",mountpt);
1755 for(i = 0; i < nmounts; i++){
1761 static char xx[1000];
1763 printf("############### Iteration %d Start\n",i);
1764 if(1 || i == 0 || i == 5)
1765 yaffs_mount(mountpt);
1767 dump_directory_tree(mountpt);
1772 sprintf(xx,"%s/0",a);
1773 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1775 sprintf(xx,"%s/1",a);
1776 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1778 for(j = 0; j < 200; j++){
1779 yaffs_write(h0,xx,1000);
1780 yaffs_write(h1,xx,1000);
1783 len0 = yaffs_lseek(h0,0,SEEK_END);
1784 len1 = yaffs_lseek(h1,0,SEEK_END);
1786 yaffs_lseek(h0,0,SEEK_SET);
1787 yaffs_lseek(h1,0,SEEK_SET);
1789 for(j = 0; j < 200; j++){
1790 yaffs_read(h0,xx,1000);
1791 yaffs_read(h1,xx,1000);
1795 yaffs_truncate(h0,0);
1799 printf("########### %d\n",i);
1800 dump_directory_tree(mountpt);
1802 if(1 || i == 4 || i == nmounts -1)
1803 yaffs_unmount(mountpt);
1808 void small_mount_test(const char *mountpt,int nmounts)
1824 sprintf(a,"%s/a",mountpt);
1830 for(i = 0; i < nmounts; i++){
1832 static char xx[1000];
1834 printf("############### Iteration %d Start\n",i);
1835 if(1 || i == 0 || i == 5)
1836 yaffs_mount(mountpt);
1838 dump_directory_tree(mountpt);
1842 sprintf(xx,"%s/0",a);
1845 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1846 for(j = 0; j < 130; j++)
1847 yaffs_write(h0,xx,1000);
1851 h0 = yaffs_open(xx,O_RDONLY,0);
1853 sprintf(xx,"%s/1",a);
1854 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1856 while((nread = yaffs_read(h0,xx,1000)) > 0)
1857 yaffs_write(h1,xx,nread);
1860 len0 = yaffs_lseek(h0,0,SEEK_END);
1861 len1 = yaffs_lseek(h1,0,SEEK_END);
1863 yaffs_lseek(h0,0,SEEK_SET);
1864 yaffs_lseek(h1,0,SEEK_SET);
1866 for(j = 0; j < 200; j++){
1867 yaffs_read(h0,xx,1000);
1868 yaffs_read(h1,xx,1000);
1874 printf("########### %d\n",i);
1875 dump_directory_tree(mountpt);
1877 if(1 || i == 4 || i == nmounts -1)
1878 yaffs_unmount(mountpt);
1885 void small_overwrite_test(const char *mountpt,int nmounts)
1901 sprintf(a,"%s/a",mountpt);
1907 for(i = 0; i < nmounts; i++){
1909 static char xx[8000];
1911 printf("############### Iteration %d Start\n",i);
1913 yaffs_mount(mountpt);
1915 dump_directory_tree(mountpt);
1919 sprintf(xx,"%s/0",a);
1920 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1921 sprintf(xx,"%s/1",a);
1922 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
1924 for(j = 0; j < 1000000; j+=1000){
1925 yaffs_truncate(h0,j);
1926 yaffs_lseek(h0,j,SEEK_SET);
1927 yaffs_write(h0,xx,7000);
1928 yaffs_write(h1,xx,7000);
1936 printf("########### %d\n",i);
1937 dump_directory_tree(mountpt);
1940 yaffs_unmount(mountpt);
1945 void yaffs_touch(const char *fn)
1947 yaffs_chmod(fn, S_IREAD | S_IWRITE);
1950 void checkpoint_fill_test(const char *mountpt,int nmounts)
1961 sprintf(a,"%s/a",mountpt);
1968 for(i = 0; i < nmounts; i++){
1969 printf("############### Iteration %d Start\n",i);
1970 yaffs_mount(mountpt);
1971 dump_directory_tree(mountpt);
1974 sprintf(b,"%s/zz",a);
1976 h = yaffs_open(b,O_CREAT | O_RDWR,S_IREAD |S_IWRITE);
1979 while(yaffs_write(h,c,50) == 50){}
1983 for(j = 0; j < 2; j++){
1984 printf("touch %d\n",j);
1986 yaffs_unmount(mountpt);
1987 yaffs_mount(mountpt);
1990 dump_directory_tree(mountpt);
1991 yaffs_unmount(mountpt);
1996 int make_file2(const char *name1, const char *name2,int syz)
2006 h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2008 h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2010 while(syz > 0 && n > 0){
2011 i = (syz > 2500) ? 2500 : syz;
2012 n = yaffs_write(h1,xx,i);
2013 n = yaffs_write(h2,xx,i);
2022 extern void SetCheckpointReservedBlocks(int n);
2024 void checkpoint_upgrade_test(const char *mountpt,int nmounts)
2036 sprintf(a,"%s/a",mountpt);
2041 printf("Create start condition\n");
2043 SetCheckpointReservedBlocks(0);
2044 yaffs_mount(mountpt);
2046 sprintf(b,"%s/zz",a);
2047 sprintf(c,"%s/xx",a);
2048 make_file2(b,c,2000000);
2049 sprintf(d,"%s/aa",a);
2050 make_file2(d,NULL,500000000);
2051 dump_directory_tree(mountpt);
2053 printf("Umount/mount attempt full\n");
2054 yaffs_unmount(mountpt);
2056 SetCheckpointReservedBlocks(10);
2057 yaffs_mount(mountpt);
2059 printf("unlink small file\n");
2061 dump_directory_tree(mountpt);
2063 printf("Umount/mount attempt\n");
2064 yaffs_unmount(mountpt);
2065 yaffs_mount(mountpt);
2067 for(j = 0; j < 500; j++){
2068 printf("***** touch %d\n",j);
2069 dump_directory_tree(mountpt);
2071 yaffs_unmount(mountpt);
2072 yaffs_mount(mountpt);
2075 for(j = 0; j < 500; j++){
2076 printf("***** touch %d\n",j);
2077 dump_directory_tree(mountpt);
2079 yaffs_unmount(mountpt);
2080 yaffs_mount(mountpt);
2084 void huge_array_test(const char *mountpt,int n)
2096 sprintf(a,"mount point %s",mountpt);
2102 yaffs_mount(mountpt);
2107 printf("\n\n START run\n\n");
2108 while(yaffs_freespace(mountpt) > 25000000){
2109 sprintf(a,"%s/file%d",mountpt,fnum);
2111 printf("create file %s\n",a);
2112 create_file_of_size(a,10000000);
2113 printf("verifying file %s\n",a);
2114 verify_file_of_size(a,10000000);
2117 printf("\n\n verification/deletion\n\n");
2119 for(i = 0; i < fnum; i++){
2120 sprintf(a,"%s/file%d",mountpt,i);
2121 printf("verifying file %s\n",a);
2122 verify_file_of_size(a,10000000);
2123 printf("deleting file %s\n",a);
2126 printf("\n\n done \n\n");
2134 int main(int argc, char *argv[])
2136 //return long_test(argc,argv);
2138 //return cache_read_test();
2140 //resize_stress_test_no_grow("/flash",20);
2142 //huge_directory_test_on_path("/ram2k");
2144 //yaffs_backward_scan_test("/flash/flash");
2145 // yaffs_device_flush_test("/flash/flash");
2148 //scan_pattern_test("/flash",10000,10);
2149 //short_scan_test("/flash/flash",40000,200);
2150 //small_mount_test("/flash/flash",1000);
2151 small_overwrite_test("/flash/flash",1000);
2152 //checkpoint_fill_test("/flash/flash",20);
2153 //checkpoint_upgrade_test("/flash/flash",20);
2154 // huge_array_test("/flash/flash",10);
2159 //long_test_on_path("/ram2k");
2160 // long_test_on_path("/flash");
2161 //simple_rw_test("/flash/flash");
2162 //fill_disk_test("/flash/flash");
2163 // rename_over_test("/flash");
2164 //lookup_test("/flash");
2165 //freespace_test("/flash/flash");
2167 //link_test("/flash/flash");
2172 // cache_bypass_bug_test();
2174 //free_space_check();
2176 //check_resize_gc_bug("/flash");