2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
4 * Copyright (C) 2002-2011 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.
23 #include "yaffs_guts.h" /* Only for dumping device innards */
25 extern int yaffs_trace_mask;
27 void dumpDir(const char *dname);
29 void copy_in_a_file(const char *yaffsName,const char *inName)
32 unsigned char buffer[100];
34 inh = open(inName,O_RDONLY);
35 outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
37 while((ni = read(inh,buffer,100)) > 0)
39 no = yaffs_write(outh,buffer,ni);
42 printf("problem writing yaffs file\n");
51 void make_a_file(const char *yaffsName,char bval,int sizeOfFile)
55 unsigned char buffer[100];
57 outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
59 memset(buffer,bval,100);
66 yaffs_write(outh,buffer,i);
68 } while (sizeOfFile > 0);
75 void make_pattern_file(char *fn,int size)
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);
84 for(i = 0; i < size; i+=256)
87 yaffs_lseek(outh,i,SEEK_SET);
88 yaffs_write(outh,&marker,sizeof(marker));
94 int check_pattern_file(char *fn)
102 h = yaffs_open(fn, O_RDWR,0);
103 size = yaffs_lseek(h,0,SEEK_END);
105 for(i = 0; i < size; i+=256)
107 yaffs_lseek(h,i,SEEK_SET);
108 yaffs_read(h,&marker,sizeof(marker));
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);
124 int dump_file_data(char *fn)
131 h = yaffs_open(fn, O_RDWR,0);
135 while(yaffs_read(h,&b,1)> 0)
152 void dump_file(const char *fn)
158 h = yaffs_open(fn,O_RDONLY,0);
161 printf("*****\nDump file %s does not exist\n",fn);
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++)
174 void create_file_of_size(const char *fn,int syze)
182 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
186 sprintf(xx,"%s %8d",fn,iteration);
188 result = yaffs_write(h,xx,n);
190 printf("Wrote %d, should have been %d. syze is %d\n",result,n,syze);
199 void verify_file_of_size(const char *fn,int syze)
208 int iterations = (syze + strlen(fn) -1)/ strlen(fn);
210 h = yaffs_open(fn, O_RDONLY, S_IREAD | S_IWRITE);
212 while (iterations > 0)
214 sprintf(xx,"%s %8d",fn,iterations);
217 result = yaffs_read(h,yy,l);
221 printf("=====>>>>> verification of file %s failed near position %lld\n",fn,(long long)yaffs_lseek(h,0,SEEK_CUR));
228 void create_resized_file_of_size(const char *fn,int syze1,int reSyze, int syze2)
234 h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
236 iterations = (syze1 + strlen(fn) -1)/ strlen(fn);
237 while (iterations > 0)
239 yaffs_write(h,fn,strlen(fn));
243 yaffs_ftruncate(h,reSyze);
245 yaffs_lseek(h,0,SEEK_SET);
246 iterations = (syze2 + strlen(fn) -1)/ strlen(fn);
247 while (iterations > 0)
249 yaffs_write(h,fn,strlen(fn));
257 void do_some_file_stuff(const char *path)
262 sprintf(fn,"%s/%s",path,"f1");
263 create_file_of_size(fn,10000);
265 sprintf(fn,"%s/%s",path,"fdel");
266 create_file_of_size(fn,10000);
269 sprintf(fn,"%s/%s",path,"f2");
271 create_resized_file_of_size(fn,10000,3000,4000);
274 void yaffs_backward_scan_test(const char *path)
282 do_some_file_stuff(path);
284 sprintf(fn,"%s/ddd",path);
288 do_some_file_stuff(fn);
295 void null_name_test(const char *path)
303 sprintf(fn,"%s",path);
305 h = yaffs_open(fn,O_CREAT| O_TRUNC| O_RDWR, 0666);
314 void yaffs_device_flush_test(const char *path)
324 do_some_file_stuff(path);
326 // Open and add some data to a few files
327 for(i = 0; i < 10; i++) {
329 sprintf(fn,"%s/ff%d",path,i);
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);
342 void short_scan_test(const char *path, int fsize, int niterations)
347 sprintf(fn,"%s/%s",path,"f1");
350 for(i = 0; i < niterations; i++)
352 printf("\n*****************\nIteration %d\n",i);
354 printf("\nmount: Directory look-up of %s\n",path);
356 make_a_file(fn,1,fsize);
363 void scan_pattern_test(const char *path, int fsize, int niterations)
370 sprintf(fn[0],"%s/%s",path,"f0");
371 sprintf(fn[1],"%s/%s",path,"f1");
372 sprintf(fn[2],"%s/%s",path,"f2");
376 for(i = 0; i < niterations; i++)
378 printf("\n*****************\nIteration %d\n",i);
380 printf("\nmount: Directory look-up of %s\n",path);
382 for(j = 0; j < 3; j++)
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]);
394 void fill_disk(const char *path,int nfiles)
404 for(n = 0; n < nfiles; n++)
406 sprintf(str,"%s/%d",path,n);
408 h = yaffs_open(str, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
410 printf("writing file %s handle %d ",str, h);
412 while ((result = yaffs_write(h,xx,600)) == 600)
414 f = yaffs_freespace(path);
416 result = yaffs_close(h);
417 printf(" close %d\n",result);
421 void fill_disk_and_delete(const char *path, int nfiles, int ncycles)
427 for(i = 0; i < ncycles; i++)
429 printf("@@@@@@@@@@@@@@ cycle %d\n",i);
430 fill_disk(path,nfiles);
432 for(j = 0; j < nfiles; j++)
434 sprintf(str,"%s/%d",path,j);
435 result = yaffs_unlink(str);
436 printf("unlinking file %s, result %d\n",str,result);
442 void fill_files(const char *path,int flags, int maxIterations,int siz)
452 sprintf(str,"%s/%d",path,i);
453 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
457 for(j = 0; j < siz; j++)
459 yaffs_write(h,str,1);
468 } while(h >= 0 && i < maxIterations);
474 sprintf(str,"%s/%d",path,i);
475 printf("unlink %s\n",str);
477 } while(yaffs_unlink(str) >= 0);
481 void leave_unlinked_file(const char *path,int maxIterations,int siz)
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);
498 } while(h < 0 && i < maxIterations);
502 for(i = 0; i < siz; i++)
504 yaffs_write(h,str,1);
508 printf("Leaving file %s open\n",str);
512 void dumpDirFollow(const char *dname)
515 struct yaffs_dirent *de;
519 d = yaffs_opendir(dname);
523 printf("opendir failed\n");
527 while((de = yaffs_readdir(d)) != NULL)
529 sprintf(str,"%s/%s",dname,de->d_name);
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)
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)
542 printf("\"%s\"",str);
544 default: printf("unknown"); break;
554 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
559 void dump_directory_tree_worker(const char *dname,int recursive)
562 struct yaffs_dirent *de;
566 d = yaffs_opendir(dname);
570 printf("opendir failed\n");
574 while((de = yaffs_readdir(d)) != NULL)
576 sprintf(str,"%s/%s",dname,de->d_name);
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)
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)
590 printf("\"%s\"",str);
592 default: printf("unknown"); break;
597 if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
598 dump_directory_tree_worker(str,1);
607 static void dump_directory_tree(const char *dname)
609 dump_directory_tree_worker(dname,1);
611 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
614 void dumpDir(const char *dname)
615 { dump_directory_tree_worker(dname,0);
617 printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
621 static void PermissionsCheck(const char *path, mode_t tmode, int tflags,int expectedResult)
625 if(yaffs_chmod(path,tmode)< 0) printf("chmod failed\n");
627 fd = yaffs_open(path,tflags,0);
629 if((fd >= 0) != (expectedResult > 0))
631 printf("Permissions check %x %x %d failed\n",tmode,tflags,expectedResult);
635 printf("Permissions check %x %x %d OK\n",tmode,tflags,expectedResult);
644 int long_test(int argc, char *argv[])
655 struct yaffs_stat ystat;
659 yaffs_mount("/boot");
660 yaffs_mount("/data");
661 yaffs_mount("/flash");
664 printf("\nDirectory look-up of /boot\n");
666 printf("\nDirectory look-up of /data\n");
668 printf("\nDirectory look-up of /flash\n");
671 //leave_unlinked_file("/flash",20000,0);
672 //leave_unlinked_file("/data",20000,0);
674 leave_unlinked_file("/ram",20,0);
677 f = yaffs_open("/boot/b1", O_RDONLY,0);
679 printf("open /boot/b1 readonly, f=%d\n",f);
681 f = yaffs_open("/boot/b1", O_CREAT,S_IREAD | S_IWRITE);
683 printf("open /boot/b1 O_CREAT, f=%d\n",f);
686 r = yaffs_write(f,"hello",1);
687 printf("write %d attempted to write to a read-only file\n",r);
691 printf("close %d\n",r);
693 f = yaffs_open("/boot/b1", O_RDWR,0);
695 printf("open /boot/b1 O_RDWR,f=%d\n",f);
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);
703 r= yaffs_lseek(f,0,SEEK_END);
704 printf("seek end %d\n",r);
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);
711 r = yaffs_read(f,buffer,10);
712 printf("read %d \"%s\"\n",r,buffer);
714 r = yaffs_read(f,buffer,10);
715 printf("read %d \"%s\"\n",r,buffer);
717 // Check values reading at end.
718 // A read past end of file should return 0 for 0 bytes read.
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);
729 printf("close %d\n",r);
731 copy_in_a_file("/boot/yyfile","xxx");
733 // Create a file with a long name
735 copy_in_a_file("/boot/file with a long name","xxx");
738 printf("\nDirectory look-up of /boot\n");
742 r = yaffs_lstat("/boot/file with a long name",&ystat);
746 r = yaffs_rename("/boot/file with a long name","/boot/r1");
748 printf("\nDirectory look-up of /boot\n");
752 r = yaffs_unlink("/boot/r1");
754 printf("\nDirectory look-up of /boot\n");
759 r = yaffs_mkdir("/boot/directory1",0);
761 printf("\nDirectory look-up of /boot\n");
763 printf("\nDirectory look-up of /boot/directory1\n");
764 dumpDir("/boot/directory1");
766 // add a file to the directory
767 copy_in_a_file("/boot/directory1/file with a long name","xxx");
769 printf("\nDirectory look-up of /boot\n");
771 printf("\nDirectory look-up of /boot/directory1\n");
772 dumpDir("/boot/directory1");
774 // Attempt to delete directory (should fail)
776 r = yaffs_rmdir("/boot/directory1");
778 printf("\nDirectory look-up of /boot\n");
780 printf("\nDirectory look-up of /boot/directory1\n");
781 dumpDir("/boot/directory1");
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");
788 printf("\nDirectory look-up of /boot\n");
790 printf("\nDirectory look-up of /boot/directory1\n");
791 dumpDir("/boot/directory1");
794 fill_disk_and_delete("/boot",20,20);
796 printf("\nDirectory look-up of /boot\n");
800 yaffs_symlink("yyfile","/boot/slink");
802 yaffs_readlink("/boot/slink",str,100);
803 printf("symlink alias is %s\n",str);
808 printf("\nDirectory look-up of /boot\n");
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");
815 h = yaffs_open("/boot/slink",O_RDWR,0);
817 printf("file length is %d\n",(int)yaffs_lseek(h,0,SEEK_END));
821 yaffs_unlink("/boot/slink");
824 printf("\nDirectory look-up of /boot\n");
829 yaffs_lstat("/boot/yyfile",&ystat);
830 temp_mode = ystat.st_mode;
832 yaffs_chmod("/boot/yyfile",0x55555);
833 printf("\nDirectory look-up of /boot\n");
836 yaffs_chmod("/boot/yyfile",temp_mode);
837 printf("\nDirectory look-up of /boot\n");
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);
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);
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);
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);
857 yaffs_chmod("/boot/yyfile",temp_mode);
859 //create a zero-length file and unlink it (test for scan bug)
861 h = yaffs_open("/boot/zlf",O_CREAT | O_TRUNC | O_RDWR,0);
864 yaffs_unlink("/boot/zlf");
867 yaffs_dump_dev("/boot");
869 fill_disk_and_delete("/boot",20,20);
871 yaffs_dump_dev("/boot");
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);
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);
885 yaffs_dump_dev("/boot");
886 yaffs_dump_dev("/data");
894 int huge_directory_test_on_path(char *path)
898 struct yaffs_dirent *de;
914 // Create a large number of files
916 for(i = 0; i < 2000; i++)
918 sprintf(str,"%s/%d",path,i);
920 f = yaffs_open(str,O_CREAT,S_IREAD | S_IWRITE);
926 d = yaffs_opendir(path);
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);
935 sprintf(str,"%s/%s",path,de->d_name);
937 switch(s.st_mode & S_IFMT){
939 //printf("data file");
951 int yaffs_scan_test(const char *path)
957 void rename_over_test(const char *mountpt)
964 sprintf(a,"%s/a",mountpt);
965 sprintf(b,"%s/b",mountpt);
966 sprintf(c,"%s/c",mountpt);
970 yaffs_mount(mountpt);
972 printf("Existing files\n");
973 dumpDirFollow(mountpt);
977 i = yaffs_open(c,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
978 printf("File c handle is %d\n",i);
980 i = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
982 i = yaffs_open(b,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
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)
989 yaffs_unmount(mountpt);
994 int resize_stress_test(const char *path)
1009 sprintf(aname,"%s%s",path,"/a");
1010 sprintf(bname,"%s%s",path,"/b");
1012 memset(abuffer,'a',1000);
1013 memset(bbuffer,'b',1000);
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);
1018 printf(" %s %d %s %d\n",aname,a,bname,b);
1022 for(j = 0; j < 100; j++)
1024 yaffs_lseek(a,0,SEEK_END);
1027 for(i = 0; i <20000; i++)
1029 //r = yaffs_lseek(b,i,SEEK_SET);
1030 //r = yaffs_write(b,bbuffer,1000);
1035 int syz = yaffs_lseek(a,0,SEEK_END);
1038 if(syz < 0) syz = 0;
1039 yaffs_ftruncate(a,syz);
1045 r = yaffs_lseek(a,i * 500,SEEK_SET);
1046 r = yaffs_write(a,abuffer,1000);
1058 int overwrite_test(const char *path)
1070 sprintf(aname,"%s%s",path,"/a");
1071 sprintf(bname,"%s%s",path,"/b");
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));
1087 int root_perm_remount(const char *path)
1089 struct yaffs_stat s;
1095 yaffs_lstat(path,&s);
1096 printf("root perms after mount %x\n",s.st_mode);
1098 yaffs_chmod(path, 0777);
1100 yaffs_lstat(path,&s);
1101 printf("root perms after setting to 0777 is %x\n",s.st_mode);
1103 yaffs_unmount(path);
1110 int resize_stress_test_no_grow_complex(const char *path,int iters)
1126 sprintf(aname,"%s%s",path,"/a");
1127 sprintf(bname,"%s%s",path,"/b");
1129 memset(abuffer,'a',1000);
1130 memset(bbuffer,'b',1000);
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);
1135 printf(" %s %d %s %d\n",aname,a,bname,b);
1139 for(j = 0; j < iters; j++)
1141 yaffs_lseek(a,0,SEEK_END);
1144 for(i = 0; i <20000; i++)
1146 //r = yaffs_lseek(b,i,SEEK_SET);
1147 //r = yaffs_write(b,bbuffer,1000);
1152 int syz = yaffs_lseek(a,0,SEEK_END);
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);
1169 r = yaffs_lseek(a,500,SEEK_END);
1170 r = yaffs_write(a,abuffer,1000);
1177 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1185 int resize_stress_test_no_grow(const char *path,int iters)
1200 sprintf(aname,"%s%s",path,"/a");
1201 sprintf(bname,"%s%s",path,"/b");
1203 memset(abuffer,'a',1000);
1204 memset(bbuffer,'b',1000);
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);
1209 printf(" %s %d %s %d\n",aname,a,bname,b);
1213 for(j = 0; j < iters; j++)
1215 yaffs_lseek(a,0,SEEK_END);
1218 for(i = 0; i <20000; i++)
1220 //r = yaffs_lseek(b,i,SEEK_SET);
1221 //r = yaffs_write(b,bbuffer,1000);
1226 int syz = yaffs_lseek(a,0,SEEK_END);
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);
1243 r = yaffs_lseek(a,-500,SEEK_END);
1244 r = yaffs_write(a,abuffer,1000);
1250 printf("file size is %lld\n",(long long)yaffs_lseek(a,0,SEEK_END));
1258 int directory_rename_test(void)
1263 yaffs_mount("/ram");
1264 yaffs_mkdir("/ram/a",0);
1265 yaffs_mkdir("/ram/a/b",0);
1266 yaffs_mkdir("/ram/c",0);
1268 printf("\nDirectory look-up of /ram\n");
1271 dumpDir("/ram/a/b");
1273 printf("Do rename (should fail)\n");
1275 r = yaffs_rename("/ram/a","/ram/a/b/d");
1276 printf("\nDirectory look-up of /ram\n");
1279 dumpDir("/ram/a/b");
1281 printf("Do rename (should not fail)\n");
1283 r = yaffs_rename("/ram/c","/ram/a/b/d");
1284 printf("\nDirectory look-up of /ram\n");
1287 dumpDir("/ram/a/b");
1294 int cache_read_test(void)
1298 int sizeOfFiles = 500000;
1303 yaffs_mount("/boot");
1305 make_a_file("/boot/a",'a',sizeOfFiles);
1306 make_a_file("/boot/b",'b',sizeOfFiles);
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);
1314 if (i > 100) i = 100;
1316 yaffs_read(a,buffer,i);
1317 yaffs_read(b,buffer,i);
1318 yaffs_write(c,buffer,i);
1319 } while(sizeOfFiles > 0);
1327 int cache_bypass_bug_test(void)
1329 // This test reporoduces a bug whereby YAFFS caching *was* buypassed
1330 // resulting in erroneous reads after writes.
1331 // This bug has been fixed.
1337 memset(buffer1,0,sizeof(buffer1));
1338 memset(buffer2,0,sizeof(buffer2));
1342 yaffs_mount("/boot");
1344 // Create a file of 2000 bytes.
1345 make_a_file("/boot/a",'X',2000);
1347 a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE);
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);
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);
1359 // Read a page size sequence from the file.
1360 yaffs_lseek(a,0,SEEK_SET);
1361 yaffs_read(a,buffer2,512);
1363 printf("buffer 1 %s\n",buffer1);
1364 printf("buffer 2 %s\n",buffer2);
1366 if(strncmp(buffer1,buffer2,20))
1368 printf("Cache bypass bug detected!!!!!\n");
1376 int free_space_check(void)
1381 yaffs_mount("/boot");
1382 fill_disk("/boot/",2);
1383 f = yaffs_freespace("/boot");
1385 printf("%d free when disk full\n",f);
1389 int truncate_test(void)
1399 yaffs_mount("/boot");
1401 yaffs_unlink("/boot/trunctest");
1403 a = yaffs_open("/boot/trunctest", O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1405 yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26);
1407 yaffs_ftruncate(a,3);
1408 l= yaffs_lseek(a,0,SEEK_END);
1410 printf("truncated length is %d\n",l);
1412 yaffs_lseek(a,5,SEEK_SET);
1413 yaffs_write(a,"1",1);
1415 yaffs_lseek(a,0,SEEK_SET);
1417 r = yaffs_read(a,y,10);
1419 printf("read %d bytes:",r);
1421 for(i = 0; i < r; i++) printf("[%02X]",y[i]);
1433 void fill_disk_test(const char *mountpt)
1438 for(i = 0; i < 5; i++)
1440 yaffs_mount(mountpt);
1441 fill_disk_and_delete(mountpt,100,i+1);
1442 yaffs_unmount(mountpt);
1448 void fill_files_test(const char *mountpt)
1453 for(i = 0; i < 5; i++)
1455 yaffs_mount(mountpt);
1456 fill_files(mountpt,2,3,100);
1457 yaffs_unmount(mountpt);
1462 void fill_empty_files_test(const char *mountpt)
1471 for(i = 0; i < 5; i++)
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);
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);
1486 yaffs_unmount(mountpt);
1491 void long_name_test(const char *mountpt)
1495 char fullName[1000];
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;
1506 sprintf(fullName,"%s/%s",mountpt,name);
1508 for(i = 0; i < 1; i++)
1510 yaffs_mount(mountpt);
1512 printf("Files at start\n");
1515 printf("Creating file %s\n",fullName);
1517 f = yaffs_open(fullName,O_CREAT | O_RDWR,0);
1520 printf("Result %d\n",f);
1525 printf("Deleting %s\n",fullName);
1526 result = yaffs_unlink(fullName);
1527 printf("Result %d\n",result);
1533 yaffs_unmount(mountpt);
1539 void lookup_test(const char *mountpt)
1547 struct yaffs_dirent *de;
1551 yaffs_mount(mountpt);
1553 d = yaffs_opendir(mountpt);
1557 printf("opendir failed\n");
1562 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1564 printf("unlinking %s\n",de->d_name);
1565 yaffs_unlink(de->d_name);
1568 printf("%d files deleted\n",i);
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);
1579 for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
1581 printf("%d %s\n",i,de->d_name);
1584 printf("%d files listed\n\n\n",i);
1591 for(i = 0; i < 2000; i++){
1592 sprintf(a,"%s/%d",mountpt,i);
1597 yaffs_unmount(mountpt);
1601 void link_test0(const char *mountpt)
1609 yaffs_mount(mountpt);
1612 sprintf(namea,"%s/a",mountpt);
1613 sprintf(nameb,"%s/b",mountpt);
1615 printf("mounted\n");
1618 yaffs_unlink(namea);
1619 printf("a unlinked\n");
1622 yaffs_unlink(nameb);
1623 printf("b unlinked\n");
1626 result = yaffs_open(namea,O_CREAT| O_RDWR,0666);
1627 yaffs_close(result);
1628 printf("a created\n");
1631 yaffs_link(namea,nameb);
1634 yaffs_unlink(namea);
1635 printf("a ulinked\n");
1637 yaffs_unlink(nameb);
1638 printf("b unlinked\n");
1641 yaffs_unmount(mountpt);
1645 void link_test1(const char *mountpt)
1653 sprintf(a,"%s/aaa",mountpt);
1654 sprintf(b,"%s/bbb",mountpt);
1655 sprintf(c,"%s/ccc",mountpt);
1659 yaffs_mount(mountpt);
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);
1677 yaffs_unmount(mountpt);
1678 yaffs_mount(mountpt);
1680 printf("link test done\n");
1683 void handle_test(const char *mountpt)
1690 sprintf(a,"%s/aaa",mountpt);
1694 yaffs_mount(mountpt);
1696 for(cycle = 0; cycle < 5; cycle++){
1697 printf("Start cycle %d\n",cycle);
1700 h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1701 printf("%d handle %d\n",i,h);
1711 yaffs_unmount(mountpt);
1714 void freespace_test(const char *mountpt)
1724 sprintf(a,"%s/aaa",mountpt);
1728 yaffs_mount(mountpt);
1730 f0 = yaffs_freespace(mountpt);
1732 h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1734 for(i = 0; i < 100; i++)
1735 yaffs_write(h,a,100);
1739 f1 = yaffs_freespace(mountpt);
1743 f2 = yaffs_freespace(mountpt);
1746 yaffs_unmount(mountpt);
1747 yaffs_mount(mountpt);
1749 f3 = yaffs_freespace(mountpt);
1751 printf("%d\n%d\n%d\n%d\n",f0, f1,f2,f3);
1756 void simple_rw_test(const char *mountpt)
1765 sprintf(a,"%s/aaa",mountpt);
1769 yaffs_mount(mountpt);
1773 h = yaffs_open(a,O_CREAT| O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1775 for(i = 100000;i < 200000; i++){
1776 result = yaffs_write(h,&i,sizeof(i));
1780 printf("write error\n");
1787 // h = yaffs_open(a,O_RDWR, S_IREAD | S_IWRITE);
1790 yaffs_lseek(h,0,SEEK_SET);
1792 for(i = 100000; i < 200000; i++){
1793 result = yaffs_read(h,&x,sizeof(x));
1795 if(result != 4 || x != i){
1796 printf("read error %d %x %x\n",i,result,x);
1800 printf("Simple rw test passed\n");
1807 void scan_deleted_files_test(const char *mountpt)
1819 sprintf(sub,"%s/sdir",mountpt);
1822 for(j = 0; j < 10; j++)
1824 printf("\n\n>>>>>>> Run %d <<<<<<<<<<<<<\n\n",j);
1825 yaffs_mount(mountpt);
1829 p = (j & 0) ? mountpt: sub;
1831 for(i = 0; i < 100; i++)
1833 sprintf(fn,"%s/%d",p,i);
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);
1846 for(i = 0; i < 10; i++)
1848 sprintf(fn,"%s/%d",p,i);
1856 yaffs_unmount(mountpt);
1865 void write_10k(int h)
1868 const char *s="0123456789";
1869 for(i = 0; i < 1000; i++)
1870 yaffs_write(h,s,10);
1873 void write_200k_file(const char *fn, const char *fdel, const char *fdel1)
1879 h1 = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
1881 for(i = 0; i < 100000; i+= 10000)
1886 offs = yaffs_lseek(h1,0,SEEK_CUR);
1889 printf("Could not write file\n");
1893 for(i = 0; i < 100000; i+= 10000)
1898 offs = yaffs_lseek(h1,0,SEEK_CUR);
1901 printf("Could not write file\n");
1905 yaffs_unlink(fdel1);
1910 void verify_200k_file(const char *fn)
1915 const char *s="0123456789";
1918 h1 = yaffs_open(fn, O_RDONLY, 0);
1920 for(i = 0; i < 200000 && errCount < 10; i+= 10)
1922 yaffs_read(h1,x,10);
1923 if(strncmp(x,s,10) != 0)
1925 printf("File %s verification failed at %d\n",fn,i);
1930 printf("Too many errors... aborted\n");
1937 void check_resize_gc_bug(const char *mountpt)
1946 sprintf(a,"%s/a",mountpt);
1947 sprintf(b,"%s/b",mountpt);
1948 sprintf(c,"%s/c",mountpt);
1954 yaffs_mount(mountpt);
1958 for(i = 0; i < 50; i++)
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);
1973 void multi_mount_test(const char *mountpt,int nmounts)
1981 sprintf(a,"%s/a",mountpt);
1985 for(i = 0; i < nmounts; i++){
1991 static char xx[1000];
1993 printf("############### Iteration %d Start\n",i);
1994 if(1 || i == 0 || i == 5)
1995 yaffs_mount(mountpt);
1997 dump_directory_tree(mountpt);
2002 sprintf(xx,"%s/0",a);
2003 h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2005 sprintf(xx,"%s/1",a);
2006 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2009 for(j = 0; j < 200; j++){
2010 yaffs_write(h0,xx,1000);
2011 yaffs_write(h1,xx,1000);
2014 while(yaffs_write(h0,xx,1000) > 0){
2016 yaffs_write(h1,xx,1000);
2019 len0 = yaffs_lseek(h0,0,SEEK_END);
2020 len1 = yaffs_lseek(h1,0,SEEK_END);
2022 yaffs_lseek(h0,0,SEEK_SET);
2023 yaffs_lseek(h1,0,SEEK_SET);
2025 for(j = 0; j < 200; j++){
2026 yaffs_read(h0,xx,1000);
2027 yaffs_read(h1,xx,1000);
2031 // yaffs_truncate(h0,0);
2035 printf("########### %d\n",i);
2036 dump_directory_tree(mountpt);
2038 if(1 || i == 4 || i == nmounts -1)
2039 yaffs_unmount(mountpt);
2044 void small_mount_test(const char *mountpt,int nmounts)
2058 sprintf(a,"%s/a",mountpt);
2064 for(i = 0; i < nmounts; i++){
2066 static char xx[1000];
2068 printf("############### Iteration %d Start\n",i);
2069 if(1 || i == 0 || i == 5)
2070 yaffs_mount(mountpt);
2072 dump_directory_tree(mountpt);
2076 sprintf(xx,"%s/0",a);
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);
2085 h0 = yaffs_open(xx,O_RDONLY,0);
2087 sprintf(xx,"%s/1",a);
2088 h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
2090 while((nread = yaffs_read(h0,xx,1000)) > 0)
2091 yaffs_write(h1,xx,nread);
2094 len0 = yaffs_lseek(h0,0,SEEK_END);
2095 len1 = yaffs_lseek(h1,0,SEEK_END);
2097 yaffs_lseek(h0,0,SEEK_SET);
2098 yaffs_lseek(h1,0,SEEK_SET);
2100 for(j = 0; j < 200; j++){
2101 yaffs_read(h0,xx,1000);
2102 yaffs_read(h1,xx,1000);
2108 printf("########### %d\n",i);
2109 dump_directory_tree(mountpt);
2111 if(1 || i == 4 || i == nmounts -1)
2112 yaffs_unmount(mountpt);
2119 void small_overwrite_test(const char *mountpt,int nmounts)
2130 sprintf(a,"%s/a",mountpt);
2136 for(i = 0; i < nmounts; i++){
2138 static char xx[8000];
2140 printf("############### Iteration %d Start\n",i);
2142 yaffs_mount(mountpt);
2144 dump_directory_tree(mountpt);
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);
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);
2165 printf("########### %d\n",i);
2166 dump_directory_tree(mountpt);
2169 yaffs_unmount(mountpt);
2174 void seek_overwrite_test(const char *mountpt,int nmounts)
2176 static char xx[5000];
2185 sprintf(a,"%s/f",mountpt);
2189 yaffs_mount(mountpt);
2192 for(i = 0; i < nmounts; i++){
2194 h0 = yaffs_open(a, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
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);
2212 void yaffs_touch(const char *fn)
2214 yaffs_chmod(fn, S_IREAD | S_IWRITE);
2217 void checkpoint_fill_test(const char *mountpt,int nmounts)
2228 sprintf(a,"%s/a",mountpt);
2235 for(i = 0; i < nmounts; i++){
2236 printf("############### Iteration %d Start\n",i);
2237 yaffs_mount(mountpt);
2238 dump_directory_tree(mountpt);
2241 sprintf(b,"%s/zz",a);
2243 h = yaffs_open(b,O_CREAT | O_RDWR,S_IREAD |S_IWRITE);
2246 while(yaffs_write(h,c,50) == 50){}
2250 for(j = 0; j < 2; j++){
2251 printf("touch %d\n",j);
2253 yaffs_unmount(mountpt);
2254 yaffs_mount(mountpt);
2257 dump_directory_tree(mountpt);
2258 yaffs_unmount(mountpt);
2263 int make_file2(const char *name1, const char *name2,int syz)
2273 h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2275 h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
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);
2289 extern void SetCheckpointReservedBlocks(int n);
2291 void checkpoint_upgrade_test(const char *mountpt,int nmounts)
2301 sprintf(a,"%s/a",mountpt);
2306 printf("Create start condition\n");
2308 yaffs_mount(mountpt);
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);
2317 printf("Umount/mount attempt full\n");
2318 yaffs_unmount(mountpt);
2320 yaffs_mount(mountpt);
2322 printf("unlink small file\n");
2324 dump_directory_tree(mountpt);
2326 printf("Umount/mount attempt\n");
2327 yaffs_unmount(mountpt);
2328 yaffs_mount(mountpt);
2330 for(j = 0; j < 500; j++){
2331 printf("***** touch %d\n",j);
2332 dump_directory_tree(mountpt);
2334 yaffs_unmount(mountpt);
2335 yaffs_mount(mountpt);
2338 for(j = 0; j < 500; j++){
2339 printf("***** touch %d\n",j);
2340 dump_directory_tree(mountpt);
2342 yaffs_unmount(mountpt);
2343 yaffs_mount(mountpt);
2347 void huge_array_test(const char *mountpt,int n)
2358 sprintf(a,"mount point %s",mountpt);
2364 yaffs_mount(mountpt);
2369 printf("\n\n START run\n\n");
2370 while((space = yaffs_freespace(mountpt)) > 25000000){
2371 sprintf(a,"%s/file%d",mountpt,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);
2379 printf("\n\n verification/deletion\n\n");
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);
2388 printf("\n\n done \n\n");
2395 void random_write(int h)
2397 static char buffer[12000];
2400 n = random() & 0x1FFF;
2401 yaffs_write(h,buffer,n);
2404 void random_seek(int h)
2407 n = random() & 0xFFFFF;
2408 yaffs_lseek(h,n,SEEK_SET);
2411 void random_truncate(int h, char * name)
2415 n = random() & 0xFFFFF;
2416 flen = yaffs_lseek(h,0,SEEK_END);
2419 yaffs_ftruncate(h,n);
2420 yaffs_lseek(h,n,SEEK_SET);
2424 #define NSMALLFILES 10
2425 void random_small_file_test(const char *mountpt,int iterations)
2428 char a[NSMALLFILES][50];
2439 yaffs_mount(mountpt);
2441 for(i = 0; i < NSMALLFILES; i++){
2446 for(n = 0; n < iterations; n++){
2448 for(i = 0; i < NSMALLFILES; i++) {
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);
2457 printf("Could not open yaffs file %d %d error %d\n",n,i,h[i]);
2467 random_truncate(h[i],a[i]);
2470 case 5: random_seek(h[i]);
2487 for(i = 0; i < NSMALLFILES; i++)
2490 yaffs_unmount(mountpt);
2493 void rmdir_test(const char *mountpt)
2498 yaffs_mount(mountpt);
2500 strcpy(name,mountpt);
2502 strcat(name,"hello");
2503 yaffs_mkdir(name,0666);
2505 yaffs_unmount(mountpt);
2510 static void print_xattrib_val(const char *path, const char *name)
2515 n = yaffs_getxattr(path,name,buffer,sizeof(buffer));
2517 u8 *b = (u8 *)buffer;
2519 printf("%d bytes:",n);
2523 printf("[%02X]",*b);
2529 printf(" Novalue result %d\n",n);
2532 static void list_xattr(const char *path)
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);
2550 void basic_utime_test(const char *mountpt)
2556 struct yaffs_utimbuf utb;
2557 struct yaffs_stat st;
2561 yaffs_mount(mountpt);
2563 strcpy(name,mountpt);
2565 strcat(name,"xfile");
2569 printf("created\n");
2570 h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2572 yaffs_fstat(h,&st); printf(" times %u %u %u\n",st.yst_atime, st.yst_ctime, st.yst_mtime);
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);
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);
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);
2594 void basic_xattr_test(const char *mountpt)
2603 yaffs_mount(mountpt);
2605 strcpy(name,mountpt);
2607 strcat(name,"xfile");
2610 h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2616 printf("Add an attribute\n");
2618 result = yaffs_setxattr(name,"foo",&val1,sizeof(val1),0);
2619 printf("wrote attribute foo: result %d\n",result);
2621 printf("Add an attribute\n");
2623 result = yaffs_setxattr(name,"bar",&val1,sizeof(val1),0);
2624 printf("wrote attribute bar: result %d\n",result);
2627 printf("Get non-existanrt attribute\n");
2628 print_xattrib_val(name,"not here");
2630 printf("Delete non existing attribute\n");
2631 yaffs_removexattr(name,"not here");
2634 printf("Remove foo\n");
2635 yaffs_removexattr(name,"foo");
2638 printf("Remove bar\n");
2639 yaffs_removexattr(name,"bar");
2644 void big_xattr_test(const char *mountpt)
2653 yaffs_mount(mountpt);
2655 strcpy(name,mountpt);
2657 strcat(name,"xfile");
2660 h = yaffs_open(name,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
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);
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);
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);
2687 void dump_dev_stats(struct yaffs_dev *dev, const char * 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);
2698 void test_flash_traffic(const char *mountpt)
2703 struct yaffs_dev *dev;
2705 yaffs_trace_mask = 0;
2709 yaffs_mount(mountpt);
2711 dev = yaffs_getdev(mountpt);
2713 strcpy(name0,mountpt);
2716 strcpy(name1,mountpt);
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");
2728 void link_follow_test(const char *mountpt)
2736 yaffs_trace_mask = 0;
2740 yaffs_mount(mountpt);
2742 sprintf(fn,"%s/file",mountpt);
2743 sprintf(sn,"%s/sym",mountpt);
2744 sprintf(hn,"%s/hl-sym",mountpt);
2746 h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
2747 result = yaffs_close(h);
2749 result = yaffs_symlink(fn,sn);
2750 result = yaffs_link(sn,hn);
2752 h =yaffs_open(hn,O_RDWR,0);
2756 void max_files_test(const char *mountpt)
2765 yaffs_trace_mask = 0;
2769 yaffs_mount(mountpt);
2771 for(i = 0; i < 5000; i++) {
2772 sprintf(fn,"%s/file%d", mountpt, i);
2774 h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
2776 printf("File %s not created\n", fn);
2777 yaffs_write(h,fn,100);
2778 result = yaffs_close(h);
2780 for(i = 0; i < 5; i++){
2781 sprintf(fn,"%s/file%d",mountpt, i);
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);
2790 printf("File %s not created\n", fn);
2791 result = yaffs_close(h);
2794 yaffs_unmount(mountpt);
2796 //h =yaffs_open(hn,O_RDWR,0);
2799 void case_insensitive_test(const char *mountpt)
2805 struct yaffs_stat s;
2809 yaffs_trace_mask = 0;
2813 yaffs_mount(mountpt);
2814 dump_directory_tree(mountpt);
2816 sprintf(fn,"%s/Abc.Txt",mountpt);
2818 h = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE);
2820 ret = yaffs_write(h,fn, strlen(fn) + 1);
2822 ret = yaffs_close(h);
2824 dump_directory_tree(mountpt);
2834 h = yaffs_open(fn2, O_RDONLY, 0);
2835 ret = yaffs_read(h, buffer, 100);
2837 if (ret != strlen(fn) + 1 || memcmp(buffer, fn, ret)){
2838 printf("wrong file read\n");
2840 printf("File %s is the same as file %s\n", fn, fn2);
2843 ret = yaffs_stat(fn2, &s);
2845 printf("renaming\n");
2847 ret = yaffs_rename(fn, fn2);
2848 dump_directory_tree(mountpt);
2852 void start_twice(const char *mountpt)
2854 printf("About to do first yaffs_start\n");
2856 printf("started\n");
2857 printf("First mount returns %d\n", yaffs_mount(mountpt));
2858 printf("About to do second yaffs_start\n");
2860 printf("started\n");
2861 printf("Second mount returns %d\n", yaffs_mount(mountpt));
2864 #define N_WRITES 2000
2867 #define BUFFER_N 1100
2868 unsigned xxbuffer[BUFFER_N];
2871 void set_buffer(int n)
2874 for(i = 0; i < BUFFER_N; i++)
2875 xxbuffer[i] = i + n;
2878 void write_big_sparse_file(int h)
2883 int n = sizeof(xxbuffer);
2886 for(i = 0; i < N_WRITES; i++) {
2887 printf("writing at %lld\n", offset);
2889 pos = yaffs_lseek(h, offset, SEEK_SET);
2891 printf("mismatched seek pos %lld offset %lld\n",
2896 wrote = yaffs_write(h, xxbuffer, n);
2899 printf("mismatched write wrote %d n %d\n", wrote, n);
2903 offset += (STRIDE * sizeof(xxbuffer));
2906 yaffs_ftruncate(h, offset);
2913 void verify_big_sparse_file(int h)
2915 unsigned check_buffer[BUFFER_N];
2919 int n = sizeof(check_buffer);
2921 const char * check_type;
2922 int checks_failed = 0;
2923 int checks_passed = 0;
2925 for(i = 0; i < N_WRITES * STRIDE; i++) {
2927 check_type = "zero";
2928 memset(xxbuffer,0, n);
2930 check_type = "buffer";
2931 set_buffer(i/STRIDE);
2933 //printf("%s checking %lld\n", check_type, offset);
2934 pos = yaffs_lseek(h, offset, SEEK_SET);
2936 printf("mismatched seek pos %lld offset %lld\n",
2941 result = yaffs_read(h, check_buffer, n);
2944 printf("mismatched read result %d n %d\n", result, n);
2951 if(memcmp(xxbuffer, check_buffer, n)) {
2954 printf("buffer at %lld mismatches\n", pos);
2955 printf("xxbuffer ");
2956 for(j = 0; j < 20; j++)
2957 printf(" %d",xxbuffer[j]);
2959 printf("check_buffer ");
2960 for(j = 0; j < 20; j++)
2961 printf(" %d",check_buffer[j]);
2969 offset += sizeof(xxbuffer);
2972 printf("%d checks passed, %d checks failed\n", checks_passed, checks_failed);
2977 void large_file_test(const char *mountpt)
2979 char xx_buffer[1000];
2985 yaffs_trace_mask = 0;
2989 yaffs_mount(mountpt);
2990 printf("mounted\n");
2993 sprintf(fullname, "%s/%s", mountpt, "big-test-file");
2995 handle = yaffs_open(fullname, O_RDONLY, 0);
2997 handle = yaffs_open(fullname, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
3000 perror("opening file");
3004 write_big_sparse_file(handle);
3005 verify_big_sparse_file(handle);
3007 yaffs_close(handle);
3009 printf("Job done\n");
3010 yaffs_unmount(mountpt);
3012 yaffs_mount(mountpt);
3013 printf("mounted again\n");
3015 handle = yaffs_open(fullname, O_RDONLY, 0);
3016 verify_big_sparse_file(handle);
3017 yaffs_unmount(mountpt);
3020 yaffs_mount_common(mountpt, 0, 1);
3021 printf("mounted with no checkpt\n");
3023 handle = yaffs_open(fullname, O_RDONLY, 0);
3024 verify_big_sparse_file(handle);
3025 yaffs_unmount(mountpt);
3027 /* Check resize by adding to the end, resizing back and verifying. */
3028 yaffs_mount_common(mountpt, 0, 1);
3029 printf("checking resize\n");
3031 handle = yaffs_open(fullname, O_RDWR, 0);
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);
3039 verify_big_sparse_file(handle);
3040 yaffs_unmount(mountpt);
3045 int mk_dir(const char *mp, const char *name)
3047 char full_name[100];
3049 sprintf(full_name, "%s/%s", mp, name);
3051 return yaffs_mkdir(full_name, S_IREAD| S_IWRITE);
3054 int mk_file(const char *mp, const char *name)
3056 char full_name[100];
3059 sprintf(full_name, "%s/%s", mp, name);
3061 h = yaffs_open(full_name, O_RDWR | O_CREAT | O_TRUNC, S_IREAD| S_IWRITE);
3063 yaffs_write(h, name, strlen(name));
3069 void xx_test(const char *mountpt)
3071 char xx_buffer[1000];
3075 yaffs_format(mountpt,0,0,0);
3077 yaffs_mount(mountpt);
3078 printf("mounted\n");
3081 printf("create files\n");
3083 mk_dir(mountpt, "foo");
3084 mk_file(mountpt, "foo/f1");
3085 mk_file(mountpt, "foo/f2");
3086 mk_file(mountpt, "foo/f3");
3087 mk_file(mountpt, "foo/f4");
3088 dump_directory_tree(mountpt);
3090 printf("unmount and remount\n");
3092 /* Unmount/remount */
3093 yaffs_unmount(mountpt);
3094 yaffs_mount(mountpt);
3095 dump_directory_tree(mountpt);
3098 void yy_test(const char *mountpt)
3100 char xx_buffer[1000];
3104 yaffs_mount(mountpt);
3105 dump_directory_tree(mountpt);
3109 void readdir_test(const char *mountpt)
3111 char xx_buffer[1000];
3116 yaffs_DIR *dirs[100];
3119 yaffs_trace_mask = 0;
3123 yaffs_mount(mountpt);
3125 for(i = 0; i < 100; i++) {
3126 dirs[i] = yaffs_opendir(mountpt);
3127 printf("%2d %p,", i, dirs[i]);
3132 for(i = 0; i < 100; i++) {
3134 yaffs_closedir(dirs[i]);
3138 for(i = 0; i < 100; i++) {
3139 dirs[i] = yaffs_opendir(mountpt);
3140 printf("%2d %p,", i, dirs[i]);
3143 yaffs_unmount(mountpt);
3148 void format_test(const char *mountpt)
3154 ret = yaffs_format(mountpt, 0, 0, 0);
3155 printf("yaffs_format(...,0, 0, 0) of unmounted returned %d\n", ret);
3157 yaffs_mount(mountpt);
3159 ret = yaffs_format(mountpt, 0, 0, 0);
3160 printf("yaffs_format(...,0, 0, 0) of mounted returned %d\n", ret);
3162 ret = yaffs_format(mountpt, 1, 0, 0);
3163 printf("yaffs_format(...,1, 0, 0) of mounted returned %d\n", ret);
3165 ret = yaffs_mount(mountpt);
3166 printf("mount should return 0 returned %d\n", ret);
3168 ret = yaffs_format(mountpt, 1, 0, 1);
3169 printf("yaffs_format(...,1, 0, 1) of mounted returned %d\n", ret);
3171 ret = yaffs_mount(mountpt);
3172 printf("mount should return -1 returned %d\n", ret);
3175 void dir_rename_test(const char *mountpt)
3183 yaffs_mount(mountpt);
3185 sprintf(fname,"%s/file",mountpt);
3186 sprintf(dname,"%s/directory",mountpt);
3188 h = yaffs_open(fname,O_CREAT | O_RDWR | O_TRUNC, 0666);
3191 yaffs_mkdir(dname, 0666);
3193 dump_directory_tree(mountpt);
3195 printf("Try to rename %s to %s\n", fname, dname);
3196 ret = yaffs_rename(fname, dname);
3197 printf("result %d, %d\n", ret, yaffs_get_error());
3199 printf("Try to rename %s to %s\n", dname, fname);
3200 ret = yaffs_rename(dname, fname);
3201 printf("result %d, %d\n", ret, yaffs_get_error());
3207 int simulate_power_failure;
3209 int main(int argc, char *argv[])
3211 random_seed = time(NULL);
3212 //return long_test(argc,argv);
3214 //return cache_read_test();
3216 // resize_stress_test_no_grow("/flash/flash",20);
3217 //root_perm_remount("/flash/flash");
3219 //huge_directory_test_on_path("/ram2k");
3221 //yaffs_backward_scan_test("/flash/flash");
3222 // yaffs_device_flush_test("/flash/flash");
3224 //rename_over_test("//////////////////flash///////////////////yaffs1///////////");
3226 //fill_empty_files_test("/yaffs2/");
3227 //resize_stress_test("/yaffs2");
3228 //overwrite_test("/yaffs2");
3230 //long_name_test("/yaffs2");
3231 //link_test0("/yaffs2");
3232 //link_test1("yaffs2");
3233 //scan_pattern_test("/flash",10000,10);
3234 //short_scan_test("/flash/flash",40000,200);
3235 //small_mount_test("/flash/flash",1000);
3236 //small_overwrite_test("/flash/flash",1000);
3237 //seek_overwrite_test("/flash/flash",1000);
3238 //checkpoint_fill_test("/flash/flash",20);
3239 //checkpoint_upgrade_test("/flash/flash",20);
3240 //small_overwrite_test("/flash/flash",1000);
3241 //checkpoint_fill_test("/flash/flash",20);
3242 //random_small_file_test("/flash/flash",10000);
3243 // huge_array_test("/flash/flash",10);
3246 // handle_test("yaffs2/");
3248 //long_test_on_path("/ram2k");
3249 // long_test_on_path("/flash");
3250 //simple_rw_test("/flash/flash");
3251 //fill_disk_test("/flash/flash");
3252 // rename_over_test("/flash");
3253 //lookup_test("/flash");
3254 //freespace_test("/flash/flash");
3256 //link_test("/flash/flash");
3258 // cache_bypass_bug_test();
3260 //free_space_check();
3262 //check_resize_gc_bug("/flash");
3264 //basic_xattr_test("/yaffs2");
3265 //big_xattr_test("/yaffs2");
3267 //null_name_test("yaffs2");
3269 //test_flash_traffic("yaffs2");
3270 // link_follow_test("/yaffs2");
3271 //basic_utime_test("/yaffs2");
3274 //format_test("/yaffs2");
3276 //max_files_test("/yaffs2");
3278 //start_twice("/yaffs2");
3280 //large_file_test("/yaffs2");
3281 //readdir_test("/yaffs2");
3283 //basic_utime_test("/yaffs2");
3284 //case_insensitive_test("/yaffs2");
3286 //yy_test("/yaffs2");
3287 dir_rename_test("/yaffs2");