*** empty log message ***
authorcharles <charles>
Tue, 27 Aug 2002 03:31:38 +0000 (03:31 +0000)
committercharles <charles>
Tue, 27 Aug 2002 03:31:38 +0000 (03:31 +0000)
Documentation/yaffs-todo.html
Makefile
snMakefile
yaffs_fileem.c
yaffs_fs.c
yaffs_guts.c
yaffs_mtdif.c
yaffs_ramem.c
yaffsdev
yaffsdev.c
yaffsdev.proj

index 831b2d32c62362220fdc9fbca6ece627eb6ed4d4..ccef2e8dbeb7d1af36d47b3aca06af3446963eff 100644 (file)
@@ -7,7 +7,7 @@
        <META NAME="AUTHOR" CONTENT=" ">
        <META NAME="CREATED" CONTENT="20020501;19062800">
        <META NAME="CHANGEDBY" CONTENT=" ">
-       <META NAME="CHANGED" CONTENT="20020709;16002500">
+       <META NAME="CHANGED" CONTENT="20020821;21171400">
 </HEAD>
 <BODY>
 <H1>YAFFS Todo as at <SDFIELD TYPE=DATETIME SDNUM="5129;2057;DD/MM/YYYY">21/08/2002</SDFIELD></H1>
@@ -22,7 +22,7 @@
 </OL>
 <H3>Tools to be done</H3>
 <OL>
-       <LI><P></P>
+       <LI><P>Dumper and analyser to work off the mtd.</P>
 </OL>
 <H3>Recently done with no known problems (ie. probably needs
 significant testing)</H3>
@@ -49,16 +49,19 @@ significant testing)</H3>
        the spirit of mkcramfs).</P>
        <LI><P>Added support for special inodes (pipes, character &amp;
        block devices, sockets).</P>
-       <LI><P>Added generic read/write support to use page caching.</P>
+       <LI><P>Added generic read/write support to use page caching.
+       Selectable by configuration of CONFIG_YAFFS_USE_GENERIC_RW.</P>
 </OL>
 <H3>Done, but currently known to be broken</H3>
 <OL>
-       <P>nothing.</P>
+       <LI><P>If you fill yaffs and then try to copy more files into it,
+       you end up with a bunch of objxxx files when you do an ls.</P>
 </OL>
 <H3>Longer term stuff to do</H3>
 <OL>
        <LI><P>Discuss improved NAND page interface with mtd group. This has
-       actually started.</P>
+       actually started. Luc van Oostenryck is also looking at an
+       alternative layer to mtd.</P>
        <LI><P>Pull out all YAFFS_OK and YAFFS_FAIL style errors and return
        with -ENOMEM style error messages.</P>
 </OL>
index 7642d476e3563dae1169b829bdeb0f117007cfc3..fa4c171e209e457dc7fad46983ee3c55dadd86fd 100644 (file)
--- a/Makefile
+++ b/Makefile
 ## comment out USE_xxxx if you don't want these features.
 
 KERNELDIR = /usr/src/kernel-headers-2.4.18
+
+# Configurations...
+# Comment out the stuff you don't want.
+#
+
+# CONFIG_YAFFS_RAM_ENABLED.
+# This adds the yaffsram file system support. Nice for testing on x86, but uses 2MB of RAM.
+# Don't enable for NAND-based targets.
+
 USE_RAM_FOR_TEST = -DCONFIG_YAFFS_RAM_ENABLED
+
+
+# CONFIG_YAFFS_MTD_ENABLED.
+# This adds the yaffs file system support for working with a NAND mtd.
+
 USE_MTD = -DCONFIG_YAFFS_MTD_ENABLED
-YAFFS_CONFIGS = -DCONFIG_YAFFS_USE_GENERIC_RW
 
