*** empty log message ***
authorcharles <charles>
Tue, 17 Sep 2002 22:36:08 +0000 (22:36 +0000)
committercharles <charles>
Tue, 17 Sep 2002 22:36:08 +0000 (22:36 +0000)
12 files changed:
devextras.h
snMakefile
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h
yaffs_mtdif.h
yaffs_nandemul.h
yaffsdev
yaffsdev.c
yaffsdev.proj
yaffsinterface.h
yportenv.h

index bd749b6857f3aa0ebbcc9739f9a206cb13acecb6..9615362b5915130765c03a75c55e9026ea91286c 100644 (file)
@@ -11,6 +11,8 @@
  * it under the terms of the GNU Lesser General Public License version 2.1 as\r
  * published by the Free Software Foundation.\r
  *\r
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.\r
+ *\r
  * This file is just holds extra declarations used during development.\r
  * Most of these are from kernel includes placed here so we can use them in \r
  * applications.\r
index 6006c6942d2358fd59c3c421bb452e147f9a0406..5f52d0f0a9dc815d907161a582ad0abceb370f58 100644 (file)
@@ -1,6 +1,6 @@
 #########################################################
 # Makefile auto generated by Cygnus Source Navigator.
-# Target: yaffsdev_disk_dump_disk Date: Sep 17 2002 Time: 06:47:40 AM
+# Target: yaffsdev_disk Date: Sep 18 2002 Time: 10:19:04 AM
 #
 
 
@@ -18,7 +18,7 @@ CPP = g++
 YACC_FLAGS =      
 LEX_FLAGS =      
 JAVA_FLAGS =      
-CC_FLAGS =  -g  -Wall  -DYAFFS_DUMP -DYAFFS_START=1281 -DYAFFS_END=32767 -DCONFIG_YAFFS_SHORT_OP_CACHE -DYAFFS_PARANOID -DYAFFS_FILEEM
+CC_FLAGS =  -g  -Wall  -DCONFIG_YAFFS_SHORT_OP_CACHE -DYAFFS_PARANOID -DYAFFS_FILEEM
 CPP_FLAGS =      
 YACC_INCLUDES = 
 LEX_INCLUDES = 
@@ -30,16 +30,16 @@ LEX_DEFINES =
 JAVA_DEFINES = 
 CC_DEFINES = 
 CPP_DEFINES = 
-yaffsdev_disk_dump_disk_LIBS = 
+yaffsdev_disk_LIBS = 
 LINKER = gcc
 LINKER_FLAGS = 
 LINKER_ENTRY = 
-yaffsdev_disk_dump_disk_OBJECTS = nand_ecc.o yaffs_fileem.o yaffs_guts.o yaffsdev.o
+yaffsdev_disk_OBJECTS = nand_ecc.o yaffs_fileem.o yaffs_guts.o yaffsdev.o
 
-all: yaffsdumpdisk
+all: yaffsdev
 
-yaffsdumpdisk: $(yaffsdev_disk_dump_disk_OBJECTS)
-       $(LINKER) -o yaffsdumpdisk $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_disk_dump_disk_OBJECTS) $(yaffsdev_disk_dump_disk_LIBS)
+yaffsdev: $(yaffsdev_disk_OBJECTS)
+       $(LINKER) -o yaffsdev $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_disk_OBJECTS) $(yaffsdev_disk_LIBS)
 
 .y.c:
        $(YACC) $< $(YACC_FLAGS) $(YACC_DEFINES) $(YACC_INCLUDES)
@@ -76,5 +76,5 @@ yaffsdev.o: /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h /op
 
 clean:
        rm -f *.o
-       rm -f yaffsdumpdisk
+       rm -f yaffsdev
 
index 29c84089cb0a155aeffaca204f514bf258b2aee3..8ef7da78edb5a84cc0f82adad3057136727edecc 100644 (file)
@@ -1012,6 +1012,12 @@ static void yaffs_read_inode (struct inode *inode)
 }
 
 
+
+static yaffs_Device *yaffs_dev;
+static yaffs_Device *yaffsram_dev;
+
+
+
 static void yaffs_put_super(struct super_block *sb)
 {
        yaffs_Device *dev = yaffs_SuperToDevice(sb);
@@ -1023,7 +1029,10 @@ static void yaffs_put_super(struct super_block *sb)
        }
        yaffs_Deinitialise(dev);
        yaffs_GrossUnlock(dev);
-       
+
+       if(dev == yaffs_dev) yaffs_dev = NULL;
+       if(dev == yaffsram_dev) yaffsram_dev = NULL;
+               
        kfree(dev);
 }
 
@@ -1045,6 +1054,7 @@ static void  yaffs_MTDPutSuper(struct super_block *sb)
 
 #endif
 
+
 static struct super_block *yaffs_internal_read_super(int useRam, struct super_block * sb, void * data, int silent)
 {
        int nBlocks;
@@ -1106,6 +1116,8 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
                dev->eraseBlockInNAND = nandemul_EraseBlockInNAND;
                dev->initialiseNAND = nandemul_InitialiseNAND;
+
+               yaffsram_dev = dev;
                
 #endif
 
@@ -1185,8 +1197,11 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
                dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
                dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
                dev->initialiseNAND = nandmtd_InitialiseNAND;
-               
+                               
                dev->putSuperFunc = yaffs_MTDPutSuper;
+
+               yaffs_dev = dev;
+               
 #endif
        }
 
@@ -1246,6 +1261,33 @@ static DECLARE_FSTYPE(yaffs_ram_fs_type, "yaffsram", yaffs_ram_read_super, FS_SI
 static struct proc_dir_entry *my_proc_entry;
 static struct proc_dir_entry *my_proc_ram_write_entry;
 
+static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name)
+{
+       buf +=sprintf(buf,"\nDevice %s\n",name);
+       buf +=sprintf(buf,"startBlock......... %d\n",dev->startBlock);
+       buf +=sprintf(buf,"endBlock........... %d\n",dev->endBlock);
+       buf +=sprintf(buf,"chunkGroupBits..... %d\n",dev->chunkGroupBits);
+       buf +=sprintf(buf,"chunkGroupSize..... %d\n",dev->chunkGroupSize);
+       buf +=sprintf(buf,"nErasedBlocks...... %d\n",dev->nErasedBlocks);
+       buf +=sprintf(buf,"nTnodesCreated..... %d\n",dev->nTnodesCreated);
+       buf +=sprintf(buf,"nFreeTnodes........ %d\n",dev->nFreeTnodes);
+       buf +=sprintf(buf,"nObjectsCreated.... %d\n",dev->nObjectsCreated);
+       buf +=sprintf(buf,"nFreeObjects....... %d\n",dev->nFreeObjects);
+       buf +=sprintf(buf,"nFreeChunks........ %d\n",dev->nFreeChunks);
+       buf +=sprintf(buf,"nPageWrites........ %d\n",dev->nPageWrites);
+       buf +=sprintf(buf,"nPageReads......... %d\n",dev->nPageReads);
+       buf +=sprintf(buf,"nBlockErasures..... %d\n",dev->nBlockErasures);
+       buf +=sprintf(buf,"nGCCopies.......... %d\n",dev->nGCCopies);
+       buf +=sprintf(buf,"garbageCollections. %d\n",dev->garbageCollections);
+       buf +=sprintf(buf,"nRetriedWrites..... %d\n",dev->nRetriedWrites);
+       buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks);
+       buf +=sprintf(buf,"cacheHits.......... %d\n",dev->cacheHits);
+       buf +=sprintf(buf,"nDeletedFiles...... %d\n",dev->nDeletedFiles);
+       buf +=sprintf(buf,"nUnlinkedFiles..... %d\n",dev->nUnlinkedFiles);
+       buf +=sprintf(buf,"nBackgroudDeletions %d\n",dev->nBackgroundDeletions);
+       
+       return buf;     
+}
 
 static int  yaffs_proc_read(
         char *page,
@@ -1257,15 +1299,18 @@ static int  yaffs_proc_read(
        )
 {
 
-       static char my_buffer[1000];
+       char my_buffer[2000];
+       char *buf;
+       buf = my_buffer;
 
        if (offset > 0) return 0;
 
        /* Fill the buffer and get its length */
-       sprintf( my_buffer, 
-               "YAFFS built:"__DATE__ " "__TIME__"\n"
-               
-       );
+       buf +=sprintf(buf,"YAFFS built:"__DATE__ " "__TIME__"\n");
+       
+       if(yaffs_dev) buf = yaffs_dump_dev(buf,yaffs_dev,"yaffs");
+       if(yaffsram_dev) buf = yaffs_dump_dev(buf,yaffsram_dev,"yaffsram");
+       
 
        strcpy(page,my_buffer);
        return strlen(my_buffer);
@@ -1290,6 +1335,8 @@ static int __init init_yaffs_fs(void)
 {
        int error = 0;
        
+       yaffs_dev = yaffsram_dev = NULL;
+       
        printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n");
 #ifdef CONFIG_YAFFS_USE_GENERIC_RW
        printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n");
index b042a9a7c61dbaf9a0f659e503d34c60525a0583..eaa18fda50db7701b6235d0621ff51cb7141d41f 100644 (file)
@@ -72,7 +72,7 @@ static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force
 static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId);
 static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
 static int yaffs_CheckStructures(void);
-static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit);
+static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit);
 static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
 
 static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev,int blockNo);
@@ -833,8 +833,9 @@ static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev, yaffs_FileStru
 
 // DeleteWorker scans backwards through the tnode tree and deletes all the
 // chunks and tnodes in the file
+// Returns 1 if the tree was deleted. Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
 
-static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit)
+static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit)
 {
        int i;
        int chunkInInode;
@@ -842,6 +843,7 @@ static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, i
        yaffs_Tags tags;
        int found;
        int chunkDeleted;
+       int allDone = 1;
        
        
        if(tn)
@@ -849,17 +851,28 @@ static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, i
                if(level > 0)
                {
                
-                       for(i = YAFFS_NTNODES_INTERNAL -1; i >= 0 && (!limit || *limit > 0); i--)
+                       for(i = YAFFS_NTNODES_INTERNAL -1; allDone && i >= 0; i--)
                        {
                            if(tn->internal[i])
                        {
-                                       yaffs_DeleteWorker(in,tn->internal[i],level - 1,
+                                       if(limit && (*limit) < 0)
+                                       {
+                                               allDone = 0;
+                                       }
+                                       else
+                                       {
+                                               allDone = yaffs_DeleteWorker(in,tn->internal[i],level - 1,
                                                                                (chunkOffset << YAFFS_TNODES_INTERNAL_BITS ) + i ,limit);
-                                       yaffs_FreeTnode(in->myDev,tn->internal[i]);
-                               tn->internal[i] = NULL;
+                                       }
+                                       if(allDone)
+                                       {
+                                               yaffs_FreeTnode(in->myDev,tn->internal[i]);
+                                       tn->internal[i] = NULL;
+                                       }
                            }
                    
                        }
+                       return (allDone) ? 1 : 0;
                }
                else if(level == 0)
                {
@@ -904,11 +917,15 @@ static void yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, i
                            }
                    
                        }
+                       return 1;
+
                        
                }
                
        }
        
+       return 1;
+       
 }
 
 
@@ -1929,14 +1946,19 @@ static void yaffs_DoUnlinkedFileDeletion(yaffs_Device *dev)
        {
                yaffs_Object *obj = dev->unlinkedDeletion;
                int limit;
+               int delresult;
                limit = 50; // Max number of chunks to delete in a file. NB this can be exceeded, but not by much.
-               yaffs_DeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0,&limit);
+               delresult = yaffs_DeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0,&limit);
+               
                if(obj->nDataChunks == 0)
                {
                        // Done all the deleting of data chunks.
                        // Now dump the header and clean up
-                       yaffs_DoGenericObjectDeletion(dev->unlinkedDeletion);
+                       yaffs_FreeTnode(dev,obj->variant.fileVariant.top);
+                       yaffs_DoGenericObjectDeletion(obj);
                        dev->nDeletedFiles--;
+                       dev->nUnlinkedFiles--;
+                       dev->nBackgroundDeletions++;
                        dev->unlinkedDeletion = NULL;   
                }
        }
