*** empty log message ***
[yaffs/.git] / yaffsdev.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
3  * yaffsdev.c
4  *
5  * Copyright (C) 2002 Aleph One Ltd.
6  *   for Toby Churchill Ltd and Brightstar Engineering
7  *
8  * Created by Charles Manning <charles@aleph1.co.uk>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  */
15  
16 #include "yaffsinterface.h"
17 #include "yportenv.h"
18
19 #if YAFFS_FILEEM        
20 #include "yaffs_fileem.h"
21 #else
22 #include "yaffs_nandemul.h" 
23 #endif
24
25 #include "yaffs_guts.h"
26 #include <stdlib.h>
27
28 #include <stdio.h>
29 #include <string.h>
30
31
32 yaffs_Device device;
33
34
35 char *testStr = "this is a test string";
36
37 char *testStr2 = "abcdefghijklmnopqrstuvwxyz1234567890";
38
39 void TestTimexxx(yaffs_Device *dev)
40 {
41         yaffs_Object *f;
42         int x;
43         
44         
45         printf("Start\n");
46         
47
48         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
49         if(f)
50         {
51                 printf("Found\n");
52         }
53         else
54         {
55                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
56                 printf("Created\n");
57         }
58         
59         
60         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
61                 
62 }
63
64
65 void TestTimeasasas(yaffs_Device *dev)
66 {
67         yaffs_Object *f; 
68         int x;
69         int i;
70         int b;
71         char data[200];
72         int written;
73         
74         
75         printf("Start\n");
76         
77
78         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
79         if(f)
80         {
81                 printf("Found\n");
82         }
83         else
84         {
85                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
86                 printf("Created\n");
87         }
88         
89         
90         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
91         
92         
93         
94         for(i = 0; i < 10000; i+=20)
95         {
96         
97                 b++;
98                 if(b & 1)
99                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
100                 else
101                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
102         }
103         
104         
105         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
106         
107         printf("Flush\n");
108         
109         yaffs_FlushFile(f);
110
111         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
112         
113         yaffs_ReadDataFromFile(f,data,1000,50);
114         data[50] = 0;
115         
116         printf("Read data is \"%s\"\n",data);
117         
118         yaffs_DumpObject(f);
119
120         printf("Resize to 3000\n");     
121         yaffs_ResizeFile(f,3000);
122         printf("Resize to 2048\n");     
123         yaffs_ResizeFile(f,2048);
124         
125         yaffs_DumpObject(f);
126
127         yaffs_FlushFile(f);
128         
129         
130                 
131
132 }
133
134 void TestTimeBigDeletes(yaffs_Device *dev)
135 {
136         yaffs_Object *f;
137         yaffs_Object *sl;
138         yaffs_Object *lnf;
139         
140         yaffs_Object *hl1;
141         yaffs_Object *hl2;
142         yaffs_Object *hl3;
143         yaffs_Object *d, *df;
144         
145         int x;
146         int i;
147         int b;
148         char data[200];
149         
150         char * alias;
151         int written;
152         
153         
154         printf("Exisiting objects\n");
155         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
156         printf("Exisiting objects in lost+found\n");
157         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
158         yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
159
160         printf("Start\n");
161         
162         
163
164         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
165         if(f)
166         {
167                 printf("Found\n");
168         }
169         else
170         {
171                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
172                 printf("Created\n");
173         }
174         
175         for(i = 0; i < 100000; i+=20)
176         { 
177         
178                 b++;
179                 if(b & 1)
180                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
181                 else
182                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
183         }
184         
185         yaffs_FlushFile(f);
186         yaffs_DeleteFile(f);
187
188         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
189         if(f)
190         {
191                 printf("Found\n");
192         }
193         else
194         {
195                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
196                 printf("Created\n");
197         }
198         
199         for(i = 0; i < 100000; i+=20)
200         { 
201         
202                 b++;
203                 if(b & 1)
204                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
205                 else
206                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
207         }
208         
209         yaffs_FlushFile(f);
210         yaffs_DeleteFile(f);
211
212         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
213         if(f)
214         {
215                 printf("Found\n");
216         }
217         else
218         {
219                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
220                 printf("Created\n");
221         }
222         
223         for(i = 0; i < 100000; i+=20)
224         { 
225         
226                 b++;
227                 if(b & 1)
228                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
229                 else
230                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
231         }
232         
233         yaffs_FlushFile(f);
234         yaffs_DeleteFile(f);
235         
236 }
237
238 void TestTime(yaffs_Device *dev)
239 {
240         yaffs_Object *f;
241         yaffs_Object *sl;
242         yaffs_Object *lnf;
243         
244         yaffs_Object *hl1;
245         yaffs_Object *hl2;
246         yaffs_Object *hl3;
247         yaffs_Object *d, *df;
248         
249         int x;
250         int i;
251         int b;
252         char data[200];
253         
254         char * alias;
255         int written;
256         
257         
258         printf("Exisiting objects\n");
259         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
260         printf("Exisiting objects in lost+found\n");
261         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
262         yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
263
264         printf("Start\n");
265         
266         
267         // Test the problem of:
268         // Create file
269         // Delete file
270         // Create file with same name
271         // Delete file <== crash
272
273         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
274         if(f)
275         {
276                 printf("Found\n");
277         }
278         else
279         {
280                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
281                 printf("Created\n");
282         }
283         yaffs_Unlink(yaffs_Root(dev),"Name1");
284
285
286         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
287         if(f)
288         {
289                 printf("Found\n");
290         }
291         else
292         {
293                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
294                 printf("Created\n");
295         }
296         yaffs_Unlink(yaffs_Root(dev),"Name1");
297         
298         
299         
300         // Other tests
301         
302         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
303         if(f)
304         {
305                 printf("Found\n");
306         }
307         else
308         {
309                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
310                 printf("Created\n");
311         }
312         
313         
314         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
315         
316         for(i = 0; i < 100000; i+=64)
317         { 
318         
319                 b++;
320                 if(b & 1)
321                         written = yaffs_WriteDataToFile(f,testStr,i,64);
322                 else
323                         written = yaffs_WriteDataToFile(f,testStr2,i,64);
324                 
325                 written = yaffs_WriteDataToFile(f,testStr2,1,20);               
326                 
327         }
328         // some short reads
329         for(i = 1000; i < 50000; i+=2)
330         { 
331                 yaffs_ReadDataFromFile(f,data,i,20);
332         }
333         
334                 
335         yaffs_ReadDataFromFile(f,data,1000,50); 
336         data[50] = 0;
337         
338         printf("Read data is \"%s\"\n",data);
339
340         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
341         yaffs_ReadDataFromFile(f,data,1000,50);
342         data[50] = 0;
343         
344         printf("Read data is \"%s\"\n",data);
345         
346         printf("Flush\n");
347         
348         yaffs_FlushFile(f);
349         yaffs_ReadDataFromFile(f,data,1000,50);
350         data[50] = 0;
351         
352         printf("Read data is \"%s\"\n",data);
353         
354         printf("File length is %d\n",yaffs_GetObjectFileLength(f));
355         
356         sl = yaffs_MknodSymLink(yaffs_Root(dev),"sym-link",0,0,0,"/tmp/alias");
357         yaffs_ReadDataFromFile(f,data,1000,50);
358         data[50] = 0;
359         
360         printf("Read data is \"%s\"\n",data);
361
362
363         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
364         
365         printf("\n\nsymlink alias is \"%s\"\n",alias = yaffs_GetSymlinkAlias(sl));
366         
367         free(alias);
368         
369         printf("Unlink symlink %d\n",yaffs_Unlink(yaffs_Root(dev),"sym-link"));
370         
371         
372         yaffs_ReadDataFromFile(f,data,1000,50);
373         data[50] = 0;
374         
375         printf("Read data is \"%s\"\n",data);
376         
377         yaffs_DumpObject(f);
378
379         printf("Resize 3000\n");        
380         yaffs_ResizeFile(f,3000);
381
382         printf("Resize 2050\n");        
383         yaffs_ResizeFile(f,2050);
384         printf("Resize 2049\n");        
385         yaffs_ResizeFile(f,2049);
386         printf("Resize 2048\n");        
387         yaffs_ResizeFile(f,2048);
388
389
390         printf("Resize 2000\n");        
391         yaffs_ResizeFile(f,2000);
392         
393         yaffs_DumpObject(f);
394         
395         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
396         
397         
398
399         yaffs_FlushFile(f);
400                 
401
402         printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
403         
404         yaffs_DeleteFile(f);
405         
406         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
407         
408         // Create a directory and play with it
409         
410
411         printf("Find or Create directory and play with it\n");
412         d =  yaffs_FindObjectByName(yaffs_Root(dev),"direct");
413         if(!d)
414         {
415                 d = yaffs_MknodDirectory(yaffs_Root(dev),"direct",0,0,0);
416         }
417         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
418         yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject);
419         
420         printf("Make file in directory\n");
421         
422         df = yaffs_MknodFile(d,"file-in-directory",0,0,0);
423         yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject);
424         
425         
426         // Do some stuff with hardlinks
427         //
428         // NB Deleting hardlinked objects can mess up pointers to hardlinks.
429         // The mechanism is as follows:
430         // * If you unlink a file,softlink or directory that has one or more hardlinks,
431         // then the object is renamed to one of the hardlinks and that hardlink is unlinked.
432         // This means that a pointer to a hardlink so deleted will point to an invalid address.
433         // Thus, make sure that pointers to hardlinks are immediately dereferenced.
434
435
436         printf("Hard link tests\n");
437                 
438         f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
439         hl1 = yaffs_Link(yaffs_Root(dev),"HardLink 1",f);
440         hl2 = yaffs_Link(yaffs_Root(dev),"HardLink 2",f);
441         hl3 = yaffs_Link(yaffs_Root(dev),"HardLink 3",hl2);
442
443         printf("\n\nHard links created\n");
444         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
445         
446         yaffs_Unlink(yaffs_Root(dev),"HardLink 1");
447         printf("\n\nHard link deleted\n");
448         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
449         
450         yaffs_Unlink(yaffs_Root(dev),"Name1");
451         printf("\n\nHard linked file deleted\n");
452         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
453         
454         yaffs_Unlink(yaffs_Root(dev),"HardLink 2");
455         printf("\n\nHard link 2 deleted\n");
456         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
457         
458         yaffs_Unlink(yaffs_Root(dev),"HardLink 3");
459
460         printf("\n\nHard link 3 deleted\n");
461         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
462         
463         // NB We don't allow unlinking or rename of the root or lost+found
464         // We allow setting attributes, but these must not be written to
465         // NAND since they are not real objects.
466         
467         printf("Attempt to rename lost+found - should have failed\n");
468         x = yaffs_RenameObject(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME,NULL,"Renamed");
469         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
470
471         f = yaffs_MknodFile(yaffs_Root(dev),"pfile",0,0,0);
472         if(f)
473         {
474                 yaffs_WriteDataToFile(f,testStr,0,strlen(testStr));
475         }
476
477         yaffs_Link(yaffs_Root(dev),"phl4",f);
478 }
479
480 void TestTimeDeleteFocussed(yaffs_Device *dev)
481 {
482         yaffs_Object *f;
483         yaffs_Object *lnf;
484         
485         
486         int x;
487         int i;
488         int b;
489         int written;
490         
491         
492         printf("Exisiting objects\n");
493         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
494         printf("Exisiting objects in lost+found\n");
495         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
496         yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
497
498         printf("Start\n");
499         
500         
501         
502
503         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
504         if(f)
505         {
506                 printf("Found\n");
507         }
508         else
509         {
510                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
511                 printf("Created\n");
512         }
513         
514         
515         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
516         
517         for(i = 0; i < 100000; i+=20)
518         { 
519         
520                 b++;
521                 if(b & 1)
522                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
523                 else
524                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
525         }
526         
527         
528
529         yaffs_FlushFile(f);
530                 
531
532         printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
533         
534         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
535         
536 }
537
538 void TestTimeTnodeFocussed(yaffs_Device *dev)
539 {
540         yaffs_Object *f;
541         yaffs_Object *lnf;
542         
543         
544         int x;
545         int i;
546         int b;
547         int written;
548         
549         
550         printf("Exisiting objects\n");
551         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
552         printf("Exisiting objects in lost+found\n");
553         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
554         yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
555
556         printf("Start\n");
557         
558         
559         
560
561         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
562         if(f)
563         {
564                 printf("Found\n");
565         }
566         else
567         {
568                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
569                 printf("Created\n");
570         }
571         
572         
573         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
574         
575         for(i = 0; i < 10000; i+=20)
576         {
577         
578                 b++;
579                 if(b & 1)
580                         written = yaffs_WriteDataToFile(f,testStr,0,strlen(testStr));
581                 else
582                         written = yaffs_WriteDataToFile(f,testStr2,0,strlen(testStr2));
583         }
584         
585 }
586
587 int main(int argc,char *argv[])
588 {
589
590         int nBlocks;
591         
592 #if YAFFS_FILEEM        
593         nBlocks =(4 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK) ;
594         device.writeChunkToNAND = yaffs_FEWriteChunkToNAND;
595         device.readChunkFromNAND = yaffs_FEReadChunkFromNAND;
596         device.eraseBlockInNAND = yaffs_FEEraseBlockInNAND;
597         device.initialiseNAND = yaffs_FEInitialiseNAND;
598
599         printf("Testing on file emulation\n");
600 #else
601         nBlocks = (2 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
602         device.writeChunkToNAND = nandemul_WriteChunkToNAND;
603         device.readChunkFromNAND = nandemul_ReadChunkFromNAND;
604         device.eraseBlockInNAND = nandemul_EraseBlockInNAND;
605         device.initialiseNAND = nandemul_InitialiseNAND;
606         
607         printf("Testing on RAM emulation\n");
608 #endif
609
610 #ifdef YAFFS_START
611         device.startBlock = YAFFS_START;  // Don't use block 0
612         device.endBlock = YAFFS_END;
613 #else
614         device.startBlock = 1;  // Don't use block 0
615         device.endBlock = nBlocks;
616 #endif
617
618         yaffs_GutsInitialise(&device);
619         
620         // yaffs_GutsTest();
621         
622         TestTime(&device);
623         
624         printf("Cache hits %d\n",device.cacheHits);
625         printf("Retired blocks %d\n",device.nRetiredBlocks);
626         
627         exit(0);
628 }