-CFLAGS = -D__KERNEL__ -DMODULE $(USE_RAM_FOR_TEST) $(USE_MTD) $(YAFFS_CONFIGS)  -I$(KERNELDIR)/include -O2 -Wall
+# CONFIG_YAFFS_USE_GENERIC_RW
+# Use generic_read/generic_write for reading/writing files. This enables the use of the Linux
+# file caching layer.
+#
+# If you disable this, then caching is disabled and file read/write is direct.
+
+USE_GENERIC_RW = -DCONFIG_YAFFS_USE_GENERIC_RW
+
+# CONFIG_YAFFS_USE_HEADER_FILE_SIZE
+# When the flash is scanned, two file sizes are constructed:
+# * The size taken from the object header for the file.
+# * The size figured out by scanning the data chunks.
+# If this option is enabled, then the object header size is ued, otherwise the scanned size is used.
+# Suggest leaving this disabled.
+
+#USE_HEADER_FILE_SIZE = -DCONFIG_YAFFS_USE_HEADER_FILE_SIZE
+
+#CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK
+# Enabling this turns off the test that chunks are erased in flash before writing to them.
+# this is safe, since the write verification will fail.
+# Suggest enabling the test (ie. keep the following line commented) during development to help debug things.
+
+#IGNORE_CHUNK_ERASED = -DCONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK
+
+#CONFIG_YAFFS_DISABLE_WRITE_VERIFY
+# I am severely reluctant to provide this config. Disabling the verification is not a good thing to do
+# since NAND writes can fail silently.
+# Disabling the write verification will cause your teeth to rot, rats to eat your corn and give you split ends.
+# You have been warned. ie. Don't uncomment the following line.
+
+#IGNORE_WRITE_VERIFY = -DCONFIG_YAFFS_DISBLE_WRITE_VERIFY
+
+# End of configuration options.
+
+YAFFS_CONFIGS = $(USE_RAM_FOR_TEST) $(USE_MTD) $(USE_GENERIC_RW) $(USE_HEADER_FILE_SIZE) $(IGNORE_CHUNK_ERASED) $(IGNORE_WRITE_VERIFY)
+
+CFLAGS = -D__KERNEL__ -DMODULE $(YAFFS_CONFIGS)  -I$(KERNELDIR)/include -O2 -Wall
 
 
 OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o
@@ -28,7 +77,7 @@ OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o
 
 all: yaffs.o
 
-$(OBJS): %.o: %.c
+$(OBJS): %.o: %.c Makefile
        gcc -c $(CFLAGS) $< -o $@
 
 yaffs.o: $(OBJS)
index 936c08d4431b1d91a57f725488145115c9168f6c..dd819c8dcdcf9ce85b34187ce474954a160beadb 100644 (file)
@@ -1,6 +1,6 @@
 #########################################################
 # Makefile auto generated by Cygnus Source Navigator.
-# Target: yaffsdev_disk Date: Aug 21 2002 Time: 03:51:36 PM
+# Target: yaffsdev_disk Date: Aug 27 2002 Time: 03:17:30 PM
 #
 
 
index dd77b37fca0fd0ab946a6b241c2ff5abce38b1af..b850581d9b1e3da6ddee81f6fb87bf522a240786 100644 (file)
@@ -56,6 +56,16 @@ static int IsAMarkedBadBlock(int blk)
 
 static __u8 yaffs_WriteFailCorruption(int chunkInNAND)
 {
+
+       // Whole blocks that fail
+       switch(chunkInNAND/YAFFS_CHUNKS_PER_BLOCK)
+       {
+               case 50:
+               case 52:
+                                       return 7;
+       }
+       
+       // Single blocks that fail
        switch(chunkInNAND)
        {
                case 2000:
@@ -70,9 +80,10 @@ static __u8 yaffs_WriteFailCorruption(int chunkInNAND)
                case 3006:
                case 3007:  return 1;// ding one bit
                
-               default: return 0;
                
        }
+
+       return 0;
 }
 
 static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data)
index dc700987448cbbe974b66743cb7981d7c9771d99..d669793752559559e71b3083f781b01927ae5c93 100644 (file)
@@ -20,7 +20,7 @@
  *
  *
  * Acknowledgements:
- * * Luc van OostenRyck for O_APPEND patch.
+ * * Luc van OostenRyck for numerous patches.
  * * Nick Bane for patches marked NCB.
  * * Some code bodily lifted from JFFS2.
  */
@@ -774,7 +774,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
        struct inode *inode = dentry->d_inode;
        int error;
        
-       T((KERN_DEBUG"yaffs_setattr\n"));
+       T((KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId));
        
        if((error = inode_change_ok(inode,attr)) == 0)
        {
@@ -831,6 +831,8 @@ static void yaffs_put_super(struct super_block *sb)
        {
                 dev->putSuperFunc(sb);
        }
+       yaffs_Deinitialise(dev);
+       kfree(dev);
 }
 
 
@@ -871,7 +873,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
 
        
 
-#if CONFIG_YAFFS_USE_CHUNK_SIZE
+#ifdef CONFIG_YAFFS_USE_CHUNK_SIZE
        sb->s_blocksize = YAFFS_BYTES_PER_CHUNK;
        sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT;
 #else
