* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+
#include "yportenv.h"
#include "yaffs_trace.h"
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);
/* 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) {
* We have to decrement free chunks so this works out properly.
*/
dev->nFreeChunks--;
+ bi->softDeletions--;
object->nDataChunks--;
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 <YAFFS_GC_PASSIVE_THRESHOLD)
dev->param.nChunksPerBlock - dev->gcPagesInUse,
prioritised));
+ dev->nGCBlocks++;
if(background)
dev->backgroundGCs++;
+
dev->gcDirtiest = 0;
dev->gcPagesInUse = 0;
dev->gcNotDone = 0;
int aggressive = 0;
int gcOk = YAFFS_OK;
int maxTries = 0;
-
int minErased;
int erasedChunks;
-
int checkpointBlockAdjust;
if(dev->param.gcControl &&
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 ||
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];
/* process any xattrib modifications */
if(xmod)
- yaffs_ApplyXMod(dev, (char *)buffer, xmod);
+ yaffs_ApplyXMod(in, (char *)buffer, xmod);
/* Tags */
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;
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;
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;
}
/* 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