@@ -3071,11 +3093,35 @@ static int yaffs_UnlinkFile(yaffs_Object *in)
        return  yaffs_DoGenericObjectDeletion(in);
 #else
        int retVal;
+       int immediateDeletion=0;
        retVal = yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,NULL);
        if(retVal == YAFFS_OK)
        {
-               in->unlinked = 1;
-               in->renameAllowed = 0;
+               //in->unlinked = 1;
+               //in->myDev->nUnlinkedFiles++;
+               //in->renameAllowed = 0;
+#ifdef __KERNEL__
+               if(in->myInode)
+               {
+                       immediateDeletion = 1;
+
+               }
+#endif
+#if WIN32
+               if(in->inUse <= 0)
+               {
+                       immediateDeletion = 1;
+
+               }
+#endif
+               
+               if(immediateDeletion)
+               {
+                       T((TSTR("yaffs: immediate deletion of file %d" TENDSTR),in->objectId));
+                       in->deleted=1;
+                       in->myDev->nDeletedFiles++;
+               }
+       
        }
        return retVal;
 
@@ -3090,9 +3136,12 @@ int yaffs_DeleteFile(yaffs_Object *in)
        {
                retVal = yaffs_UnlinkFile(in);
        }
-       if(retVal == YAFFS_OK && in->unlinked)
+       if(retVal == YAFFS_OK && 
+          in->unlinked &&
+          !in->deleted)
        {
                in->deleted = 1;
+               in->myDev->nDeletedFiles++;
        }
        return in->deleted ? YAFFS_OK : YAFFS_FAIL;     
 }
@@ -3639,6 +3688,7 @@ static void yaffs_AddObjectToDirectory(yaffs_Object *directory, yaffs_Object *ob
        if(directory == obj->myDev->unlinkedDir)
        {
                obj->unlinked = 1;
+               obj->myDev->nUnlinkedFiles++;
                obj->renameAllowed = 0;
        }
 }
@@ -3986,6 +4036,8 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        dev->doingBufferedBlockRewrite = 0;
        dev->blockSelectedForGC = -1;
        dev->nDeletedFiles = 0;
+       dev->nBackgroundDeletions=0;
+       dev->nUnlinkedFiles = 0;
        
        yaffs_InitialiseBlocks(dev,nBlocks);
        
index 855354296f944cd44a2e153dd06ccb2440e233fa..b42c7cb9100008adc622da25401dc7138f91b6b7 100644 (file)
@@ -11,6 +11,8 @@
  * it under the terms of the GNU Lesser General Public License version 2.1 as
  * published by the Free Software Foundation.
  *
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  */
 
 #ifndef __YAFFS_GUTS_H__
@@ -442,8 +444,9 @@ struct yaffs_DeviceStruct
        // Stuff for background deletion and unlinked files.
        yaffs_Object *unlinkedDir;              // Directory where unlinked and deleted files live.
        yaffs_Object *unlinkedDeletion; // Current file being background deleted.
-       int  nDeletedFiles;                             // Count of files awaiting deletion;
-       
+       int nDeletedFiles;                              // Count of files awaiting deletion;
+       int nUnlinkedFiles;                             // Count of unlinked files. 
+       int nBackgroundDeletions;                       // Count of background deletions.       
        
 };
 
index 42b65e2ea43abbe28b22fcc08bff6ef7b79b82fe..dd908ec59ee08f27c970658b0ee8883aabb45cb0 100644 (file)
@@ -11,6 +11,9 @@
  * it under the terms of the GNU Lesser General Public License version 2.1 as
  * published by the Free Software Foundation.
  *
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ *
  */
 
 #ifndef __YAFFS_MTDIF_H__
index 880d35038fe61fb0ef31f444f330256567f1379b..bd51465d19ca9adb04f5f269b73700ddcfa83a46 100644 (file)
@@ -10,6 +10,9 @@
  * it under the terms of the GNU Lesser General Public License version 2.1 as
  * published by the Free Software Foundation.
  *
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ *
  * yaffs_nandemul.h: Interface to emulated NAND functions
  *
  */
index 3a7e43e15266f58ed026ccec3094a6ffda448bf8..e1033293f8ed5dad5cea6fa8c7176c616a51b729 100755 (executable)
Binary files a/yaffsdev and b/yaffsdev differ
index afb9354bc17537a5d51263e1f1d8cb1ccf4aebad..3fb6a62e39ee13af9795f1a2b961e71dde0c84b8 100644 (file)
@@ -129,6 +129,110 @@ void TestTimeasasas(yaffs_Device *dev)
        
                
 
+}
+
+void TestTimeBigDeletes(yaffs_Device *dev)
+{
+       yaffs_Object *f;
+       yaffs_Object *sl;
+       yaffs_Object *lnf;
+       
+       yaffs_Object *hl1;
+       yaffs_Object *hl2;
+       yaffs_Object *hl3;
+       yaffs_Object *d, *df;
+       
+       int x;
+       int i;
+       int b;
+       char data[200];
+       
+       char * alias;
+       int written;
+       
+       
+       printf("Exisiting objects\n");
+       yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
+       printf("Exisiting objects in lost+found\n");
+       lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME);
+       yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject);
+
+       printf("Start\n");
+       
+       
+
+       f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
+       if(f)
+       {
+               printf("Found\n");
+       }
+       else
+       {
+               f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
+               printf("Created\n");
+       }
+       
+       for(i = 0; i < 100000; i+=20)
+       { 
+       
+               b++;
+               if(b & 1)
+                       written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
+               else
+                       written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
+       }
+       
+       yaffs_FlushFile(f);
+       yaffs_DeleteFile(f);
+
+       f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
+       if(f)
+       {
+               printf("Found\n");
+       }
+       else
+       {
+               f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
+               printf("Created\n");
+       }
+       
+       for(i = 0; i < 100000; i+=20)
+       { 
+       
+               b++;
+               if(b & 1)
+                       written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
+               else
+                       written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
+       }
+       
+       yaffs_FlushFile(f);
+       yaffs_DeleteFile(f);
+
+       f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
+       if(f)
+       {
+               printf("Found\n");
+       }
+       else
+       {
+               f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0);
+               printf("Created\n");
+       }
+       
+       for(i = 0; i < 100000; i+=20)
+       { 
+       
+               b++;
+               if(b & 1)
+                       written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr));
+               else
+                       written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2));
+       }
+       
+       yaffs_FlushFile(f);
+       yaffs_DeleteFile(f);
+       
 }
 
 void TestTime(yaffs_Device *dev)
@@ -294,6 +398,8 @@ void TestTime(yaffs_Device *dev)
 
        printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename"));
        
+       yaffs_DeleteFile(f);
+       
        yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject);
        
        // Create a directory and play with it
@@ -510,7 +616,7 @@ int main(int argc,char *argv[])
        
        // yaffs_GutsTest();
        
-       TestTime(&device);
+       TestTimeBigDeletes(&device);
        
        printf("Cache hits %d\n",device.cacheHits);
        printf("Retired blocks %d\n",device.nRetiredBlocks);
index 38db4124e717da6c403c951ab7712de8bd506e56..2ead24fb4884d4bf64598003925dc7638ddd5e8a 100644 (file)
Binary files a/yaffsdev.proj and b/yaffsdev.proj differ
index ddac14b5cc5bc276a8f0a2336d6aaf8da54c892c..e4b0ff1d08ea8b66a713ba7fc7afe369aa8ac288 100644 (file)
@@ -11,6 +11,8 @@
  * it under the terms of the GNU Lesser General Public License version 2.1 as
  * published by the Free Software Foundation.
  *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ *
  */
  
 #ifndef __YAFFSINTERFACE_H__
index 100d8a370065dc5856b07a6709871d4b39782eb8..6f42e105251ecd99fd3e2a343f665afee83ab242 100644 (file)
@@ -12,6 +12,9 @@
  * it under the terms of the GNU Lesser General Public License version 2.1 as\r
  * published by the Free Software Foundation.\r
  *\r
+ *\r
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.\r
+ *\r
  */\r
  \r
 #ifndef __PORTENV_H__\r