@@ -880,6 +882,11 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl
 #endif
        T(("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",sb->s_blocksize));
 
+#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY
+       T(("yaffs: Write verification disabled. All guarantees null and void\n");
+#endif
+
+
        
        if(useRam)
        {
@@ -1070,7 +1077,7 @@ static int __init init_yaffs_fs(void)
        int error = 0;
        
        printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n");
-#if CONFIG_YAFFS_USE_GENERIC_RW
+#ifdef CONFIG_YAFFS_USE_GENERIC_RW
        printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n");
 #else
        printk(KERN_DEBUG "yaffs is using direct read/write (uncached)\n");
index abb01e2c1694ede4e0be49e82b7c9e564c560029..fa1c9d59d1645a4c7953827ea7105750da19a155 100644 (file)
@@ -73,7 +73,7 @@ static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkIn
 \r
 static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type);\r
 static void yaffs_AddObjectToDirectory(yaffs_Object *directory, yaffs_Object *obj);\r
-static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name);\r
+static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force);\r
 static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId);\r
 static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);\r
 static int yaffs_CheckStructures(void);\r
@@ -87,6 +87,7 @@ static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaf
 \r
 static int  yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND);\r
 \r
+static int yaffs_UnlinkWorker(yaffs_Object *obj);\r
 \r
 \r
 static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1);\r
@@ -187,7 +188,6 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8
 \r
 static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND)\r
 {\r
-#if 1\r
 \r
        static int init = 0;\r
        static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK];\r
@@ -208,7 +208,6 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND
        if(memcmp(cmpbuf,data,YAFFS_BYTES_PER_CHUNK)) return  YAFFS_FAIL;\r
        if(memcmp(cmpbuf,spare,16)) return YAFFS_FAIL;\r
 \r
-#endif\r
        \r
        return YAFFS_OK;\r
        \r
@@ -244,9 +243,14 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8
                {\r
 \r
                        // First check this chunk is erased...\r
+#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK\r
                        writeOk = yaffs_CheckChunkErased(dev,chunk);\r
-               \r
-                       if(writeOk)\r
+#endif         \r
+                       if(!writeOk)\r
+                       {\r
+                               T((TSTR("**>> yaffs chunk %d was not erased" TENDSTR),chunk));\r
+                       }\r
+                       else\r
                        {\r
                                writeOk =  yaffs_WriteChunkToNAND(dev,chunk,data,spare);\r
                        }\r
@@ -260,14 +264,15 @@ static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8
                                // NB We check a raw read without ECC correction applied\r
                                yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0);\r
                                \r
+#ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY\r
                                if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare))\r
                                                        {\r
                                        // Didn't verify\r
-                                       T((TSTR("**>> yaffs write failed on chunk %d" TENDSTR), chunk));\r
-                                       // yaffs_DeleteChunk(dev,chunk);\r
+                                       T((TSTR("**>> yaffs write verify failed on chunk %d" TENDSTR), chunk));\r
 \r
                                        writeOk = 0;\r
-                               }                                       \r
+                               }       \r
+#endif                         \r
                                \r
                        }\r
                        if(writeOk)\r
@@ -327,12 +332,19 @@ static int yaffs_RewriteBufferedBlock(yaffs_Device *dev)
        //      Set current write block to the new block\r
        \r
        dev->doingBufferedBlockRewrite = 0;\r
+       \r
+       return 1;\r
 }\r
 \r
 \r
 static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND)\r
 {\r
-       \r
+       int blockInNAND = chunkInNAND/YAFFS_CHUNKS_PER_BLOCK;\r
+\r
+       // Mark the block for retirement\r
+       dev->blockInfo[blockInNAND].needsRetiring = 1;\r
+\r
+       //TODO  \r
        // Just do a garbage collection on the affected block then retire the block\r
        // NB recursion\r
 }\r
@@ -352,6 +364,12 @@ static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaf
 \r
 static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND)\r
 {\r
+       int blockInNAND = chunkInNAND/YAFFS_CHUNKS_PER_BLOCK;\r
+\r
+       // Mark the block for retirement\r
+       dev->blockInfo[blockInNAND].needsRetiring = 1;\r
+       // Delete the chunk\r
+       yaffs_DeleteChunk(dev,chunkInNAND);\r
 }\r
 \r
 \r
@@ -360,6 +378,7 @@ static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND)
 static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1)\r
 {\r
 \r
+\r
        if( memcmp(d0,d1,YAFFS_BYTES_PER_CHUNK) != 0 ||\r
                s0->tagByte0 != s1->tagByte0 ||\r
                s0->tagByte1 != s1->tagByte1 ||\r
@@ -1411,7 +1430,7 @@ yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type,
                                break;\r
                }\r
 \r
-               if(yaffs_UpdateObjectHeader(in,name) < 0)\r
+               if(yaffs_UpdateObjectHeader(in,name,0) < 0)\r
                {\r
                        // Could not create the object header, fail the creation\r
                        yaffs_UnlinkWorker(in);\r
@@ -1479,7 +1498,7 @@ static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const
                obj->dirty = 1;\r
                yaffs_AddObjectToDirectory(newDir,obj);\r
                \r
-               if(yaffs_UpdateObjectHeader(obj,newName) >= 0)\r
+               if(yaffs_UpdateObjectHeader(obj,newName,0) >= 0)\r
                {\r
                        return YAFFS_OK;\r
                }\r
@@ -1638,21 +1657,52 @@ static int yaffs_FindDirtiestBlock(yaffs_Device *dev)
 }\r
 \r
 \r
-static int yaffs_FindBlockForAllocation(yaffs_Device *dev,int useReserve)\r
+static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo)\r
+{\r
+       yaffs_BlockInfo *bi = &dev->blockInfo[blockNo];\r
+       \r
+       int erasedOk = 0;\r
+       \r
+       // If the block is still healthy erase it and mark as clean.\r
+       // If the block has had a data failure, then retire it.\r
+       bi->blockState = YAFFS_BLOCK_STATE_DIRTY;\r
+\r
+       if(!bi->needsRetiring)\r
+       {\r
+               erasedOk = yaffs_EraseBlockInNAND(dev,blockNo);\r
+               if(!erasedOk)\r
+               {\r
+                       T((TSTR("**>> Erasure failed %d" TENDSTR),blockNo));\r
+               }\r
+       }\r
+       \r
+       if( erasedOk )\r
+       {\r
+               bi->blockState = YAFFS_BLOCK_STATE_EMPTY;\r
+               dev->nErasedBlocks++;\r
+               bi->pagesInUse = 0;\r
+               bi->pageBits = 0;\r
+       \r
+               T((TSTR("Erased block %d" TENDSTR),blockNo));\r
+       }\r
+       else\r
+       {\r
+               yaffs_RetireBlock(dev,blockNo);\r
+               T((TSTR("**>> Block %d retired" TENDSTR),blockNo));\r
+       }\r
+}\r
+\r
+\r
+static int yaffs_FindBlockForAllocation(yaffs_Device *dev)\r
 {\r
        int i;\r
        \r
-       if(useReserve && dev->nErasedBlocks < 1)\r
+       if(dev->nErasedBlocks < 1)\r
        {\r
                // Hoosterman we've got a problem.\r
                // Can't get space to gc\r
                return -1;\r
        }\r
-       else if(!useReserve && dev->nErasedBlocks <= YAFFS_RESERVED_BLOCKS)\r
-       {\r
-               // We are not in GC, so we hold some in reserve so we can get\r
-               // a gc done.\r
-       }\r
        \r
        // Find an empty block.\r
        \r
@@ -1676,31 +1726,6 @@ static int yaffs_FindBlockForAllocation(yaffs_Device *dev,int useReserve)
 }\r
 \r
 \r
-static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo)\r
-{\r
-       yaffs_BlockInfo *bi = &dev->blockInfo[blockNo];\r
-       \r
-       // Mark as dirty.\r
-       // If the block is still healthy erase it and mark as clean.\r
-       // If the block has had a data failure, then retire it.\r
-       bi->blockState = YAFFS_BLOCK_STATE_DIRTY;\r
-       \r
-       if(!bi->needsRetiring && yaffs_EraseBlockInNAND(dev,blockNo))\r
-       {\r
-               bi->blockState = YAFFS_BLOCK_STATE_EMPTY;\r
-               dev->nErasedBlocks++;\r
-               bi->pagesInUse = 0;\r
-               bi->pageBits = 0;\r
-       \r
-               T((TSTR("Erased block %d" TENDSTR),blockNo));\r
-       }\r
-       else\r
-       {\r
-               yaffs_RetireBlock(dev,blockNo);\r
-               T((TSTR("**>> Block %d retired" TENDSTR),blockNo));\r
-       }\r
-}\r
-\r
 \r
 static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve)\r
 {\r
@@ -1709,10 +1734,16 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve)
        if(dev->allocationBlock < 0)\r
        {\r
                // Get next block to allocate off\r
-               dev->allocationBlock = yaffs_FindBlockForAllocation(dev,useReserve);\r
+               dev->allocationBlock = yaffs_FindBlockForAllocation(dev);\r
                dev->allocationPage = 0;\r
        }\r
        \r
