X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=df8efbe3c6371ac22914fc444492775f8cf82c48;hp=40b7948ca6c929c16de86e66378d9b3959860040;hb=d24fe5806785f38e1f21cc1442c336152fc4b8d1;hpb=91b30c2152828de2f34760b2812d7c6cc9779e7d diff --git a/yaffs_guts.c b/yaffs_guts.c index 40b7948..df8efbe 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -12,9 +12,10 @@ */ const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.96 2009-12-03 03:42:28 charles Exp $"; + "$Id: yaffs_guts.c,v 1.107 2010-02-17 02:01:25 charles Exp $"; #include "yportenv.h" +#include "yaffs_trace.h" #include "yaffsinterface.h" #include "yaffs_guts.h" @@ -113,6 +114,12 @@ static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev, yaffs_FileStructure *fStruct, __u32 chunkId); +static void yaffs_SkipRestOfBlock(yaffs_Device *dev); +static int yaffs_VerifyChunkWritten(yaffs_Device *dev, + int chunkInNAND, + const __u8 *data, + yaffs_ExtendedTags *tags); + /* Function to calculate chunk and offset */ static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, int *chunkOut, @@ -548,8 +555,8 @@ static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh, if (!(tags && obj && oh)) { T(YAFFS_TRACE_VERIFY, - (TSTR("Verifying object header tags %x obj %x oh %x"TENDSTR), - (__u32)tags, (__u32)obj, (__u32)oh)); + (TSTR("Verifying object header tags %p obj %p oh %p"TENDSTR), + tags, obj, oh)); return; } @@ -918,6 +925,29 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev, } + +static int yaffs_VerifyChunkWritten(yaffs_Device *dev, + int chunkInNAND, + const __u8 *data, + yaffs_ExtendedTags *tags) +{ + int retval = YAFFS_OK; + yaffs_ExtendedTags tempTags; + __u8 *buffer = yaffs_GetTempBuffer(dev,__LINE__); + int result; + + result = yaffs_ReadChunkWithTagsFromNAND(dev,chunkInNAND,buffer,&tempTags); + if(memcmp(buffer,data,dev->nDataBytesPerChunk) || + tempTags.objectId != tags->objectId || + tempTags.chunkId != tags->chunkId || + tempTags.byteCount != tags->byteCount) + retval = YAFFS_FAIL; + + yaffs_ReleaseTempBuffer(dev, buffer, __LINE__); + + return retval; +} + static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, const __u8 *data, yaffs_ExtendedTags *tags, @@ -957,12 +987,11 @@ static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, * chunk due to power loss. This checking policy should * catch that case with very few checks and thus save a * lot of checks that are most likely not needed. + * + * Mods to the above + * If an erase check fails or the write fails we skip the + * rest of the block. */ - if (bi->gcPrioritise) { - yaffs_DeleteChunk(dev, chunk, 1, __LINE__); - /* try another chunk */ - continue; - } /* let's give it a try */ attempts++; @@ -977,20 +1006,30 @@ static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, (TSTR("**>> yaffs chunk %d was not erased" TENDSTR), chunk)); - /* try another chunk */ + /* If not erased, delete this one, + * skip rest of block and + * try another chunk */ + yaffs_DeleteChunk(dev,chunk,1,__LINE__); + yaffs_SkipRestOfBlock(dev); continue; } - bi->skipErasedCheck = 1; } writeOk = yaffs_WriteChunkWithTagsToNAND(dev, chunk, data, tags); + + if(!bi->skipErasedCheck) + writeOk = yaffs_VerifyChunkWritten(dev, chunk, data, tags); + if (writeOk != YAFFS_OK) { + /* Clean up aborted write, skip to next block and + * try another chunk */ yaffs_HandleWriteChunkError(dev, chunk, erasedOk); - /* try another chunk */ continue; } + bi->skipErasedCheck = 1; + /* Copy the data into the robustification buffer */ yaffs_HandleWriteChunkOk(dev, chunk, data, tags); @@ -1100,6 +1139,7 @@ static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND, /* Delete the chunk */ yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__); + yaffs_SkipRestOfBlock(dev); } @@ -1130,7 +1170,7 @@ 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) + if (name && yaffs_strnlen(name,YAFFS_SHORT_NAME_LENGTH+1) <= YAFFS_SHORT_NAME_LENGTH) yaffs_strcpy(obj->shortName, name); else obj->shortName[0] = _Y('\0'); @@ -1149,11 +1189,22 @@ static void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name) * adds them to the tnode free list. * Don't use this function directly */ +static Y_INLINE int yaffs_CalcTnodeSize(yaffs_Device *dev) +{ + int tnodeSize; + /* Calculate the tnode size in bytes for variable width tnode support. + * Must be a multiple of 32-bits */ + tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; + + if (tnodeSize < sizeof(yaffs_Tnode)) + tnodeSize = sizeof(yaffs_Tnode); + return tnodeSize; +} static int yaffs_CreateTnodes(yaffs_Device *dev, int nTnodes) { int i; - int tnodeSize; + int tnodeSize = yaffs_CalcTnodeSize(dev); yaffs_Tnode *newTnodes; __u8 *mem; yaffs_Tnode *curr; @@ -1163,12 +1214,6 @@ static int yaffs_CreateTnodes(yaffs_Device *dev, int nTnodes) if (nTnodes < 1) return YAFFS_OK; - /* Calculate the tnode size in bytes for variable width tnode support. - * Must be a multiple of 32-bits */ - tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; - - if (tnodeSize < sizeof(yaffs_Tnode)) - tnodeSize = sizeof(yaffs_Tnode); /* make these things */ @@ -1241,6 +1286,11 @@ static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device *dev) { yaffs_Tnode *tn = NULL; +#ifdef CONFIG_YAFFS_VALGRIND_TEST + tn = YMALLOC(yaffs_CalcTnodeSize(dev)); + if(tn) + dev->nTnodesCreated++; +#else /* If there are none left make more */ if (!dev->freeTnodes) yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES); @@ -1257,7 +1307,7 @@ static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device *dev) dev->freeTnodes = dev->freeTnodes->internal[0]; dev->nFreeTnodes--; } - +#endif dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ return tn; @@ -1266,10 +1316,7 @@ static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device *dev) static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev) { yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev); - int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; - - if (tnodeSize < sizeof(yaffs_Tnode)) - tnodeSize = sizeof(yaffs_Tnode); + int tnodeSize = yaffs_CalcTnodeSize(dev); if (tn) memset(tn, 0, tnodeSize); @@ -1281,6 +1328,10 @@ static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev) static void yaffs_FreeTnode(yaffs_Device *dev, yaffs_Tnode *tn) { if (tn) { +#ifdef CONFIG_YAFFS_VALGRIND_TEST + YFREE(tn); + dev->nTnodesCreated--; +#else #ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG if (tn->internal[YAFFS_NTNODES_INTERNAL] != 0) { /* Hoosterman, this thing looks like it is already in the list */ @@ -1292,6 +1343,7 @@ static void yaffs_FreeTnode(yaffs_Device *dev, yaffs_Tnode *tn) tn->internal[0] = dev->freeTnodes; dev->freeTnodes = tn; dev->nFreeTnodes++; +#endif } dev->nCheckpointBlocksRequired = 0; /* force recalculation*/ } @@ -1312,6 +1364,7 @@ static void yaffs_DeinitialiseTnodes(yaffs_Device *dev) dev->freeTnodes = NULL; dev->nFreeTnodes = 0; + dev->nTnodesCreated = 0; } static void yaffs_InitialiseTnodes(yaffs_Device *dev) @@ -1508,7 +1561,6 @@ static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev, tn->internal[x] = yaffs_GetTnode(dev); if(!tn->internal[x]) return NULL; - } else if (l == 1) { /* Looking from level 1 at level 0 */ if (passedTn) { @@ -1768,6 +1820,10 @@ static void yaffs_SoftDeleteFile(yaffs_Object *obj) * level 0 tnode entries must be zeroed out. * Could also use this for file deletion, but that's probably better handled * by a special case. + * + * This function is recursive. For levels > 0 the function is called again on + * any sub-tree. For level == 0 we just check if the sub-tree has data. + * If there is no data in a subtree then it is pruned. */ static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn, @@ -1779,17 +1835,27 @@ static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn, if (tn) { hasData = 0; - for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) { - if (tn->internal[i] && level > 0) { - tn->internal[i] = - yaffs_PruneWorker(dev, tn->internal[i], - level - 1, - (i == 0) ? del0 : 1); + if(level > 0){ + for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) { + if (tn->internal[i]) { + tn->internal[i] = + yaffs_PruneWorker(dev, tn->internal[i], + level - 1, + (i == 0) ? del0 : 1); + } + + if (tn->internal[i]) + hasData++; } + } else { + int tnodeSize_u32 = yaffs_CalcTnodeSize(dev)/sizeof(__u32); + __u32 *map = (__u32 *)tn; - if (tn->internal[i]) - hasData++; - } + for(i = 0; !hasData && i < tnodeSize_u32; i++){ + if(map[i]) + hasData++; + } + } if (hasData == 0 && del0) { /* Free and return NULL */ @@ -1903,8 +1969,10 @@ static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device *dev) { yaffs_Object *tn = NULL; -#ifdef VALGRIND_TEST +#ifdef CONFIG_YAFFS_VALGRIND_TEST tn = YMALLOC(sizeof(yaffs_Object)); + if(tn) + dev->nObjectsCreated++; #else /* If there are none left make more */ if (!dev->freeObjects) @@ -1991,17 +2059,16 @@ static void yaffs_FreeObject(yaffs_Object *tn) { yaffs_Device *dev = tn->myDev; -#ifdef __KERNEL__ T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), tn, tn->myInode)); -#endif + if (!tn) + YBUG(); if (tn->parent) YBUG(); if (!ylist_empty(&tn->siblings)) YBUG(); -#ifdef __KERNEL__ if (tn->myInode) { /* We're still hooked up to a cached inode. * Don't delete now, but mark for later deletion @@ -2009,12 +2076,12 @@ static void yaffs_FreeObject(yaffs_Object *tn) tn->deferedFree = 1; return; } -#endif yaffs_UnhashObject(tn); -#ifdef VALGRIND_TEST +#ifdef CONFIG_YAFFS_VALGRIND_TEST YFREE(tn); + dev->nObjectsCreated--; tn = NULL; #else /* Link into the free list. */ @@ -2051,6 +2118,7 @@ static void yaffs_DeinitialiseObjects(yaffs_Device *dev) dev->freeObjects = NULL; dev->nFreeObjects = 0; + dev->nObjectsCreated = 0; } static void yaffs_InitialiseObjects(yaffs_Device *dev) @@ -2172,7 +2240,7 @@ yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number) yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number, yaffs_ObjectType type) { - yaffs_Object *theObject; + yaffs_Object *theObject=NULL; yaffs_Tnode *tn = NULL; if (number < 0) @@ -2257,14 +2325,17 @@ static yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev, static YCHAR *yaffs_CloneString(const YCHAR *str) { YCHAR *newStr = NULL; + int len; if (!str) str = _Y(""); - newStr = YMALLOC((yaffs_strlen(str) + 1) * sizeof(YCHAR)); - if (newStr) - yaffs_strcpy(newStr, str); - + len = yaffs_strnlen(str,YAFFS_MAX_ALIAS_LENGTH); + newStr = YMALLOC((len + 1) * sizeof(YCHAR)); + if (newStr){ + yaffs_strncpy(newStr, str,len); + newStr[len] = 0; + } return newStr; } @@ -2311,6 +2382,7 @@ static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type, + if (in) { in->hdrChunk = 0; in->valid = 1; @@ -2499,7 +2571,7 @@ int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName, force = 1; #endif - if(yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH) + if(yaffs_strnlen(newName,YAFFS_MAX_NAME_LENGTH+1) > YAFFS_MAX_NAME_LENGTH) /* ENAMETOOLONG */ return YAFFS_FAIL; @@ -2859,12 +2931,7 @@ static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev) int nBytes = 0; int nBlocks; int devBlocks = (dev->endBlock - dev->startBlock + 1); - int tnodeSize; - - tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; - - if (tnodeSize < sizeof(yaffs_Tnode)) - tnodeSize = sizeof(yaffs_Tnode); + int tnodeSize = yaffs_CalcTnodeSize(dev); nBytes += sizeof(yaffs_CheckpointValidity); nBytes += sizeof(yaffs_CheckpointDevice); @@ -2976,6 +3043,22 @@ static int yaffs_GetErasedChunks(yaffs_Device *dev) } +/* + * yaffs_SkipRestOfBlock() skips over the rest of the allocation block + * if we don't want to write to it. + */ +static void yaffs_SkipRestOfBlock(yaffs_Device *dev) +{ + if(dev->allocationBlock > 0){ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->allocationBlock); + if(bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING){ + bi->blockState = YAFFS_BLOCK_STATE_FULL; + dev->allocationBlock = -1; + } + } +} + + static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, int wholeBlock) { @@ -3135,6 +3218,7 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, if (tags.chunkId == 0) { /* It is an object Id, * We need to nuke the shrinkheader flags first + * Also need to clean up shadowing. * We no longer want the shrinkHeader flag since its work is done * and if it is left in place it will mess up scanning. */ @@ -3143,6 +3227,9 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, oh = (yaffs_ObjectHeader *)buffer; oh->isShrink = 0; tags.extraIsShrinkHeader = 0; + oh->shadowsObject = 0; + oh->inbandShadowsObject = 0; + tags.extraShadows = 0; yaffs_VerifyObjectHeader(object, oh, &tags, 1); } @@ -3162,7 +3249,8 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block, object->serial = tags.serialNumber; } else { /* It's a data chunk */ - yaffs_PutChunkIntoFile + int ok; + ok = yaffs_PutChunkIntoFile (object, tags.chunkId, newChunk, 0); @@ -3474,7 +3562,6 @@ static int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode, if(!chunkInNAND) /* Dummy insert, bail now */ return YAFFS_OK; - existingChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode); @@ -3661,8 +3748,14 @@ static int yaffs_WriteChunkDataToObject(yaffs_Object *in, int chunkInInode, yaffs_CheckGarbageCollection(dev); - /* Get the previous chunk at this location in the file if it exists */ + /* Get the previous chunk at this location in the file if it exists. + * If it does not exist then put a zero into the tree. This creates + * the tnode now, rather than later when it is harder to clean up. + */ prevChunkId = yaffs_FindChunkInFile(in, chunkInInode, &prevTags); + if(prevChunkId <= 0 && + !yaffs_PutChunkIntoFile(in, chunkInInode, 0, 0)){ + } /* Set up new tags */ yaffs_InitialiseTags(&newTags); @@ -4343,11 +4436,7 @@ static int yaffs_CheckpointTnodeWorker(yaffs_Object *in, yaffs_Tnode *tn, int i; yaffs_Device *dev = in->myDev; int ok = 1; - int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; - - if (tnodeSize < sizeof(yaffs_Tnode)) - tnodeSize = sizeof(yaffs_Tnode); - + int tnodeSize = yaffs_CalcTnodeSize(dev); if (tn) { if (level > 0) { @@ -4398,10 +4487,7 @@ static int yaffs_ReadCheckpointTnodes(yaffs_Object *obj) yaffs_FileStructure *fileStructPtr = &obj->variant.fileVariant; yaffs_Tnode *tn; int nread = 0; - int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; - - if (tnodeSize < sizeof(yaffs_Tnode)) - tnodeSize = sizeof(yaffs_Tnode); + int tnodeSize = yaffs_CalcTnodeSize(dev); ok = (yaffs_CheckpointRead(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk)); @@ -4457,8 +4543,8 @@ static int yaffs_WriteCheckpointObjects(yaffs_Device *dev) cp.structType = sizeof(cp); T(YAFFS_TRACE_CHECKPOINT, ( - TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %x" TENDSTR), - cp.objectId, cp.parentId, cp.variantType, cp.hdrChunk, (unsigned) obj)); + TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %p" TENDSTR), + cp.objectId, cp.parentId, cp.variantType, cp.hdrChunk, obj)); ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp)); @@ -4491,7 +4577,7 @@ static int yaffs_ReadCheckpointObjects(yaffs_Device *dev) ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp)); if (cp.structType != sizeof(cp)) { T(YAFFS_TRACE_CHECKPOINT, (TSTR("struct size %d instead of %d ok %d"TENDSTR), - cp.structType, sizeof(cp), ok)); + cp.structType, (int)sizeof(cp), ok)); ok = 0; } @@ -5103,7 +5189,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *obj) alias = obj->variant.symLinkVariant.alias; if(!alias) return 0; - return yaffs_strlen(alias); + return yaffs_strnlen(alias,YAFFS_MAX_ALIAS_LENGTH); default: return 0; } @@ -5171,13 +5257,8 @@ static int yaffs_UnlinkFileIfNeeded(yaffs_Object *in) int retVal; int immediateDeletion = 0; -#ifdef __KERNEL__ if (!in->myInode) immediateDeletion = 1; -#else - if (in->inUse <= 0) - immediateDeletion = 1; -#endif if (immediateDeletion) { retVal = @@ -5297,13 +5378,8 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj) int immediateDeletion = 0; -#ifdef __KERNEL__ if (!obj->myInode) immediateDeletion = 1; -#else - if (obj->inUse <= 0) - immediateDeletion = 1; -#endif if(obj) yaffs_UpdateParent(obj->parent); @@ -5320,23 +5396,26 @@ static int yaffs_UnlinkWorker(yaffs_Object *obj) * Instead, we do the following: * - Select a hardlink. * - Unhook it from the hard links - * - Unhook it from its parent directory (so that the rename can work) + * - Move it from its parent directory (so that the rename can work) * - Rename the object to the hardlink's name. * - Delete the hardlink */ yaffs_Object *hl; + yaffs_Object *parent; int retVal; YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; hl = ylist_entry(obj->hardLinks.next, yaffs_Object, hardLinks); + yaffs_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1); + parent = hl->parent; + ylist_del_init(&hl->hardLinks); - ylist_del_init(&hl->siblings); - yaffs_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1); + yaffs_AddObjectToDirectory(obj->myDev->unlinkedDir, hl); - retVal = yaffs_ChangeObjectName(obj, hl->parent, name, 0, 0); + retVal = yaffs_ChangeObjectName(obj,parent, name, 0, 0); if (retVal == YAFFS_OK) retVal = yaffs_DoGenericObjectDeletion(hl); @@ -5751,7 +5830,7 @@ static int yaffs_Scan(yaffs_Device *dev) dev->allocationBlock = blk; dev->allocationPage = c; dev->allocationBlockFinder = blk; - /* Set it to here to encourage the allocator to go forth from here. */ + /* Set block finder here to encourage the allocator to go forth from here. */ } @@ -5997,12 +6076,6 @@ static int yaffs_Scan(yaffs_Device *dev) break; } -/* - if (parent == dev->deletedDir) { - yaffs_DestroyObject(in); - bi->hasShrinkHeader = 1; - } -*/ } } } @@ -6012,6 +6085,12 @@ static int yaffs_Scan(yaffs_Device *dev) state = YAFFS_BLOCK_STATE_FULL; } + if (state == YAFFS_BLOCK_STATE_ALLOCATING) { + /* If the block was partially allocated then treat it as fully allocated.*/ + state = YAFFS_BLOCK_STATE_FULL; + dev->allocationBlock = -1; + } + bi->blockState = state; /* Now let's see if it was dirty */ @@ -6354,13 +6433,9 @@ static int yaffs_ScanBackwards(yaffs_Device *dev) dev->allocationBlockFinder = blk; } else { /* This is a partially written block that is not - * the current allocation block. This block must have - * had a write failure, so set up for retirement. + * the current allocation block. */ - /* bi->needsRetiring = 1; ??? TODO */ - bi->gcPrioritise = 1; - T(YAFFS_TRACE_ALWAYS, (TSTR("Partially written block %d detected" TENDSTR), blk)); @@ -6622,6 +6697,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev) oh-> shadowsObject, 1); + yaffs_SetObjectName(in, oh->name); @@ -6753,6 +6829,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev) state = YAFFS_BLOCK_STATE_FULL; } + bi->blockState = state; /* Now let's see if it was dirty */ @@ -6763,6 +6840,8 @@ static int yaffs_ScanBackwards(yaffs_Device *dev) } } + + yaffs_SkipRestOfBlock(dev); if (altBlockIndex) YFREE_ALT(blockIndex); @@ -7087,7 +7166,7 @@ int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize) } #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM else if (obj->shortName[0]) - yaffs_strcpy(name, obj->shortName); + yaffs_strncpy(name, obj->shortName,YAFFS_SHORT_NAME_LENGTH+1); #endif else { int result; @@ -7103,11 +7182,12 @@ int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize) NULL); } yaffs_strncpy(name, oh->name, buffSize - 1); + name[buffSize-1]=0; yaffs_ReleaseTempBuffer(obj->myDev, buffer, __LINE__); } - return yaffs_strlen(name); + return yaffs_strnlen(name,buffSize-1); } int yaffs_GetObjectFileLength(yaffs_Object *obj) @@ -7120,7 +7200,7 @@ int yaffs_GetObjectFileLength(yaffs_Object *obj) if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK){ if(!obj->variant.symLinkVariant.alias) return 0; - return yaffs_strlen(obj->variant.symLinkVariant.alias); + return yaffs_strnlen(obj->variant.symLinkVariant.alias,YAFFS_MAX_ALIAS_LENGTH); } else { /* Only a directory should drop through to here */ return obj->myDev->nDataBytesPerChunk; @@ -7758,7 +7838,7 @@ static void yaffs_VerifyFreeChunks(yaffs_Device *dev) do { \ if (sizeof(structure) != syze) { \ T(YAFFS_TRACE_ALWAYS, (TSTR("%s should be %d but is %d\n" TENDSTR),\ - name, syze, sizeof(structure))); \ + name, syze, (int) sizeof(structure))); \ return YAFFS_FAIL; \ } \ } while (0) @@ -7769,7 +7849,7 @@ static int yaffs_CheckStructures(void) /* yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion"); */ /* yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare"); */ #ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG - yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode"); +/* yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode"); */ #endif #ifndef CONFIG_YAFFS_WINCE yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader");