changeset 231:66bdb92cfbde

Some fixes and add NOR integrity code
author charles
date Fri, 07 Nov 2008 00:32:22 +0000
parents 99c5e0826821
children 26a5a095ef02
files direct/Makefile direct/dtest.c direct/fsx_test/Makefile direct/fsx_test/yaffs_fsx.c direct/yaffscfg2k.c yaffs_guts.c yaffs_guts.h yaffs_tagscompat.c
diffstat 8 files changed, 310 insertions(+), 141 deletions(-) [+]
line wrap: on
line diff
--- a/direct/Makefile
+++ b/direct/Makefile
@@ -20,25 +20,29 @@
 
 CFLAGS =      -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2  
 CFLAGS +=     -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES -DNO_Y_INLINE
-CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS)
-#CFLAGS+=    -fstack-check -O0
+CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing -fno-strict-aliasing
+CFLAGS +=    -O0
+#CFLAGS +=    -DVALGRIND_TEST
 
 #CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
 #CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
 
 
-DIRECTTESTOBJS = dtest.o yaffscfg2k.o yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
+COMMONTESTOBJS = yaffscfg2k.o yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
 		 yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
 		 yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o yaffs_nand.o \
-		 yaffs_checkptrw.o  yaffs_qsort.o
+		 yaffs_checkptrw.o  yaffs_qsort.o\
+		 yaffs_norif1.o  ynorsim.o nor_stress.o
 #		 yaffs_checkptrwtest.o\
-		 
+
+DIRECTTESTOBJS = $(COMMONTESTOBJS) dtest.o
+YAFFSTESTOBJS  = $(COMMONTESTOBJS) yaffs_test.o
 
 BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o
 
 #ALLOBJS =  dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o yaffs_ramem2k.o
 
-ALLOBJS = $(DIRECTTESTOBJS) $(BOOTTESTOBJS)
+ALLOBJS = $(sort $(DIRECTTESTOBJS) $(YAFFSTESTOBJS))
 
 SYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \
           yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h  yaffs_nandemul2k.h \
@@ -48,7 +52,7 @@ SYMLINKS = devextras.h yaffs_ecc.c yaffs
 
 #all: directtest2k boottest
 
-all: directtest2k
+all: directtest2k yaffs_test
 
 $(ALLOBJS): %.o: %.c
 	gcc -c $(CFLAGS) -o $@ $<
@@ -59,6 +63,9 @@ all: directtest2k
 directtest2k: $(SYMLINKS) $(DIRECTTESTOBJS)
 	gcc -o $@ $(DIRECTTESTOBJS)
 
+yaffs_test: $(SYMLINKS) $(YAFFSTESTOBJS)
+	gcc -o $@ $(YAFFSTESTOBJS)
+
 
 boottest: $(SYMLINKS) $(BOOTTESTOBJS)
 	gcc -o $@ $(BOOTTESTOBJS)
--- a/direct/dtest.c
+++ b/direct/dtest.c
@@ -22,6 +22,8 @@
 
 #include "yaffsfs.h"
 
+#include "nor_stress.h"
+
 void dumpDir(const char *dname);
 
 char xx[600];