+       if(!useReserve &&  dev->nErasedBlocks <= YAFFS_RESERVED_BLOCKS)\r
+       {\r
+               // Not enough space to allocate unless we're allowed to use the reserve.\r
+               return -1;\r
+       }\r
+       \r
        // Next page please....\r
        if(dev->allocationBlock >= 0)\r
        {\r
@@ -1733,12 +1764,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve)
                        dev->allocationBlock = -1;\r
                }\r
 \r
-#ifdef YAFFS_PARANOID\r
-               if(yaffs_CheckChunkErased(dev,retVal) == YAFFS_FAIL)\r
-               {\r
-                       T((TSTR("..................Trying to allocate non-erased page %d" TENDSTR),retVal));\r
-               }\r
-#endif         \r
+\r
                return retVal;\r
                \r
        }\r
@@ -2373,7 +2399,7 @@ int yaffs_WriteChunkDataToObject(yaffs_Object *in,int chunkInInode, const __u8 *
 // UpdateObjectHeader updates the header on NAND for an object.\r
 // If name is not NULL, then that new name is used.\r
 //\r
-int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name)\r
+int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force)\r
 {\r
 \r
        yaffs_Device *dev = in->myDev;\r
@@ -2388,7 +2414,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name)
     yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bufferNew;\r
     yaffs_ObjectHeader *ohOld = (yaffs_ObjectHeader *)bufferOld;\r
     \r
-    if(!in->fake)\r
+    if(!in->fake || force)\r
     {\r
   \r
                yaffs_CheckGarbageCollection(dev);              \r
@@ -2413,17 +2439,29 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name)
                oh->st_ctime = in->st_ctime;\r
                oh->st_rdev = in->st_rdev;\r
        \r
-               oh->parentObjectId = in->parent->objectId;\r
+               if(in->parent)\r
+               {\r
+                       oh->parentObjectId = in->parent->objectId;\r
+               }\r
+               else\r
+               {\r
+                       oh->parentObjectId = 0;\r
+               }\r
+               \r
                oh->sum = in->sum;\r
                if(name && *name)\r
                {\r
                        memset(oh->name,0,YAFFS_MAX_NAME_LENGTH + 1);\r
                        strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH);\r
                }\r
-               else\r
+               else if(prevChunkId)\r
                {       \r
                        memcpy(oh->name, ohOld->name,YAFFS_MAX_NAME_LENGTH + 1);\r
                }\r
+               else\r
+               {\r
+                       memset(oh->name,0,YAFFS_MAX_NAME_LENGTH + 1);   \r
+               }\r
        \r
                switch(in->variantType)\r
                {\r
@@ -2746,7 +2784,7 @@ int yaffs_FlushFile(yaffs_Object *in)
        \r
                in->st_mtime = CURRENT_TIME;\r
 \r
-               retVal = yaffs_UpdateObjectHeader(in,NULL);\r
+               retVal = yaffs_UpdateObjectHeader(in,NULL,0);\r
        }\r
        else\r
        {\r
@@ -2896,7 +2934,7 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj)
                yaffs_HashObject(hl);\r
                \r
                // Update the hardlink which has become an object\r
-               yaffs_UpdateObjectHeader(hl,NULL);\r
+               yaffs_UpdateObjectHeader(hl,NULL,0);\r
 \r
                // Finally throw away the deleted object\r
                yaffs_DeleteChunk(obj->myDev,obj->chunkId);\r
@@ -3117,6 +3155,11 @@ static int yaffs_Scan(yaffs_Device *dev)
                                if(in->variant.fileVariant.scannedFileSize <endpos)\r
                                {\r
                                        in->variant.fileVariant.scannedFileSize = endpos;\r
+#ifndef CONFIG_YAFFS_USE_HEADER_FILE_SIZE\r
+                                               in->variant.fileVariant.fileSize =      \r
+                                                       in->variant.fileVariant.scannedFileSize;\r
+#endif\r
+\r
                                }\r
                                //T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId));  \r
                        }\r
@@ -3153,7 +3196,25 @@ static int yaffs_Scan(yaffs_Device *dev)
                                        }\r
                                }\r
                                \r
