*** 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 TestTime(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         // Test the problem of:
164         // Create file
165         // Delete file
166         // Create file with same name
167         // Delete file <== crash
168
169         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
170         if(f)
171         {
172                 printf("Found\n");
173         }
174         else
175         {
176                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
177                 printf("Created\n");
178         }
179         yaffs_Unlink(yaffs_Root(dev),"Name1");
180
181
182         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
183         if(f)
184         {
185                 printf("Found\n");
186         }
187         else
188         {
189                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
190                 printf("Created\n");
191         }
192         yaffs_Unlink(yaffs_Root(dev),"Name1");
193         
194         
195         
196         // Other tests
197         
198         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
199         if(f)
200         {
201                 printf("Found\n");
202         }
203         else
204         {
205                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
206                 printf("Created\n");
207         }
208         
209         
210         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
211         
212         for(i = 0; i < 100000; i+=20)
213         { 
214         
215                 b++;
216                 if(b & 1)
217                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
218                 else
219                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
220         }
221         // some short reads
222         for(i = 1000; i < 50000; i+=2)
223         { 
224                 yaffs_ReadDataFromFile(f,data,i,20);
225         }
226         
227                 
228         yaffs_ReadDataFromFile(f,data,1000,50); 
229         data[50] = 0;
230         
231         printf("Read data is \"%s\"\n",data);
232
233         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
234         yaffs_ReadDataFromFile(f,data,1000,50);
235         data[50] = 0;
236         
237         printf("Read data is \"%s\"\n",data);
238         
239         printf("Flush\n");
240         
241         yaffs_FlushFile(f);
242         yaffs_ReadDataFromFile(f,data,1000,50);
243         data[50] = 0;
244         
245         printf("Read data is \"%s\"\n",data);
246         
247         printf("File length is %d\n",yaffs_GetObjectFileLength(f));
248         
249         sl = yaffs_MknodSymLink(yaffs_Root(dev),"sym-link",0,0,0,"/tmp/alias");
250         yaffs_ReadDataFromFile(f,data,1000,50);
251         data[50] = 0;
252         
253         printf("Read data is \"%s\"\n",data);
254
255
256         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
257         
258         printf("\n\nsymlink alias is \"%s\"\n",alias = yaffs_GetSymlinkAlias(sl));
259         
260         free(alias);
261         
262         printf("Unlink symlink %d\n",yaffs_Unlink(yaffs_Root(dev),"sym-link"));
263         
264         
265         yaffs_ReadDataFromFile(f,data,1000,50);
266         data[50] = 0;
267         
268         printf("Read data is \"%s\"\n",data);
269         
270         yaffs_DumpObject(f);
271
272         printf("Resize 3000\n");        
273         yaffs_ResizeFile(f,3000);
274
275         printf("Resize 2050\n");        
276         yaffs_ResizeFile(f,2050);
277         printf("Resize 2049\n");        
278         yaffs_ResizeFile(f,2049);
279         printf("Resize 2048\n");        
280         yaffs_ResizeFile(f,2048);
281
282
283         printf("Resize 2000\n");        
284         yaffs_ResizeFile(f,2000);
285         
286         yaffs_DumpObject(f);
287         
288         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
289         
290         
291
292         yaffs_FlushFile(f);
293                 
294
295         printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
296         
297         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
298         
299         // Create a directory and play with it
300         
301
302         printf("Find or Create directory and play with it\n");
303         d =  yaffs_FindObjectByName(yaffs_Root(dev),"direct");
304         if(!d)
305         {
306                 d = yaffs_MknodDirectory(yaffs_Root(dev),"direct",0,0,0);
307         }
308         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
309         yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject);
310         
311         printf("Make file in directory\n");
312         
313         df = yaffs_MknodFile(d,"file-in-directory",0,0,0);
314         yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject);
315         
316         
317         // Do some stuff with hardlinks
318         //
319         // NB Deleting hardlinked objects can mess up pointers to hardlinks.
320         // The mechanism is as follows:
321         // * If you unlink a file,softlink or directory that has one or more hardlinks,
322         // then the object is renamed to one of the hardlinks and that hardlink is unlinked.
323         // This means that a pointer to a hardlink so deleted will point to an invalid address.
324         // Thus, make sure that pointers to hardlinks are immediately dereferenced.
325
326
327         printf("Hard link tests\n");
328                 
329         f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
330         hl1 = yaffs_Link(yaffs_Root(dev),"HardLink 1",f);
331         hl2 = yaffs_Link(yaffs_Root(dev),"HardLink 2",f);
332         hl3 = yaffs_Link(yaffs_Root(dev),"HardLink 3",hl2);
333
334         printf("\n\nHard links created\n");
335         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
336         
337         yaffs_Unlink(yaffs_Root(dev),"HardLink 1");
338         printf("\n\nHard link deleted\n");
339         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
340         
341         yaffs_Unlink(yaffs_Root(dev),"Name1");
342         printf("\n\nHard linked file deleted\n");
343         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
344         
345         yaffs_Unlink(yaffs_Root(dev),"HardLink 2");
346         printf("\n\nHard link 2 deleted\n");
347         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
348         
349         yaffs_Unlink(yaffs_Root(dev),"HardLink 3");
350
351         printf("\n\nHard link 3 deleted\n");
352         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
353         
354         // NB We don't allow unlinking or rename of the root or lost+found
355         // We allow setting attributes, but these must not be written to
356         // NAND since they are not real objects.
357         
358         printf("Attempt to rename lost+found - should have failed\n");
359         x = yaffs_RenameObject(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME,NULL,"Renamed");
360         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
361
362         f = yaffs_MknodFile(yaffs_Root(dev),"pfile",0,0,0);
363         if(f)
364         {
365                 yaffs_WriteDataToFile(f,testStr,0,strlen(testStr));
366         }
367
368         yaffs_Link(yaffs_Root(dev),"phl4",f);
369 }
370
371 void TestTimeDeleteFocussed(yaffs_Device *dev)
372 {
373         yaffs_Object *f;
374         yaffs_Object *lnf;
375         
376         
377         int x;
378         int i;
379         int b;
380         int written;
381         
382         
383         printf("Exisiting objects\n");
384         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
385         printf("Exisiting objects in lost+found\n");
386         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
387         yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
388
389         printf("Start\n");
390         
391         
392         
393
394         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
395         if(f)
396         {
397                 printf("Found\n");
398         }
399         else
400         {
401                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
402                 printf("Created\n");
403         }
404         
405         
406         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
407         
408         for(i = 0; i < 100000; i+=20)
409         { 
410         
411                 b++;
412                 if(b & 1)
413                         written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
414                 else
415                         written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
416         }
417         
418         
419
420         yaffs_FlushFile(f);
421                 
422
423         printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
424         
425         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
426         
427 }
428
429 void TestTimeTnodeFocussed(yaffs_Device *dev)
430 {
431         yaffs_Object *f;
432         yaffs_Object *lnf;
433         
434         
435         int x;
436         int i;
437         int b;
438         int written;
439         
440         
441         printf("Exisiting objects\n");
442         yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
443         printf("Exisiting objects in lost+found\n");
444         lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
445         yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
446
447         printf("Start\n");
448         
449         
450         
451
452         f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
453         if(f)
454         {
455                 printf("Found\n");
456         }
457         else
458         {
459                 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
460                 printf("Created\n");
461         }
462         
463         
464         x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
465         
466         for(i = 0; i < 10000; i+=20)
467         {
468         
469                 b++;
470                 if(b & 1)
471                         written = yaffs_WriteDataToFile(f,testStr,0,strlen(testStr));
472                 else
473                         written = yaffs_WriteDataToFile(f,testStr2,0,strlen(testStr2));
474         }
475         
476 }
477
478 int main(int argc,char *argv[])
479 {
480
481         int nBlocks;
482         
483 #if YAFFS_FILEEM        
484         nBlocks =(32 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK) ;
485         device.writeChunkToNAND = yaffs_FEWriteChunkToNAND;
486         device.readChunkFromNAND = yaffs_FEReadChunkFromNAND;
487         device.eraseBlockInNAND = yaffs_FEEraseBlockInNAND;
488         device.initialiseNAND = yaffs_FEInitialiseNAND;
489
490         printf("Testing on file emulation\n");
491 #else
492         nBlocks = (2 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
493         device.writeChunkToNAND = nandemul_WriteChunkToNAND;
494         device.readChunkFromNAND = nandemul_ReadChunkFromNAND;
495         device.eraseBlockInNAND = nandemul_EraseBlockInNAND;
496         device.initialiseNAND = nandemul_InitialiseNAND;
497         
498         printf("Testing on RAM emulation\n");
499 #endif
500
501 #ifdef YAFFS_START
502         device.startBlock = YAFFS_START;  // Don't use block 0
503         device.endBlock = YAFFS_END;
504 #else
505         device.startBlock = 1;  // Don't use block 0
506         device.endBlock = nBlocks;
507 #endif
508
509         yaffs_GutsInitialise(&device);
510         
511         // yaffs_GutsTest();
512         
513         TestTime(&device);
514         
515         printf("Cache hits %d\n",device.cacheHits);
516         printf("Retired blocks %d\n",device.nRetiredBlocks);
517         
518         exit(0);
519 }