2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
5 * Copyright (C) 2002 Aleph One Ltd.
6 * for Toby Churchill Ltd and Brightstar Engineering
8 * Created by Charles Manning <charles@aleph1.co.uk>
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.
16 #include "yaffsinterface.h"
20 #include "yaffs_fileem.h"
22 #include "yaffs_nandemul.h"
25 #include "yaffs_guts.h"
35 char *testStr = "this is a test string";
37 char *testStr2 = "abcdefghijklmnopqrstuvwxyz1234567890";
39 void TestTimexxx(yaffs_Device *dev)
48 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
55 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
60 x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
65 void TestTimeasasas(yaffs_Device *dev)
78 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
85 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
90 x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
94 for(i = 0; i < 10000; i+=20)
99 written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
101 written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
105 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
111 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
113 yaffs_ReadDataFromFile(f,data,1000,50);
116 printf("Read data is \"%s\"\n",data);
120 printf("Resize to 3000\n");
121 yaffs_ResizeFile(f,3000);
122 printf("Resize to 2048\n");
123 yaffs_ResizeFile(f,2048);
134 void TestTimeBigDeletes(yaffs_Device *dev)
143 yaffs_Object *d, *df;
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);
164 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
171 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
175 for(i = 0; i < 100000; i+=20)
180 written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
182 written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
188 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
195 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
199 for(i = 0; i < 100000; i+=20)
204 written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
206 written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
212 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
219 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
223 for(i = 0; i < 100000; i+=20)
228 written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
230 written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
238 void TestTime(yaffs_Device *dev)
247 yaffs_Object *d, *df;
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);
267 // Test the problem of:
270 // Create file with same name
271 // Delete file <== crash
273 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
280 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
283 yaffs_Unlink(yaffs_Root(dev),"Name1");
286 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
293 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
296 yaffs_Unlink(yaffs_Root(dev),"Name1");
302 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
309 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
314 x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
316 for(i = 0; i < 100000; i+=64)
321 written = yaffs_WriteDataToFile(f,testStr,i,64);
323 written = yaffs_WriteDataToFile(f,testStr2,i,64);
325 written = yaffs_WriteDataToFile(f,testStr2,1,20);
329 for(i = 1000; i < 50000; i+=2)
331 yaffs_ReadDataFromFile(f,data,i,20);
335 yaffs_ReadDataFromFile(f,data,1000,50);
338 printf("Read data is \"%s\"\n",data);
340 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
341 yaffs_ReadDataFromFile(f,data,1000,50);
344 printf("Read data is \"%s\"\n",data);
349 yaffs_ReadDataFromFile(f,data,1000,50);
352 printf("Read data is \"%s\"\n",data);
354 printf("File length is %d\n",yaffs_GetObjectFileLength(f));
356 sl = yaffs_MknodSymLink(yaffs_Root(dev),"sym-link",0,0,0,"/tmp/alias");
357 yaffs_ReadDataFromFile(f,data,1000,50);
360 printf("Read data is \"%s\"\n",data);
363 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
365 printf("\n\nsymlink alias is \"%s\"\n",alias = yaffs_GetSymlinkAlias(sl));
369 printf("Unlink symlink %d\n",yaffs_Unlink(yaffs_Root(dev),"sym-link"));
372 yaffs_ReadDataFromFile(f,data,1000,50);
375 printf("Read data is \"%s\"\n",data);
379 printf("Resize 3000\n");
380 yaffs_ResizeFile(f,3000);
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);
390 printf("Resize 2000\n");
391 yaffs_ResizeFile(f,2000);
395 lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
402 printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
406 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
408 // Create a directory and play with it
411 printf("Find or Create directory and play with it\n");
412 d = yaffs_FindObjectByName(yaffs_Root(dev),"direct");
415 d = yaffs_MknodDirectory(yaffs_Root(dev),"direct",0,0,0);
417 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
418 yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject);
420 printf("Make file in directory\n");
422 df = yaffs_MknodFile(d,"file-in-directory",0,0,0);
423 yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject);
426 // Do some stuff with hardlinks
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.
436 printf("Hard link tests\n");
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);
443 printf("\n\nHard links created\n");
444 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
446 yaffs_Unlink(yaffs_Root(dev),"HardLink 1");
447 printf("\n\nHard link deleted\n");
448 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
450 yaffs_Unlink(yaffs_Root(dev),"Name1");
451 printf("\n\nHard linked file deleted\n");
452 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
454 yaffs_Unlink(yaffs_Root(dev),"HardLink 2");
455 printf("\n\nHard link 2 deleted\n");
456 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
458 yaffs_Unlink(yaffs_Root(dev),"HardLink 3");
460 printf("\n\nHard link 3 deleted\n");
461 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
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.
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);
471 f = yaffs_MknodFile(yaffs_Root(dev),"pfile",0,0,0);
474 yaffs_WriteDataToFile(f,testStr,0,strlen(testStr));
477 yaffs_Link(yaffs_Root(dev),"phl4",f);
480 void TestTimeDeleteFocussed(yaffs_Device *dev)
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);
503 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
510 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
515 x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
517 for(i = 0; i < 100000; i+=20)
522 written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
524 written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
532 printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
534 yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
538 void TestTimeTnodeFocussed(yaffs_Device *dev)
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);
561 f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
568 f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
573 x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename");
575 for(i = 0; i < 10000; i+=20)
580 written = yaffs_WriteDataToFile(f,testStr,0,strlen(testStr));
582 written = yaffs_WriteDataToFile(f,testStr2,0,strlen(testStr2));
587 int main(int argc,char *argv[])
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;
599 printf("Testing on file emulation\n");
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;
607 printf("Testing on RAM emulation\n");
611 device.startBlock = YAFFS_START; // Don't use block 0
612 device.endBlock = YAFFS_END;
614 device.startBlock = 1; // Don't use block 0
615 device.endBlock = nBlocks;
618 yaffs_GutsInitialise(&device);
624 printf("Cache hits %d\n",device.cacheHits);
625 printf("Retired blocks %d\n",device.nRetiredBlocks);