From b91298ceff82f7f47539ec0308c6b310e1d9e755 Mon Sep 17 00:00:00 2001 From: charles Date: Wed, 20 Oct 2004 20:12:43 +0000 Subject: [PATCH] *** empty log message *** --- Makefile | 6 +++--- yaffs_fs.c | 21 ++++++++++++++++++--- yaffs_guts.c | 30 ++++++++++++++++++++++++++++-- yaffs_guts.h | 7 ++++++- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index e748baa..9b084cb 100644 --- a/Makefile +++ b/Makefile @@ -12,13 +12,13 @@ # 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 diff --git a/yaffs_fs.c b/yaffs_fs.c index 099a108..00bb742 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -24,11 +24,12 @@ * * 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); } diff --git a/yaffs_guts.c b/yaffs_guts.c index 91fb73c..7c97b31 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -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; } diff --git a/yaffs_guts.h b/yaffs_guts.h index 4aafe1d..eb1d8b8 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -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); -- 2.30.2