*** empty log message ***
[yaffs/.git] / direct / dtest.c
1 /*
2 * Test code for the "direct" interface. 
3 */
4
5
6 #include <stdio.h>
7 #include <string.h>
8
9 #include "yaffsfs.h"
10
11 char xx[600];
12
13 void copy_in_a_file(char *yaffsName,char *inName)
14 {
15         int inh,outh;
16         unsigned char buffer[100];
17         int ni,no;
18         inh = open(inName,O_RDONLY);
19         outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
20         
21         while((ni = read(inh,buffer,100)) > 0)
22         {
23                 no = yaffs_write(outh,buffer,ni);
24                 if(ni != no)
25                 {
26                         printf("problem writing yaffs file\n");
27                 }
28                 
29         }
30         
31         yaffs_close(outh);
32         close(inh);
33 }
34
35 void make_a_file(char *yaffsName,char bval,int sizeOfFile)
36 {
37         int outh;
38         int i;
39         unsigned char buffer[100];
40
41         outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
42         
43         memset(buffer,bval,100);
44         
45         do{
46                 i = sizeOfFile;
47                 if(i > 100) i = 100;
48                 sizeOfFile -= i;
49                 
50                 yaffs_write(outh,buffer,i);
51                 
52         } while (sizeOfFile > 0);
53         
54                 
55         yaffs_close(outh);
56
57 }
58
59
60
61
62 void fill_disk(char *path,int nfiles)
63 {
64         int h;
65         int n;
66         int result;
67         
68         char str[50];
69         
70         for(n = 0; n < nfiles; n++)
71         {
72                 sprintf(str,"%s/%d",path,n);
73                 
74                 h = yaffs_open(str, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
75                 
76                 printf("writing file %s handle %d ",str, h);
77                 
78                 while ((result = yaffs_write(h,xx,600)) == 600)
79                 {
80                         //printf(".");
81                 }
82                 result = yaffs_close(h);
83                 printf(" close %d\n",result);
84         }
85 }
86
87 void fill_disk_and_delete(char *path, int nfiles, int ncycles)
88 {
89         int i,j;
90         char str[50];
91         int result;
92         
93         for(i = 0; i < ncycles; i++)
94         {
95                 printf("@@@@@@@@@@@@@@ cycle %d\n",i);
96                 fill_disk(path,nfiles);
97                 
98                 for(j = 0; j < nfiles; j++)
99                 {
100                         sprintf(str,"%s/%d",path,j);
101                         result = yaffs_unlink(str);
102                         printf("unlinking file %s, result %d\n",str,result);
103                 }
104         }
105 }
106
107
108 void fill_files(char *path,int flags, int maxIterations,int siz)
109 {
110         int i;
111         int j;
112         char str[50];
113         int h;
114         
115         i = 0;
116         
117         do{
118                 sprintf(str,"%s/%d",path,i);
119                 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
120                 yaffs_close(h);
121
122                 if(h >= 0)
123                 {
124                         for(j = 0; j < siz; j++)
125                         {
126                                 yaffs_write(h,str,1);
127                         }
128                 }
129                 
130                 if( flags & 1)
131                 {
132                         yaffs_unlink(str);
133                 }
134                 i++;
135         } while(h >= 0 && i < maxIterations);
136         
137         if(flags & 2)
138         {
139                 i = 0;
140                 do{
141                         sprintf(str,"%s/%d",path,i);
142                         printf("unlink %s\n",str);
143                         i++;
144                 } while(yaffs_unlink(str) >= 0);
145         }
146 }
147
148 void leave_unlinked_file(char *path,int maxIterations,int siz)
149 {
150         int i;
151         char str[50];
152         int h;
153         
154         i = 0;
155         
156         do{
157                 sprintf(str,"%s/%d",path,i);
158                 printf("create %s\n",str);
159                 h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
160                 if(h >= 0)
161                 {
162                         yaffs_unlink(str);
163                 }
164                 i++;
165         } while(h < 0 && i < maxIterations);
166         
167         if(h >= 0)
168         {
169                 for(i = 0; i < siz; i++)
170                 {
171                         yaffs_write(h,str,1);
172                 }
173         }
174         
175         printf("Leaving file %s open\n",str);
176
177 }
178
179 void dumpDirFollow(const char *dname)
180 {
181         yaffs_DIR *d;
182         yaffs_dirent *de;
183         struct yaffs_stat s;
184         char str[100];
185                         
186         d = yaffs_opendir(dname);
187         
188         if(!d)
189         {
190                 printf("opendir failed\n");
191         }
192         else
193         {
194                 while((de = yaffs_readdir(d)) != NULL)
195                 {
196                         sprintf(str,"%s/%s",dname,de->d_name);
197                         
198                         yaffs_stat(str,&s);
199                         
200                         printf("%s length %d mode %X ",de->d_name,s.st_size,s.st_mode);
201                         switch(s.st_mode & S_IFMT)
202                         {
203                                 case S_IFREG: printf("data file"); break;
204                                 case S_IFDIR: printf("directory"); break;
205                                 case S_IFLNK: printf("symlink -->");
206                                                           if(yaffs_readlink(str,str,100) < 0)
207                                                                 printf("no alias");
208                                                           else
209                                                                 printf("\"%s\"",str);    
210                                                           break;
211                                 default: printf("unknown"); break;
212                         }
213                         
214                         printf("\n");           
215                 }
216                 
217                 yaffs_closedir(d);
218         }
219         printf("\n");
220         
221         printf("Free space in %s is %d\n\n",dname,yaffs_freespace(dname));
222
223 }
224 void dumpDir(const char *dname)
225 {
226         yaffs_DIR *d;
227         yaffs_dirent *de;
228         struct yaffs_stat s;
229         char str[100];
230                         
231         d = yaffs_opendir(dname);
232         
233         if(!d)
234         {
235                 printf("opendir failed\n");
236         }
237         else
238         {
239                 while((de = yaffs_readdir(d)) != NULL)
240                 {
241                         sprintf(str,"%s/%s",dname,de->d_name);
242                         
243                         yaffs_lstat(str,&s);
244                         
245                         printf("%s length %d mode %X ",de->d_name,s.st_size,s.st_mode);
246                         switch(s.st_mode & S_IFMT)
247                         {
248                                 case S_IFREG: printf("data file"); break;
249                                 case S_IFDIR: printf("directory"); break;
250                                 case S_IFLNK: printf("symlink -->");
251                                                           if(yaffs_readlink(str,str,100) < 0)
252                                                                 printf("no alias");
253                                                           else
254                                                                 printf("\"%s\"",str);    
255                                                           break;
256                                 default: printf("unknown"); break;
257                         }
258                         
259                         printf("\n");           
260                 }
261                 
262                 yaffs_closedir(d);
263         }
264         printf("\n");
265         
266         printf("Free space in %s is %d\n\n",dname,yaffs_freespace(dname));
267
268 }
269
270
271 static void PermissionsCheck(const char *path, mode_t tmode, int tflags,int expectedResult)
272 {
273         int fd;
274         
275         if(yaffs_chmod(path,tmode)< 0) printf("chmod failed\n");
276         
277         fd = yaffs_open(path,tflags,0);
278         
279         if((fd >= 0) != (expectedResult > 0))
280         {
281                 printf("Permissions check %x %x %d failed\n",tmode,tflags,expectedResult);
282         }
283         else
284         {
285                 printf("Permissions check %x %x %d OK\n",tmode,tflags,expectedResult);
286         }
287         
288         
289         yaffs_close(fd);
290         
291         
292 }
293
294 int long_test(int argc, char *argv[])
295 {
296
297         int f;
298         int r;
299         char buffer[20];
300         
301         char str[100];
302         
303         int h;
304         mode_t temp_mode;
305         struct yaffs_stat ystat;
306         
307         yaffs_StartUp();
308         
309         yaffs_mount("/boot");
310         yaffs_mount("/data");
311         yaffs_mount("/flash");
312         yaffs_mount("/ram");
313         
314         printf("\nDirectory look-up of /boot\n");
315         dumpDir("/boot");
316         printf("\nDirectory look-up of /data\n");
317         dumpDir("/data");
318         printf("\nDirectory look-up of /flash\n");
319         dumpDir("/flash");
320
321         //leave_unlinked_file("/flash",20000,0);
322         //leave_unlinked_file("/data",20000,0);
323         
324         leave_unlinked_file("/ram",20,0);
325         
326
327         f = yaffs_open("/boot/b1", O_RDONLY,0);
328         
329         printf("open /boot/b1 readonly, f=%d\n",f);
330         
331         f = yaffs_open("/boot/b1", O_CREAT,S_IREAD | S_IWRITE);
332         
333         printf("open /boot/b1 O_CREAT, f=%d\n",f);
334         
335         
336         r = yaffs_write(f,"hello",1);
337         printf("write %d attempted to write to a read-only file\n",r);
338         
339         r = yaffs_close(f);
340         
341         printf("close %d\n",r);
342
343         f = yaffs_open("/boot/b1", O_RDWR,0);
344         
345         printf("open /boot/b1 O_RDWR,f=%d\n",f);
346         
347         
348         r = yaffs_write(f,"hello",2);
349         printf("write %d attempted to write to a writeable file\n",r);
350         r = yaffs_write(f,"world",3);
351         printf("write %d attempted to write to a writeable file\n",r);
352         
353         r= yaffs_lseek(f,0,SEEK_END);
354         printf("seek end %d\n",r);
355         memset(buffer,0,20);
356         r = yaffs_read(f,buffer,10);
357         printf("read %d \"%s\"\n",r,buffer);
358         r= yaffs_lseek(f,0,SEEK_SET);
359         printf("seek set %d\n",r);
360         memset(buffer,0,20);
361         r = yaffs_read(f,buffer,10);
362         printf("read %d \"%s\"\n",r,buffer);
363         memset(buffer,0,20);
364         r = yaffs_read(f,buffer,10);
365         printf("read %d \"%s\"\n",r,buffer);
366
367         // Check values reading at end.
368         // A read past end of file should return 0 for 0 bytes read.
369                 
370         r= yaffs_lseek(f,0,SEEK_END);
371         r = yaffs_read(f,buffer,10);
372         printf("read at end returned  %d\n",r); 
373         r= yaffs_lseek(f,500,SEEK_END);
374         r = yaffs_read(f,buffer,10);
375         printf("read past end returned  %d\n",r);       
376         
377         r = yaffs_close(f);
378         
379         printf("close %d\n",r);
380         
381         copy_in_a_file("/boot/yyfile","xxx");
382         
383         // Create a file with a long name
384         
385         copy_in_a_file("/boot/file with a long name","xxx");
386         
387         
388         printf("\nDirectory look-up of /boot\n");
389         dumpDir("/boot");
390
391         // Check stat
392         r = yaffs_stat("/boot/file with a long name",&ystat);
393         
394         // Check rename
395         
396         r = yaffs_rename("/boot/file with a long name","/boot/r1");
397         
398         printf("\nDirectory look-up of /boot\n");
399         dumpDir("/boot");
400         
401         // Check unlink
402         r = yaffs_unlink("/boot/r1");
403         
404         printf("\nDirectory look-up of /boot\n");
405         dumpDir("/boot");
406
407         // Check mkdir
408         
409         r = yaffs_mkdir("/boot/directory1",0);
410         
411         printf("\nDirectory look-up of /boot\n");
412         dumpDir("/boot");
413         printf("\nDirectory look-up of /boot/directory1\n");
414         dumpDir("/boot/directory1");
415
416         // add a file to the directory                  
417         copy_in_a_file("/boot/directory1/file with a long name","xxx");
418         
419         printf("\nDirectory look-up of /boot\n");
420         dumpDir("/boot");
421         printf("\nDirectory look-up of /boot/directory1\n");
422         dumpDir("/boot/directory1");
423         
424         //  Attempt to delete directory (should fail)
425         
426         r = yaffs_rmdir("/boot/directory1");
427         
428         printf("\nDirectory look-up of /boot\n");
429         dumpDir("/boot");
430         printf("\nDirectory look-up of /boot/directory1\n");
431         dumpDir("/boot/directory1");
432         
433         // Delete file first, then rmdir should work
434         r = yaffs_unlink("/boot/directory1/file with a long name");
435         r = yaffs_rmdir("/boot/directory1");
436         
437         
438         printf("\nDirectory look-up of /boot\n");
439         dumpDir("/boot");
440         printf("\nDirectory look-up of /boot/directory1\n");
441         dumpDir("/boot/directory1");
442
443 #if 0
444         fill_disk_and_delete("/boot",20,20);
445                         
446         printf("\nDirectory look-up of /boot\n");
447         dumpDir("/boot");
448 #endif
449
450         yaffs_symlink("yyfile","/boot/slink");
451         
452         yaffs_readlink("/boot/slink",str,100);
453         printf("symlink alias is %s\n",str);
454         
455         
456         
457         
458         printf("\nDirectory look-up of /boot\n");
459         dumpDir("/boot");
460         printf("\nDirectory look-up of /boot (using stat instead of lstat)\n");
461         dumpDirFollow("/boot");
462         printf("\nDirectory look-up of /boot/directory1\n");
463         dumpDir("/boot/directory1");
464
465         h = yaffs_open("/boot/slink",O_RDWR,0);
466         
467         printf("file length is %d\n",yaffs_lseek(h,0,SEEK_END));
468         
469         yaffs_close(h);
470         
471         yaffs_unlink("/boot/slink");
472
473         
474         printf("\nDirectory look-up of /boot\n");
475         dumpDir("/boot");
476         
477         // Check chmod
478         
479         yaffs_stat("/boot/yyfile",&ystat);
480         temp_mode = ystat.st_mode;
481         
482         yaffs_chmod("/boot/yyfile",0x55555);
483         printf("\nDirectory look-up of /boot\n");
484         dumpDir("/boot");
485         
486         yaffs_chmod("/boot/yyfile",temp_mode);
487         printf("\nDirectory look-up of /boot\n");
488         dumpDir("/boot");
489         
490         // Permission checks...
491         PermissionsCheck("/boot/yyfile",0, O_WRONLY,0);
492         PermissionsCheck("/boot/yyfile",0, O_RDONLY,0);
493         PermissionsCheck("/boot/yyfile",0, O_RDWR,0);
494
495         PermissionsCheck("/boot/yyfile",S_IREAD, O_WRONLY,0);
496         PermissionsCheck("/boot/yyfile",S_IREAD, O_RDONLY,1);
497         PermissionsCheck("/boot/yyfile",S_IREAD, O_RDWR,0);
498
499         PermissionsCheck("/boot/yyfile",S_IWRITE, O_WRONLY,1);
500         PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDONLY,0);
501         PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDWR,0);
502         
503         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_WRONLY,1);
504         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDONLY,1);
505         PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDWR,1);
506
507         yaffs_chmod("/boot/yyfile",temp_mode);
508         
509         //create a zero-length file and unlink it (test for scan bug)
510         
511         h = yaffs_open("/boot/zlf",O_CREAT | O_TRUNC | O_RDWR,0);
512         yaffs_close(h);
513         
514         yaffs_unlink("/boot/zlf");
515         
516         
517         yaffs_DumpDevStruct("/boot");
518         
519         fill_disk_and_delete("/boot",20,20);
520         
521         yaffs_DumpDevStruct("/boot");
522         
523         fill_files("/boot",1,10000,0);
524         fill_files("/boot",1,10000,5000);
525         fill_files("/boot",2,10000,0);
526         fill_files("/boot",2,10000,5000);
527         
528         leave_unlinked_file("/data",20000,0);
529         leave_unlinked_file("/data",20000,5000);
530         leave_unlinked_file("/data",20000,5000);
531         leave_unlinked_file("/data",20000,5000);
532         leave_unlinked_file("/data",20000,5000);
533         leave_unlinked_file("/data",20000,5000);
534         
535         yaffs_DumpDevStruct("/boot");
536         yaffs_DumpDevStruct("/data");
537         
538                 
539                 
540         return 0;
541
542 }
543
544
545
546 int directory_rename_test(void)
547 {
548         int r;
549         yaffs_StartUp();
550         
551         yaffs_mount("/ram");
552         yaffs_mkdir("/ram/a",0);
553         yaffs_mkdir("/ram/a/b",0);
554         yaffs_mkdir("/ram/c",0);
555         
556         printf("\nDirectory look-up of /ram\n");
557         dumpDir("/ram");
558         dumpDir("/ram/a");
559         dumpDir("/ram/a/b");
560
561         printf("Do rename (should fail)\n");
562                 
563         r = yaffs_rename("/ram/a","/ram/a/b/d");
564         printf("\nDirectory look-up of /ram\n");
565         dumpDir("/ram");
566         dumpDir("/ram/a");
567         dumpDir("/ram/a/b");
568
569         printf("Do rename (should not fail)\n");
570                 
571         r = yaffs_rename("/ram/c","/ram/a/b/d");
572         printf("\nDirectory look-up of /ram\n");
573         dumpDir("/ram");
574         dumpDir("/ram/a");
575         dumpDir("/ram/a/b");
576         
577         
578         return 1;
579         
580 }
581
582 int cache_read_test(void)
583 {
584         int a,b,c;
585         int i;
586         int sizeOfFiles = 500000;
587         char buffer[100];
588         
589         yaffs_StartUp();
590         
591         yaffs_mount("/boot");
592         
593         make_a_file("/boot/a",'a',sizeOfFiles);
594         make_a_file("/boot/b",'b',sizeOfFiles);
595
596         a = yaffs_open("/boot/a",O_RDONLY,0);
597         b = yaffs_open("/boot/b",O_RDONLY,0);
598         c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
599
600         do{
601                 i = sizeOfFiles;
602                 if (i > 100) i = 100;
603                 sizeOfFiles  -= i;
604                 yaffs_read(a,buffer,i);
605                 yaffs_read(b,buffer,i);
606                 yaffs_write(c,buffer,i);
607         } while(sizeOfFiles > 0);
608         
609         
610         
611         return 1;
612         
613 }
614
615 int cache_bypass_bug_test(void)
616 {
617         // This test reporoduces a bug whereby YAFFS caching is buypassed
618         // resulting in erroneous reads after writes.
619         int a;
620         int i;
621         char buffer1[1000];
622         char buffer2[1000];
623         
624         memset(buffer1,0,sizeof(buffer1));
625         memset(buffer2,0,sizeof(buffer2));
626                 
627         yaffs_StartUp();
628         
629         yaffs_mount("/boot");
630         
631         // Create a file of 2000 bytes.
632         make_a_file("/boot/a",'X',2000);
633
634         a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE);
635         
636         // Write a short sequence to the file.
637         // This will go into the cache.
638         yaffs_lseek(a,0,SEEK_SET);
639         yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20); 
640
641         // Read a short sequence from the file.
642         // This will come from the cache.
643         yaffs_lseek(a,0,SEEK_SET);
644         yaffs_read(a,buffer1,30); 
645
646         // Read a page size sequence from the file.
647         yaffs_lseek(a,0,SEEK_SET);
648         yaffs_read(a,buffer2,512); 
649         
650         printf("buffer 1 %s\n",buffer1);
651         printf("buffer 2 %s\n",buffer2);
652         
653         if(strncmp(buffer1,buffer2,20))
654         {
655                 printf("Cache bypass bug detected!!!!!\n");
656         }
657         
658         
659         return 1;
660 }
661
662
663
664 int main(int argc, char *argv[])
665 {
666         //return long_test(argc,argv);
667         
668         //return cache_read_test();
669         
670         return cache_bypass_bug_test();
671         
672 }