X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=df8efbe3c6371ac22914fc444492775f8cf82c48;hp=5ea11500ffd506fa3f3a083dea48a62ca27c574f;hb=380068d8dfd26d7975fb356f9f5439282d17b4d6;hpb=211d5ed173ffbb5736bfe98e7fd1706fd581d23b diff --git a/yaffs_guts.c b/yaffs_guts.c index 5ea1150..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.103 2010-01-01 23:54:03 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" @@ -1188,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; @@ -1202,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 */ @@ -1280,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); @@ -1296,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; @@ -1305,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); @@ -1320,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 */ @@ -1331,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*/ } @@ -1548,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) { @@ -1836,15 +1848,10 @@ static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn, hasData++; } } else { - int tnodeSize; + int tnodeSize_u32 = yaffs_CalcTnodeSize(dev)/sizeof(__u32); __u32 *map = (__u32 *)tn; - tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8; - if (tnodeSize < sizeof(yaffs_Tnode)) - tnodeSize = sizeof(yaffs_Tnode); - tnodeSize /= sizeof(__u32); - - for(i = 0; !hasData && i < tnodeSize; i++){ + for(i = 0; !hasData && i < tnodeSize_u32; i++){ if(map[i]) hasData++; } @@ -1962,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) @@ -2050,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 @@ -2068,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. */ @@ -2232,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) @@ -2374,6 +2382,7 @@ static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type, + if (in) { in->hdrChunk = 0; in->valid = 1; @@ -2922,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); @@ -3245,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); @@ -3557,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); @@ -3744,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); @@ -4426,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) { @@ -4481,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)); @@ -5254,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 = @@ -5380,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); @@ -5403,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);