X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_guts.c;h=7e97a5f0eadc0aad888f3ed30c92cf7b1563c3d9;hp=a1782e7a5177a4293058bc7061e5c46206521887;hb=54d164b5b1fda9b2b25a09efe5cdfe15546e4a36;hpb=87b146cb7bc31e574084000364d6462e6469bf7d diff --git a/yaffs_guts.c b/yaffs_guts.c index a1782e7..7e97a5f 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -66,15 +66,12 @@ static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number, yaffs_ObjectType type); -static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod); +static int yaffs_ApplyXMod(yaffs_Object *obj, char *buffer, yaffs_XAttrMod *xmod); static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj); static int yaffs_CheckStructures(void); static int yaffs_DoGenericObjectDeletion(yaffs_Object *in); -static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev, int blockNo); - - static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev, int chunkInNAND); @@ -434,9 +431,9 @@ static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev, /* let's give it a try */ attempts++; -#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED - bi->skipErasedCheck = 0; -#endif + if(dev->param.alwaysCheckErased) + bi->skipErasedCheck = 0; + if (!bi->skipErasedCheck) { erasedOk = yaffs_CheckChunkErased(dev, chunk); if (erasedOk != YAFFS_OK) { @@ -2435,7 +2432,16 @@ static unsigned yaffs_FindBlockForGarbageCollection(yaffs_Device *dev, threshold = dev->param.nChunksPerBlock; iterations = nBlocks; } else { - int maxThreshold = dev->param.nChunksPerBlock/2; + int maxThreshold; + + if(background) + maxThreshold = dev->param.nChunksPerBlock/2; + else + maxThreshold = dev->param.nChunksPerBlock/8; + + if(maxThreshold < YAFFS_GC_PASSIVE_THRESHOLD) + maxThreshold = YAFFS_GC_PASSIVE_THRESHOLD; + threshold = background ? (dev->gcNotDone + 2) * 2 : 0; if(threshold param.nChunksPerBlock - dev->gcPagesInUse, prioritised)); + dev->nGCBlocks++; if(background) dev->backgroundGCs++; + dev->gcDirtiest = 0; dev->gcPagesInUse = 0; dev->gcNotDone = 0; @@ -2535,10 +2543,8 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background) int aggressive = 0; int gcOk = YAFFS_OK; int maxTries = 0; - int minErased; int erasedChunks; - int checkpointBlockAdjust; if(dev->param.gcControl && @@ -2566,6 +2572,9 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev, int background) if (dev->nErasedBlocks < minErased) aggressive = 1; else { + if(!background && erasedChunks > (dev->nFreeChunks / 4)) + break; + if(dev->gcSkip > 20) dev->gcSkip = 20; if(erasedChunks < dev->nFreeChunks/2 || @@ -2999,7 +3008,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force, int newChunkId; yaffs_ExtendedTags newTags; yaffs_ExtendedTags oldTags; - YCHAR *alias = NULL; + const YCHAR *alias = NULL; __u8 *buffer = NULL; YCHAR oldName[YAFFS_MAX_NAME_LENGTH + 1]; @@ -3100,7 +3109,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force, /* process any xattrib modifications */ if(xmod) - yaffs_ApplyXMod(dev, (char *)buffer, xmod); + yaffs_ApplyXMod(in, (char *)buffer, xmod); /* Tags */ @@ -4927,10 +4936,11 @@ static int yaffs_DoXMod(yaffs_Object *obj, int set, const YCHAR *name, const voi return -ENOSPC; } -static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod) +static int yaffs_ApplyXMod(yaffs_Object *obj, char *buffer, yaffs_XAttrMod *xmod) { int retval = 0; int x_offs = sizeof(yaffs_ObjectHeader); + yaffs_Device *dev = obj->myDev; int x_size = dev->nDataBytesPerChunk - sizeof(yaffs_ObjectHeader); char * x_buffer = buffer + x_offs; @@ -4940,6 +4950,9 @@ static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod else retval = nval_del(x_buffer, x_size, xmod->name); + obj->hasXattr = nval_hasvalues(x_buffer, x_size); + obj->xattrKnown = 1; + xmod->result = retval; return retval; @@ -4954,30 +4967,45 @@ static int yaffs_DoXFetch(yaffs_Object *obj, const YCHAR *name, void *value, int int x_offs = sizeof(yaffs_ObjectHeader); int x_size = dev->nDataBytesPerChunk - sizeof(yaffs_ObjectHeader); - __u8 * x_buffer; + char * x_buffer; int retval = 0; if(obj->hdrChunk < 1) return -ENODATA; - buffer = yaffs_GetTempBuffer(dev, __LINE__); + /* If we know that the object has no xattribs then don't do all the + * reading and parsing. + */ + if(obj->xattrKnown && !obj->hasXattr){ + if(name) + return -ENODATA; + else + return 0; + } + + buffer = (char *) yaffs_GetTempBuffer(dev, __LINE__); if(!buffer) return -ENOMEM; - result = yaffs_ReadChunkWithTagsFromNAND(dev,obj->hdrChunk, buffer, &tags); + result = yaffs_ReadChunkWithTagsFromNAND(dev,obj->hdrChunk, (__u8 *)buffer, &tags); if(result != YAFFS_OK) retval = -ENOENT; else{ x_buffer = buffer + x_offs; + if (!obj->xattrKnown){ + obj->hasXattr = nval_hasvalues(x_buffer, x_size); + obj->xattrKnown = 1; + } + if(name) retval = nval_get(x_buffer, x_size, name, value, size); else retval = nval_list(x_buffer, x_size, value,size); } - yaffs_ReleaseTempBuffer(dev,buffer,__LINE__); + yaffs_ReleaseTempBuffer(dev,(__u8 *)buffer,__LINE__); return retval; } @@ -5507,9 +5535,8 @@ static int yaffs_CheckStructures(void) /* yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags"); */ /* 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"); */ -#endif + #ifndef CONFIG_YAFFS_WINCE yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader"); #endif