Mercurial > yaffs-ecoscentric
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; } }
