*** empty log message ***
authorcharles <charles>
Wed, 20 Oct 2004 20:12:43 +0000 (20:12 +0000)
committercharles <charles>
Wed, 20 Oct 2004 20:12:43 +0000 (20:12 +0000)
Makefile
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h

index e748baa4e8af101a6ce3e5ad34603d8b97ec854e..9b084cbde6b8aebe312c7507f3632d6f228361fe 100644 (file)
--- a/Makefile
+++ b/Makefile
 # it under the terms of the GNU General Public License version 2 as
 # published by the Free Software Foundation.
 #
-# $Id: Makefile,v 1.12 2003-08-20 03:53:39 charles Exp $
+# $Id: Makefile,v 1.13 2004-10-20 20:12:43 charles Exp $
 #
 
 ## Change or override  KERNELDIR to your kernel
 ## comment out USE_xxxx if you don't want these features.
 
-KERNELDIR = /usr/src/kernel-headers-2.4.18
+KERNELDIR = /opt/2.4.27/linux-2.4.27/
 
 ## Change if you are using a cross-compiler
 MAKETOOLS = 
@@ -108,7 +108,7 @@ YAFFS_CONFIGS = $(USE_RAM_FOR_TEST) $(USE_MTD) $(USE_GENERIC_RW) $(USE_HEADER_FI
                 $(ENABLE_SHORT_NAMES_IN_RAM) $(USE_NANDECC) $(USE_OLD_MTD) $(USE_WRONGECC)
 
 
-CFLAGS = -D__KERNEL__ -DMODULE $(YAFFS_CONFIGS)  -I$(KERNELDIR)/include -O2 -Wall
+CFLAGS = -D__KERNEL__ -DMODULE  $(YAFFS_CONFIGS)  -I $(KERNELDIR)/include -O2 -Wall
 
 
 OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o yaffs_ecc.o
index 099a1083122eb1ff1f1cccc3c9fea0a4c2e84260..00bb742cf4aff519208c626eab8a167cf458b33b 100644 (file)
  * * Nick Bane for numerous patches.
  * * Nick Bane for 2.5/2.6 integration.
  * * Andras Toth for mknod rdev issue.
+ * * Michael Fischer for finding the problem with inode inconsistency.
  * * Some code bodily lifted from JFFS2.
  */
 
 
-const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.34 2004-09-20 22:00:20 charles Exp $";
+const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.35 2004-10-20 20:12:43 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 
@@ -364,15 +365,29 @@ static void yaffs_put_inode(struct inode *inode)
 // clear is called to tell the fs to release any per-inode data it holds
 static void yaffs_clear_inode(struct inode *inode)
 {
-       yaffs_Object *obj = yaffs_InodeToObject(inode);
+       yaffs_Object *obj;
+       yaffs_Device *dev;
+       
+       obj = yaffs_InodeToObject(inode);
        
        T(YAFFS_TRACE_OS,("yaffs_clear_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count),
                obj ? "object exists" : "null object"));        
 
        if(obj)
        {
+               dev = obj->myDev;
+               yaffs_GrossLock(dev);
+               
+               // Clear the association between the inode ant the yaffs_Object.
                obj->myInode = NULL;
-               inode->u.generic_ip = NULL;     
+               inode->u.generic_ip = NULL;
+               
+               // If the object freeing was deferred, then the real free happens now.
+               // This should fix the inode inconsistency problem.
+               
+               yaffs_HandleDeferedFree(obj);
+               
+               yaffs_GrossUnlock(dev);
        }
        
        
index 91fb73c598fda9e44ed5052abc06a0ff8de1b38d..7c97b314bfd1d2be9d5ce70e42e0324099edc728 100644 (file)
@@ -14,7 +14,7 @@
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.36 2004-10-10 17:54:59 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.37 2004-10-20 20:12:43 charles Exp $";
 
 #include "yportenv.h"
 
@@ -1444,6 +1444,16 @@ static void yaffs_FreeObject(yaffs_Object *tn)
 
        yaffs_Device *dev = tn->myDev;
        
+#ifdef  __KERNEL__
+       if(tn->myInode)
+       {
+               // We're still hooked up to a cached inode.
+               // Don't delete now, but mark for later deletion
+               tn->deferedFree = 1;
+               return;
+       }
+#endif
+       
        yaffs_UnhashObject(tn);
        
        // Link into the free list.
@@ -1453,6 +1463,18 @@ static void yaffs_FreeObject(yaffs_Object *tn)
 }
 
 
+#ifdef __KERNEL__
+
+void yaffs_HandleDeferedFree(yaffs_Object *obj)
+{
+       if(obj->deferedFree)
+       {
+          yaffs_FreeObject(obj);
+       }
+}
+
+#endif
+
 
 
 static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
@@ -3743,12 +3765,14 @@ static int yaffs_DoGenericObjectDeletion(yaffs_Object *in)
        
        yaffs_RemoveObjectFromDirectory(in);
        yaffs_DeleteChunk(in->myDev,in->chunkId,1);
+#if 0
 #ifdef __KERNEL__
        if(in->myInode)
        {
                in->myInode->u.generic_ip = NULL;
-               in->myInode = 0;
+               in->myInode = NULL;
        }
+#endif
 #endif
        yaffs_FreeObject(in);
        return YAFFS_OK;
@@ -3786,6 +3810,8 @@ static int yaffs_UnlinkFile(yaffs_Object *in)
 #ifdef __KERNEL__
                if(!in->myInode)
                {
+                       // Might be open at present,
+                       // Caught by delete_inode in yaffs_fs.c
                        immediateDeletion = 1;
 
                }
index 4aafe1dae791dc5b3a879ccd1d4bae9a82142c73..eb1d8b8ee4cf716391062f49e413f7275510941b 100644 (file)
@@ -14,7 +14,7 @@
  *
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  *
- * $Id: yaffs_guts.h,v 1.17 2004-10-10 17:54:59 charles Exp $
+ * $Id: yaffs_guts.h,v 1.18 2004-10-20 20:12:43 charles Exp $
  */
 
 #ifndef __YAFFS_GUTS_H__
@@ -360,6 +360,8 @@ struct  yaffs_ObjectStruct
 
 #ifdef __KERNEL__
        struct inode *myInode;
+       __u8  deferedFree;   // YAFFS has removed the object from NAND, but it is being kept
+                            // Alive until the inode is cleared to prevent inode inconsistencies.
 #endif
 
 
@@ -575,6 +577,9 @@ yaffs_Object *yaffs_LostNFound(yaffs_Device *dev);
 void  yfsd_WinFileTimeNow(__u32 target[2]);
 #endif
 
+#ifdef __KERNEL__
+void yaffs_HandleDeferedFree(yaffs_Object *obj);
+#endif
 
 // Debug dump 
 int yaffs_DumpObject(yaffs_Object *obj);