-                               if(!in->valid)\r
+                               if(!in->valid &&\r
+                                  (tags.objectId == YAFFS_OBJECTID_ROOT ||\r
+                                   tags.objectId == YAFFS_OBJECTID_LOSTNFOUND))\r
+                               {\r
+                                       // We only load some info, don't fiddle with directory structure\r
+                                       in->valid = 1;\r
+                                       in->variantType = oh->type;\r
+       \r
+                                       in->st_mode  = oh->st_mode;\r
+                                       in->st_uid   = oh->st_uid;\r
+                                       in->st_gid   = oh->st_gid;\r
+                                       in->st_atime = oh->st_atime;\r
+                                       in->st_mtime = oh->st_mtime;\r
+                                       in->st_ctime = oh->st_ctime;\r
+                                       in->st_rdev = oh->st_rdev;\r
+                                       in->chunkId  = chunk;\r
+\r
+                               }\r
+                               else if(!in->valid)\r
                                {\r
                                        // we need to load this info\r
                                \r
@@ -3202,7 +3263,9 @@ static int yaffs_Scan(yaffs_Device *dev)
                                                case YAFFS_OBJECT_TYPE_UNKNOWN:         // Todo got a problem\r
                                                        break;\r
                                                case YAFFS_OBJECT_TYPE_FILE:\r
+#ifdef CONFIG_YAFFS_USE_HEADER_FILE_SIZE\r
                                                        in->variant.fileVariant.fileSize = oh->fileSize;\r
+#endif\r
                                                        break;\r
                                                case YAFFS_OBJECT_TYPE_HARDLINK:\r
                                                        in->variant.hardLinkVariant.equivalentObjectId = oh->equivalentObjectId;\r
@@ -3496,7 +3559,7 @@ int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr)
        \r
        if(valid & ATTR_SIZE) yaffs_ResizeFile(obj,attr->ia_size);\r
        \r
-       yaffs_UpdateObjectHeader(obj,NULL);\r
+       yaffs_UpdateObjectHeader(obj,NULL,1);\r
        \r
        return YAFFS_OK;\r
        \r
index 3f1e9241ac4930a172a383c095d3b402706f096c..7f74b6f79598b78ec9e9cc1172bb3f4b9d6c56c4 100644 (file)
@@ -12,7 +12,7 @@
  * published by the Free Software Foundation.
  *
  */
- #ifdef YAFFS_MTD_ENABLED
+#ifdef CONFIG_YAFFS_MTD_ENABLED
  
 #include "yportenv.h"
 
@@ -100,5 +100,5 @@ int nandmtd_InitialiseNAND(yaffs_Device *dev)
        return YAFFS_OK;
 }
 
-#endif // YAFFS_MTD_ENABLED
+#endif // CONFIG_YAFFS_MTD_ENABLED
 
index 2c8d0bce05bb43249f622c329d7d4aecc11ae8ac..2aebfe981de65c8dadcb7b0a9f798b8e8b4e5eae 100644 (file)
  // Since this creates the RAM block at start up it is pretty useless for testing the scanner.
 
 #ifndef __KERNEL__
-#define YAFFS_RAM_ENABLED
+#define CONFIG_YAFFS_RAM_ENABLED
 #endif
 
-#ifdef YAFFS_RAM_ENABLED
+#ifdef CONFIG_YAFFS_RAM_ENABLED
 
 #include "yportenv.h"
 
index 551fec2a0d6716be1461e4a817d5cac6202fa002..b217ad6fd7c425f2717d4fa0b826d8ff227d6deb 100755 (executable)
Binary files a/yaffsdev and b/yaffsdev differ
index 23d8f0c31cbf4d1fd37af02742892e79ca3b8883..ff4b7e6f8f29e8dcad3fc5e3d2a1402a347756c0 100644 (file)
@@ -160,8 +160,41 @@ void TestTime(yaffs_Device *dev)
        printf("Start\n");
        
        
-       
+       // Test the problem of:
+       // Create file
+       // Delete file
+       // Create file with same name
+       // Delete file <== crash
 
+       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");
+       }
+       yaffs_Unlink(yaffs_Root(dev),"Name1");
+
+
+       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");
+       }
+       yaffs_Unlink(yaffs_Root(dev),"Name1");
+       
+       
+       
+       // Other tests
+       
        f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1");
        if(f)
        {
index e57aca8e3e8ba2d3e1c89298ce0f4cc8bbfedba2..c0bc23340855fb929289433cbb566494900fe0ae 100644 (file)
Binary files a/yaffsdev.proj and b/yaffsdev.proj differ