@@ -2284,6 +2286,7 @@ void random_small_file_test(const char *
 
 int main(int argc, char *argv[])
 {
+
 	//return long_test(argc,argv);
 	
 	//return cache_read_test();
--- a/direct/fsx_test/Makefile
+++ b/direct/fsx_test/Makefile
@@ -31,6 +31,7 @@ FSXTESTOBJS = yaffs_fsx.o yaffscfg2k.o y
 		 yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
 		 yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o yaffs_nand.o \
 		 yaffs_checkptrw.o  yaffs_qsort.o \
+		 yaffs_norif1.o ynorsim.o
 #		 yaffs_checkptrwtest.o\
 		 
 
@@ -48,7 +49,8 @@ YAFFSSYMLINKS = devextras.h yaffs_ecc.c 
 
 YAFFSDIRECTSYMLINKS =  yaffscfg2k.c yaffs_fileem2k.c yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
 		       yaffs_fileem2k.h yaffsfs.h yaffs_malloc.h yaffs_ramdisk.h ydirectenv.h \
-		       yaffscfg.h yaffs_fileem.c yaffs_flashif.c yaffs_ramdisk.c yaffs_ramem2k.c
+		       yaffscfg.h yaffs_fileem.c yaffs_flashif.c yaffs_ramdisk.c yaffs_ramem2k.c\
+		       yaffs_norif1.c yaffs_norif1.h ynorsim.c ynorsim.h
 
 
 
--- a/direct/fsx_test/yaffs_fsx.c
+++ b/direct/fsx_test/yaffs_fsx.c
@@ -130,11 +130,7 @@ int	writebdy = 1;			/* -w flag */
 long	monitorstart = -1;		/* -m flag */
 long	monitorend = -1;		/* -m flag */
 int	lite = 0;			/* -L flag */
-<<<<<<< yaffs_fsx.c
-long	numops = 5000;			/* -N flag */
-=======
-long	numops = /*-1 */ 100000;			/* -N flag */
->>>>>>> 1.3
+long	numops = /*-1 */ 10000000;			/* -N flag */
 int	randomoplen = 1;		/* -O flag disables it */
 int	seed = 1;			/* -S flag */
 
@@ -778,7 +774,7 @@ getnum(char *s, char **e)
 }
 
 
-#define BASE_NAME "/flash/yaffs2"
+#define BASE_NAME "/flash/yaffs1"
 
 int
 main(int argc, char **argv)
--- a/direct/yaffscfg2k.c
+++ b/direct/yaffscfg2k.c
@@ -22,18 +22,22 @@
 #include "yaffsfs.h"
 #include "yaffs_fileem2k.h"
 #include "yaffs_nandemul2k.h"
+#include "yaffs_norif1.h"
 
 #include <errno.h>
 
 unsigned yaffs_traceMask = 
 
 	YAFFS_TRACE_SCAN |  
-	YAFFS_TRACE_GC | YAFFS_TRACE_GC_DETAIL | 
+	YAFFS_TRACE_GC |
 	YAFFS_TRACE_ERASE | 
+	YAFFS_TRACE_ERROR | 
 	YAFFS_TRACE_TRACING | 
 	YAFFS_TRACE_ALLOCATE | 
 	YAFFS_TRACE_CHECKPOINT |
 	YAFFS_TRACE_BAD_BLOCKS |
+
+/*	YAFFS_TRACE_VERIFY |  */
 	
 	0;
         
@@ -108,26 +112,20 @@ void yaffsfs_LocalInitialisation(void)
 #include "yaffs_flashif2.h"
 #include "yaffs_nandemul2k.h"
 
-static yaffs_Device ramDev;
-static yaffs_Device bootDev;
+static yaffs_Device ram1Dev;
+static yaffs_Device nand2;
 static yaffs_Device flashDev;
 static yaffs_Device ram2kDev;
+static yaffs_Device m18_1Dev;
 
 static yaffsfs_DeviceConfiguration yaffsfs_config[] = {
-#if 0
-	{ "/ram", &ramDev},
-	{ "/boot", &bootDev},
-	{ "/flash/", &flashDev},
-	{ "/ram2k", &ram2kDev},
-	{(void *)0,(void *)0}
-#else
-	//{ "/", &ramDev},
-	{ "/flash/yaffs1", &bootDev},
-	{ "/flash/yaffs2", &flashDev},
+
+	{ "/ram1", &ram1Dev},
+	{ "/M18-1", &m18_1Dev},
+	{ "/yaffs2", &flashDev},
 	{ "/ram2k", &ram2kDev},
 	{ "/flash/bigblock", &flashDev},
 	{(void *)0,(void *)0} /* Null entry to terminate list */
-#endif
 };
 
 
@@ -138,36 +136,36 @@ int yaffs_StartUp(void)
 	yaffsfs_LocalInitialisation();
 	
 	// Set up devices
-	// /ram
-	memset(&ramDev,0,sizeof(ramDev));
-	ramDev.totalBytesPerChunk = 512;
-	ramDev.nChunksPerBlock = 32;
-	ramDev.nReservedBlocks = 2; // Set this smaller for RAM
-	ramDev.startBlock = 0; // Can use block 0
-	ramDev.endBlock = 127; // Last block in 2MB.	
-	//ramDev.useNANDECC = 1;
-	ramDev.nShortOpCaches = 0;	// Disable caching on this device.
-	ramDev.genericDevice = (void *) 0;	// Used to identify the device in fstat.
-	ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
-	ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
-	ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
-	ramDev.initialiseNAND = yramdisk_InitialiseNAND;
+	// /ram1   ram, yaffs1
+	memset(&ram1Dev,0,sizeof(ram1Dev));
+	ram1Dev.totalBytesPerChunk = 512;
+	ram1Dev.nChunksPerBlock = 32;
+	ram1Dev.nReservedBlocks = 2; // Set this smaller for RAM
+	ram1Dev.startBlock = 0; // Can use block 0
+	ram1Dev.endBlock = 127; // Last block in 2MB.	
+	//ram1Dev.useNANDECC = 1;
+	ram1Dev.nShortOpCaches = 0;	// Disable caching on this device.
+	ram1Dev.genericDevice = (void *) 0;	// Used to identify the device in fstat.
+	ram1Dev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
+	ram1Dev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
+	ram1Dev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
+	ram1Dev.initialiseNAND = yramdisk_InitialiseNAND;
 
-	// /boot (yaffs1)
-	memset(&bootDev,0,sizeof(bootDev));
-	bootDev.totalBytesPerChunk = 512;
-	bootDev.nChunksPerBlock = 32;
-	bootDev.nReservedBlocks = 5;
-	bootDev.startBlock = 0; // Can use block 0
-	bootDev.endBlock = 63; // Last block
-	//bootDev.useNANDECC = 0; // use YAFFS's ECC
-	bootDev.nShortOpCaches = 10; // Use caches
-	bootDev.genericDevice = (void *) 1;	// Used to identify the device in fstat.
-	bootDev.writeChunkToNAND = yflash_WriteChunkToNAND;
-	bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND;
-	bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND;
-	bootDev.initialiseNAND = yflash_InitialiseNAND;
-
+	// /M18-1 yaffs1 on M18 nor sim
+	memset(&m18_1Dev,0,sizeof(m18_1Dev));
+	m18_1Dev.totalBytesPerChunk = 1024;
+	m18_1Dev.nChunksPerBlock =248;
+	m18_1Dev.nReservedBlocks = 2;
+	m18_1Dev.startBlock = 0; // Can use block 0
+	m18_1Dev.endBlock = 127; // Last block
+	m18_1Dev.useNANDECC = 0; // use YAFFS's ECC
+	m18_1Dev.nShortOpCaches = 10; // Use caches
+	m18_1Dev.genericDevice = (void *) 1;	// Used to identify the device in fstat.
+	m18_1Dev.writeChunkToNAND = ynorif1_WriteChunkToNAND;
+	m18_1Dev.readChunkFromNAND = ynorif1_ReadChunkFromNAND;
+	m18_1Dev.eraseBlockInNAND = ynorif1_EraseBlockInNAND;
+	m18_1Dev.initialiseNAND = ynorif1_InitialiseNAND;
+	m18_1Dev.deinitialiseNAND = ynorif1_DeinitialiseNAND;
 
 
 	// /flash (yaffs2)
--- a/yaffs_guts.c
+++ b/yaffs_guts.c
@@ -97,6 +97,7 @@ static void yaffs_VerifyFreeChunks(yaffs
 
 static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in);
 
+static void yaffs_VerifyDirectory(yaffs_Object *directory);
 #ifdef YAFFS_PARANOID
 static int yaffs_CheckFileSanity(yaffs_Object * in);
 #else
@@ -721,12 +722,6 @@ static void yaffs_VerifyFile(yaffs_Objec
 
 }
 
-static void yaffs_VerifyDirectory(yaffs_Object *obj)
-{
-	if(obj && yaffs_SkipVerification(obj->myDev))
-		return;
-	
-}
 
 static void yaffs_VerifyHardLink(yaffs_Object *obj)
 {
@@ -1108,7 +1103,7 @@ static __u16 yaffs_CalcNameSum(const YCH
 	__u16 sum = 0;
 	__u16 i = 1;
 
-	YUCHAR *bname = (YUCHAR *) name;
+	const YUCHAR *bname = (const YUCHAR *) name;
 	if (bname) {
 		while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH/2))) {
 
@@ -1121,12 +1116,14 @@ static __u16 yaffs_CalcNameSum(const YCH
 			bname++;
 		}
 	}
+	
 	return sum;
 }
 
 static void yaffs_SetObjectName(yaffs_Object * obj, const YCHAR * name)
 {
 #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
+	memset(obj->shortName,0,sizeof (YCHAR) * (YAFFS_SHORT_NAME_LENGTH+1)); 
 	if (name && yaffs_strlen(name) <= YAFFS_SHORT_NAME_LENGTH) {
 		yaffs_strcpy(obj->shortName, name);
 	} else {
@@ -1911,6 +1908,9 @@ static yaffs_Object *yaffs_AllocateEmpty
 {
 	yaffs_Object *tn = NULL;
 
+#ifdef VALGRIND_TEST
+	tn = YMALLOC(sizeof(yaffs_Object));
+#else
 	/* If there are none left make more */
 	if (!dev->freeObjects) {
 		yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS);
@@ -1921,7 +1921,9 @@ static yaffs_Object *yaffs_AllocateEmpty
 		dev->freeObjects =
 		    (yaffs_Object *) (dev->freeObjects->siblings.next);
 		dev->nFreeObjects--;
-
+	}
+#endif
+	if(tn){
 		/* Now sweeten it up... */
 
 		memset(tn, 0, sizeof(yaffs_Object));
@@ -1931,6 +1933,13 @@ static yaffs_Object *yaffs_AllocateEmpty
 		YINIT_LIST_HEAD(&(tn->hardLinks));
 		YINIT_LIST_HEAD(&(tn->hashLink));
 		YINIT_LIST_HEAD(&tn->siblings);
+		
+
+		/* Now make the directory sane */
+		if(dev->rootDir){
+			tn->parent = dev->rootDir;
+			ylist_add(&(tn->siblings),&dev->rootDir->variant.directoryVariant.children);
+		}
 
                 /* Add it to the lost and found directory.
                  * NB Can't put root or lostNFound in lostNFound so
@@ -1987,6 +1996,13 @@ static void yaffs_FreeObject(yaffs_Objec
 
 	yaffs_Device *dev = tn->myDev;
 
+	
+	if(tn->parent)
+		YBUG();
+	if(!ylist_empty(&tn->siblings))
+		YBUG();
+
+
 #ifdef  __KERNEL__
 	if (tn->myInode) {
 		/* We're still hooked up to a cached inode.
@@ -1999,11 +2015,14 @@ static void yaffs_FreeObject(yaffs_Objec
 
         yaffs_UnhashObject(tn);
 
+#ifdef VALGRIND_TEST
+	YFREE(tn);
+#else
         /* Link into the free list. */
         tn->siblings.next = (struct ylist_head *)(dev->freeObjects);
         dev->freeObjects = tn;
         dev->nFreeObjects++;
-
+#endif
 	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
 
 }
@@ -2201,6 +2220,12 @@ yaffs_Object *yaffs_CreateNewObject(yaff
 		theObject->yst_atime = theObject->yst_mtime =
 		    theObject->yst_ctime = Y_CURRENT_TIME;
 #endif
+
+#if 0
+		theObject->sum_prev = 12345;
+		theObject->sum_trailer = 6789;
+#endif
+
 		switch (type) {
 		case YAFFS_OBJECT_TYPE_FILE:
 			theObject->variant.fileVariant.fileSize = 0;
@@ -2467,9 +2492,15 @@ static int yaffs_ChangeObjectName(yaffs_
 int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
 		       yaffs_Object * newDir, const YCHAR * newName)
 {
-	yaffs_Object *obj;
-	yaffs_Object *existingTarget;
+	yaffs_Object *obj=NULL;
+	yaffs_Object *existingTarget=NULL;
 	int force = 0;
+	
+	
+	if(!oldDir || oldDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+		YBUG();
+	if(!newDir || newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+		YBUG();
 
 #ifdef CONFIG_YAFFS_CASE_INSENSITIVE
 	/* Special case for case insemsitive systems (eg. WinCE).
@@ -2481,16 +2512,11 @@ int yaffs_RenameObject(yaffs_Object * ol
 	}
 #endif
 
-	obj = yaffs_FindObjectByName(oldDir, oldName);
-	/* Check new name to long. */
-	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK &&
-	    yaffs_strlen(newName) > YAFFS_MAX_ALIAS_LENGTH)
+	else if (yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
 	  /* ENAMETOOLONG */
 	  return YAFFS_FAIL;
-	else if (obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK &&
-		 yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
-	  /* ENAMETOOLONG */
-	  return YAFFS_FAIL;
+
+	obj = yaffs_FindObjectByName(oldDir, oldName);
 
 	if (obj && obj->renameAllowed) {
 
@@ -2846,7 +2872,8 @@ static int yaffs_FindBlockForAllocation(
 
 static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
 {
-	if(!dev->nCheckpointBlocksRequired){
+	if(!dev->nCheckpointBlocksRequired &&
+	   dev->isYaffs2){
 		/* Not a valid value so recalculate */
 		int nBytes = 0;
 		int nBlocks;
@@ -2885,9 +2912,14 @@ static int yaffs_CheckSpaceForAllocation
 	int reservedBlocks = dev->nReservedBlocks;
 	int checkpointBlocks;
 	
-	checkpointBlocks =  yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
-	if(checkpointBlocks < 0)
-		checkpointBlocks = 0;
+	if(dev->isYaffs2){
+		checkpointBlocks =  yaffs_CalcCheckpointBlocksRequired(dev) - 
+				    dev->blocksInCheckpoint;
+		if(checkpointBlocks < 0)
+			checkpointBlocks = 0;
+	} else {
+		checkpointBlocks =0;
+	}
 	
 	reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
 	
@@ -3063,9 +3095,11 @@ static int yaffs_GarbageCollectBlock(yaf
 					    tags.objectId, tags.chunkId, tags.byteCount));
 				}
 
-				if (object && object->deleted
-				    && tags.chunkId != 0) {
-					/* Data chunk in a deleted file, throw it away
+				if (object && 
+				    object->deleted &&
+				    object->softDeleted &&
+				    tags.chunkId != 0) {
+					/* Data chunk in a soft deleted file, throw it away
 					 * It's a soft deleted data chunk,
 					 * No need to copy this, just forget about it and 
 					 * fix up the object.
@@ -3640,6 +3674,14 @@ static int yaffs_WriteChunkDataToObject(
 	newTags.serialNumber =
 	    (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1;
 	newTags.byteCount = nBytes;
+	
+	if(nBytes < 1 || nBytes > dev->totalBytesPerChunk){
+	  T(YAFFS_TRACE_ERROR,
+	  (TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
+	  while(1){}
+        }
+	
+	
 
 	newChunkId =
 	    yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
@@ -4796,6 +4838,12 @@ int yaffs_WriteDataToFile(yaffs_Object *
 		//chunk = offset / dev->nDataBytesPerChunk + 1;
 		//start = offset % dev->nDataBytesPerChunk;
 		yaffs_AddrToChunk(dev,offset,&chunk,&start);
+		
+		if(chunk * dev->nDataBytesPerChunk + start != offset ||
+		   start >= dev->nDataBytesPerChunk){
+		   T(YAFFS_TRACE_ERROR,(TSTR("AddrToChunk of offset %d gives chunk %d start %d"TENDSTR),
+		   			(int)offset, chunk,start));
+		}
 		chunk++;
 
 		/* OK now check for the curveball where the start and end are in
@@ -5149,62 +5197,66 @@ static int yaffs_DoGenericObjectDeletion
  * and the inode associated with the file.
  * It does not delete the links associated with the file.
  */
+ 
 static int yaffs_UnlinkFile(yaffs_Object * in)
 {
 
 	int retVal;
 	int immediateDeletion = 0;
 
-	if (1) {
 #ifdef __KERNEL__
-		if (!in->myInode) {
-			immediateDeletion = 1;
-
-		}
+	if (!in->myInode) {
+		immediateDeletion = 1;
+	}
 #else
-		if (in->inUse <= 0) {
-			immediateDeletion = 1;
-
-		}
+	if (in->inUse <= 0) {
+		immediateDeletion = 1;
+	}
 #endif
-		if (immediateDeletion) {
-			retVal =
-			    yaffs_ChangeObjectName(in, in->myDev->deletedDir,
-						   _Y("deleted"), 0, 0);
-			T(YAFFS_TRACE_TRACING,
-			  (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
-			   in->objectId));
-			in->deleted = 1;
-			in->myDev->nDeletedFiles++;
-			if (0 && in->myDev->isYaffs2) {
-				yaffs_ResizeFile(in, 0);
-			}
-			yaffs_SoftDeleteFile(in);
-		} else {
-			retVal =
-			    yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,
-						   _Y("unlinked"), 0, 0);
+
+	if (immediateDeletion) {
+		retVal =
+		    yaffs_ChangeObjectName(in, in->myDev->deletedDir,
+					   _Y("deleted"), 0, 0);
+		T(YAFFS_TRACE_TRACING,
+		  (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
+		   in->objectId));
+		in->deleted = 1;
+		in->myDev->nDeletedFiles++;
+		if (1 || in->myDev->isYaffs2) {
+			yaffs_ResizeFile(in, 0);
 		}
-
-	}
+		yaffs_SoftDeleteFile(in);
+	} else {
+		retVal =
+		    yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,
+					   _Y("unlinked"), 0, 0);
+	}
+
+
 	return retVal;
 }
 
 int yaffs_DeleteFile(yaffs_Object * in)
 {
 	int retVal = YAFFS_OK;
+	int deleted = in->deleted;
+	
+	yaffs_ResizeFile(in,0);
 
 	if (in->nDataChunks > 0) {
-		/* Use soft deletion if there is data in the file */
+		/* Use soft deletion if there is data in the file.
+		 * That won't be the case if it has been resized to zero.
+		 */
 		if (!in->unlinked) {
 			retVal = yaffs_UnlinkFile(in);
 		}
 		if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
-			in->deleted = 1;
+			in->deleted = deleted = 1;
 			in->myDev->nDeletedFiles++;
 			yaffs_SoftDeleteFile(in);
 		}
-		return in->deleted ? YAFFS_OK : YAFFS_FAIL;
+		return deleted ? YAFFS_OK : YAFFS_FAIL;
 	} else {
 		/* The file has no data chunks so we toss it immediately */
 		yaffs_FreeTnode(in->myDev, in->variant.fileVariant.top);
@@ -5238,7 +5290,7 @@ static int yaffs_DeleteHardLink(yaffs_Ob
         /* remove this hardlink from the list assocaited with the equivalent
          * object
          */
-        ylist_del(&in->hardLinks);
+        ylist_del_init(&in->hardLinks);
         return yaffs_DoGenericObjectDeletion(in);
 }
 
@@ -5799,10 +5851,12 @@ static int yaffs_Scan(yaffs_Device * dev
 						break;
 					}
 
-					if (parent == dev->deletedDir) {
+/*
+ 					if (parent == dev->deletedDir) {
 						yaffs_DestroyObject(in);
 						bi->hasShrinkHeader = 1;
 					}
+*/
 				}
 			}
 		}
@@ -6627,15 +6681,91 @@ static int yaffs_ScanBackwards(yaffs_Dev
 
 /*------------------------------  Directory Functions ----------------------------- */
 
+static void yaffs_VerifyObjectInDirectory(yaffs_Object *obj)
+{
+        struct ylist_head *lh;
+        yaffs_Object *listObj;
+        
+        int count = 0;
+
+	if(!obj)
+		YBUG();
+
+        if(yaffs_SkipVerification(obj->myDev))
+                return;
+
+	if(!obj->parent)
+		YBUG();
+		
+	if(obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+		YBUG();
+	
+        /* Iterate through the objects in each hash entry */
+         
+        ylist_for_each(lh, &obj->parent->variant.directoryVariant.children) {
+		if (lh) {
+                        listObj = ylist_entry(lh, yaffs_Object, siblings);
+			yaffs_VerifyObject(listObj);
+			if(obj == listObj)
+				count ++;
+                }
+	 }
+	 
+	 if(count != 1)
+	 	YBUG();
+	 
+
+}
+
+static void yaffs_VerifyDirectory(yaffs_Object *directory)
+{
+
+        struct ylist_head *lh;
+        yaffs_Object *listObj;
+        
+	if(!directory)
+		YBUG();
+
+        if(yaffs_SkipVerification(directory->myDev))
+                return;
+
+		
+	if(directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+		YBUG();
+	
+        /* Iterate through the objects in each hash entry */
+         
+        ylist_for_each(lh, &directory->variant.directoryVariant.children) {
+		if (lh) {
+                        listObj = ylist_entry(lh, yaffs_Object, siblings);
+			if(listObj->parent != directory)
+				YBUG();
+			yaffs_VerifyObjectInDirectory(listObj);
+                }
+	 }
+	 
+}
+
+
 static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj)
 {
 	yaffs_Device *dev = obj->myDev;
-	
+	yaffs_Object *parent;
+	
+        yaffs_VerifyObjectInDirectory(obj);
+	parent = obj->parent;
+	
+	yaffs_VerifyDirectory(parent);
+
         if(dev && dev->removeObjectCallback)
                 dev->removeObjectCallback(obj);
+
            
         ylist_del_init(&obj->siblings);
         obj->parent = NULL;
+
+	yaffs_VerifyDirectory(parent);
+
 }
 
 
@@ -6660,12 +6790,18 @@ static void yaffs_AddObjectToDirectory(y
 
         if (obj->siblings.prev == NULL) {
                 /* Not initialised */
-                YINIT_LIST_HEAD(&obj->siblings);
-
-        } else if (!ylist_empty(&obj->siblings)) {
-                /* If it is holed up somewhere else, un hook it */
-                yaffs_RemoveObjectFromDirectory(obj);
-        }
+                YBUG();
+
+        } else if (ylist_empty(&obj->siblings)) {
+        	YBUG();
+        } 
+
+
+	yaffs_VerifyDirectory(directory);
+
+	yaffs_RemoveObjectFromDirectory(obj);
+        
+        
         /* Now add it */
         ylist_add(&obj->siblings, &directory->variant.directoryVariant.children);
         obj->parent = directory;
@@ -6676,6 +6812,11 @@ static void yaffs_AddObjectToDirectory(y
 		obj->myDev->nUnlinkedFiles++;
 		obj->renameAllowed = 0;
 	}
+
+	yaffs_VerifyDirectory(directory);
+        yaffs_VerifyObjectInDirectory(obj);
+
+
 }
 
 yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
@@ -6712,6 +6853,9 @@ yaffs_Object *yaffs_FindObjectByName(yaf
                 if (i) {
                         l = ylist_entry(i, yaffs_Object, siblings);
                         
+                        if(l->parent != directory)
+                        	YBUG();
+                        
                         yaffs_CheckObjectDetailsLoaded(l);
 
 			/* Special case for lost-n-found */
@@ -7078,7 +7222,7 @@ int yaffs_GutsInitialise(yaffs_Device * 
 	/* Check geometry parameters. */
 
 	if ((!dev->inbandTags && dev->isYaffs2 && dev->totalBytesPerChunk < 1024) || 
-	    (!dev->isYaffs2 && dev->totalBytesPerChunk != 512) || 
+	    (!dev->isYaffs2 && dev->totalBytesPerChunk < 512) || 
 	    (dev->inbandTags && !dev->isYaffs2 ) ||
 	     dev->nChunksPerBlock < 2 || 
 	     dev->nReservedBlocks < 2 || 
@@ -7372,6 +7516,9 @@ void yaffs_Deinitialise(yaffs_Device * d
 
 
 		dev->isMounted = 0;
+		
+		if(dev->deinitialiseNAND)
+			dev->deinitialiseNAND(dev);
 	}
 
 }
--- a/yaffs_guts.h
+++ b/yaffs_guts.h
@@ -132,12 +132,12 @@ typedef struct {
 
 #ifndef CONFIG_YAFFS_NO_YAFFS1
 typedef struct {
-	unsigned chunkId:20;
-	unsigned serialNumber:2;
-	unsigned byteCount:10;
-	unsigned objectId:18;
-	unsigned ecc:12;
-	unsigned unusedStuff:2;
+        unsigned chunkId:20;
+        unsigned serialNumber:2;
+        unsigned byteCountLSB:10;
+        unsigned objectId:18;
+        unsigned ecc:12;
+        unsigned byteCountMSB:2;
 
 } yaffs_Tags;
 
@@ -420,10 +420,12 @@ struct yaffs_ObjectStruct {
 	__u8 deferedFree:1;	/* For Linux kernel. Object is removed from NAND, but is
 				 * still in the inode cache. Free of object is defered.
 				 * until the inode is released.
-				 */
+                                 */
 
-	__u8 serial;		/* serial number of chunk in NAND. Cached here */
-	__u16 sum;		/* sum of the name to speed searching */
+        __u8 serial;            /* serial number of chunk in NAND. Cached here */
+/*        __u16 sum_prev; */
+        __u16 sum;              /* sum of the name to speed searching */
+/*        __u16 sum_trailer; */
 
         struct yaffs_DeviceStruct *myDev;       /* The device I'm on */
 
@@ -443,10 +445,10 @@ struct yaffs_ObjectStruct {
 
 	__u32 objectId;		/* the object id value */
 
-	__u32 yst_mode;
+        __u32 yst_mode;
 
 #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
-	YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
+        YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
 #endif
 
 #ifndef __KERNEL__
@@ -572,12 +574,13 @@ struct yaffs_DeviceStruct {
 	int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev,
 				  int chunkInNAND, __u8 * data,
 				  yaffs_Spare * spare);
-	int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev,
-				 int blockInNAND);
-	int (*initialiseNAND) (struct yaffs_DeviceStruct * dev);
+        int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev,
+                                 int blockInNAND);
+        int (*initialiseNAND) (struct yaffs_DeviceStruct * dev);
+        int (*deinitialiseNAND) (struct yaffs_DeviceStruct * dev);
 
 #ifdef CONFIG_YAFFS_YAFFS2
-	int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
+        int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
 					 int chunkInNAND, const __u8 * data,
 					 const yaffs_ExtendedTags * tags);
 	int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,
--- a/yaffs_tagscompat.c
+++ b/yaffs_tagscompat.c
@@ -418,7 +418,16 @@ int yaffs_TagsCompatabilityWriteChunkWit
 	} else {
 		tags.objectId = eTags->objectId;
 		tags.chunkId = eTags->chunkId;
-		tags.byteCount = eTags->byteCount;
+
+		tags.byteCountLSB = eTags->byteCount & 0x3ff;
+		
+		if(dev->nDataBytesPerChunk >= 1024){
+			tags.byteCountMSB = (eTags->byteCount >> 10) & 3;
+		} else {
+			tags.byteCountMSB = 3;
+		}
+		
+
 		tags.serialNumber = eTags->serialNumber;
 
 		if (!dev->useNANDECC && data) {
@@ -470,7 +479,11 @@ int yaffs_TagsCompatabilityReadChunkWith
 
 				eTags->objectId = tags.objectId;
 				eTags->chunkId = tags.chunkId;
-				eTags->byteCount = tags.byteCount;
+				eTags->byteCount = tags.byteCountLSB;
+
+				if(dev->nDataBytesPerChunk >= 1024)
+					eTags->byteCount |= (((unsigned) tags.byteCountMSB) << 10);
+
 				eTags->serialNumber = tags.serialNumber;
 			}
 		}