*/
const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.81 2009-03-06 17:20:51 wookey Exp $";
+ "$Id: yaffs_guts.c,v 1.89 2009-09-09 00:56:53 charles Exp $";
#include "yportenv.h"
const yaffs_ExtendedTags *tags);
/* Other local prototypes */
+static void yaffs_UpdateParent(yaffs_Object *obj);
static int yaffs_UnlinkObject(yaffs_Object *obj);
static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj);
static int yaffs_TagsMatch(const yaffs_ExtendedTags *tags, int objectId,
int chunkInObject);
-loff_t yaffs_GetFileSize(yaffs_Object *obj);
-
static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
yaffs_BlockInfo **blockUsedPtr);
T(YAFFS_TRACE_BUFFERS,
(TSTR("Out of temp buffers at line %d, other held by lines:"),
lineNo));
- for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
+ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line));
- }
+
T(YAFFS_TRACE_BUFFERS, (TSTR(" " TENDSTR)));
/*
chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
chunkInRange = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax);
- chunkIdOk = chunkInRange || obj->hdrChunk == 0;
+ chunkIdOk = chunkInRange || (obj->hdrChunk == 0);
chunkValid = chunkInRange &&
yaffs_CheckChunkBit(dev,
obj->hdrChunk / dev->nChunksPerBlock,
erasedOk = yaffs_CheckChunkErased(dev, chunk);
if (erasedOk != YAFFS_OK) {
T(YAFFS_TRACE_ERROR,
- (TSTR ("**>> yaffs chunk %d was not erased"
+ (TSTR("**>> yaffs chunk %d was not erased"
TENDSTR), chunk));
/* try another chunk */
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) {
+ 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 {
+ else
obj->shortName[0] = _Y('\0');
- }
#endif
obj->sum = yaffs_CalcNameSum(name);
}
yaffs_Tnode *tn = NULL;
/* If there are none left make more */
- if (!dev->freeTnodes) {
+ if (!dev->freeTnodes)
yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES);
- }
if (dev->freeTnodes) {
tn = dev->freeTnodes;
int level = fStruct->topLevel;
/* Check sane level and chunk Id */
- if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL) {
+ if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
return NULL;
- }
- if (chunkId > YAFFS_MAX_CHUNK_ID) {
+ if (chunkId > YAFFS_MAX_CHUNK_ID)
return NULL;
- }
/* First check we're tall enough (ie enough topLevel) */
requiredTallness++;
}
- if (requiredTallness > fStruct->topLevel) {
- /* Not tall enough, so we can't find it, return NULL. */
- return NULL;
- }
+ if (requiredTallness > fStruct->topLevel)
+ return NULL; /* Not tall enough, so we can't find it */
/* Traverse down to level 0 */
while (level > 0 && tn) {
/* Check sane level and page Id */
- if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL) {
+ if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL)
return NULL;
- }
- if (chunkId > YAFFS_MAX_CHUNK_ID) {
+ if (chunkId > YAFFS_MAX_CHUNK_ID)
return NULL;
- }
/* First check we're tall enough (ie enough topLevel) */
for (j = 0; theChunk && j < dev->chunkGroupSize; j++) {
if (yaffs_CheckChunkBit(dev, theChunk / dev->nChunksPerBlock,
theChunk % dev->nChunksPerBlock)) {
- yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL,
- tags);
- if (yaffs_TagsMatch(tags, objectId, chunkInInode)) {
- /* found it; */
+
+ if(dev->chunkGroupSize == 1)
return theChunk;
+ else {
+ yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL,
+ tags);
+ if (yaffs_TagsMatch(tags, objectId, chunkInInode)) {
+ /* found it; */
+ return theChunk;
+ }
}
}
theChunk++;
in->nDataChunks--;
if (limit) {
*limit = *limit - 1;
- if (*limit <= 0) {
+ if (*limit <= 0)
hitLimit = 1;
- }
}
}
(i == 0) ? del0 : 1);
}
- if (tn->internal[i]) {
+ if (tn->internal[i])
hasData++;
- }
}
if (hasData == 0 && del0) {
hasData = 0;
for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
- if (tn->internal[i]) {
+ if (tn->internal[i])
hasData++;
- }
}
if (!hasData) {
tn = YMALLOC(sizeof(yaffs_Object));
#else
/* If there are none left make more */
- if (!dev->freeObjects) {
+ if (!dev->freeObjects)
yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS);
- }
if (dev->freeObjects) {
tn = dev->freeObjects;
* NB Can't put root or lostNFound in lostNFound so
* check if lostNFound exists first
*/
- if (dev->lostNFoundDir) {
+ if (dev->lostNFoundDir)
yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn);
- }
tn->beingCreated = 0;
}
{
yaffs_Device *dev = tn->myDev;
-#ifdef __KERNEL__
- T(YAFFS_TRACE_OS,(TSTR("FreeObject %p inode %p"TENDSTR),tn,tn->myInode));
+#ifdef __KERNEL__
+ T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), tn, tn->myInode));
#endif
-
- if(tn->parent)
+
+ if (tn->parent)
YBUG();
if (!ylist_empty(&tn->siblings))
YBUG();
void yaffs_HandleDeferedFree(yaffs_Object *obj)
{
- if (obj->deferedFree) {
+ if (obj->deferedFree)
yaffs_FreeObject(obj);
- }
}
#endif
yaffs_Object *theObject;
yaffs_Tnode *tn = NULL;
- if (number < 0) {
+ if (number < 0)
number = yaffs_CreateNewObjectNumber(dev);
- }
theObject = yaffs_AllocateEmptyObject(dev);
if (!theObject)
{
yaffs_Object *theObject = NULL;
- if (number > 0) {
+ if (number > 0)
theObject = yaffs_FindObjectByNumber(dev, number);
- }
- if (!theObject) {
+ if (!theObject)
theObject = yaffs_CreateNewObject(dev, number, type);
- }
return theObject;
yaffs_Device *dev = parent->myDev;
/* Check if the entry exists. If it does then fail the call since we don't want a dup.*/
- if (yaffs_FindObjectByName(parent, name)) {
+ if (yaffs_FindObjectByName(parent, name))
return NULL;
- }
in = yaffs_CreateNewObject(dev, -1, type);
in = NULL;
}
+ yaffs_UpdateParent(parent);
}
return in;
yaffs_Object *existingTarget;
- if (newDir == NULL) {
+ if (newDir == NULL)
newDir = obj->parent; /* use the old directory */
- }
if (newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_ALWAYS,
}
/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
- if (obj->myDev->isYaffs2) {
+ if (obj->myDev->isYaffs2)
unlinkOp = (newDir == obj->myDev->unlinkedDir);
- } else {
+ else
unlinkOp = (newDir == obj->myDev->unlinkedDir
&& obj->variantType == YAFFS_OBJECT_TYPE_FILE);
- }
deleteOp = (newDir == obj->myDev->deletedDir);
* While look-up is case insensitive, the name isn't.
* Therefore we might want to change x.txt to X.txt
*/
- if (oldDir == newDir && yaffs_strcmp(oldName, newName) == 0) {
+ if (oldDir == newDir && yaffs_strcmp(oldName, newName) == 0)
force = 1;
- }
#endif
else if (yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
existingTarget->objectId);
yaffs_UnlinkObject(existingTarget);
}
+ yaffs_UpdateParent(oldDir);
+ if(newDir != oldDir)
+ yaffs_UpdateParent(newDir);
return yaffs_ChangeObjectName(obj, newDir, newName, 1, 0);
}
dev->nonAggressiveSkip--;
- if (!aggressive && (dev->nonAggressiveSkip > 0)) {
+ if (!aggressive && (dev->nonAggressiveSkip > 0))
return -1;
- }
if (!prioritised)
pagesInUse =
(aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
- if (aggressive) {
+ if (aggressive)
iterations =
dev->internalEndBlock - dev->internalStartBlock + 1;
- } else {
+ else {
iterations =
dev->internalEndBlock - dev->internalStartBlock + 1;
iterations = iterations / 16;
- if (iterations > 200) {
+ if (iterations > 200)
iterations = 200;
- }
}
for (i = 0; i <= iterations && pagesInUse > 0 && !prioritised; i++) {
b++;
- if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
+ if (b < dev->internalStartBlock || b > dev->internalEndBlock)
b = dev->internalStartBlock;
- }
if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
T(YAFFS_TRACE_ERROR,
bi = yaffs_GetBlockInfo(dev, b);
-#if 0
- if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
- dirtiest = b;
- pagesInUse = 0;
- } else
-#endif
-
if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
(bi->pagesInUse - bi->softDeletions) < pagesInUse &&
yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
n = dev->nErasedBlocks * dev->nChunksPerBlock;
- if (dev->allocationBlock > 0) {
+ if (dev->allocationBlock > 0)
n += (dev->nChunksPerBlock - dev->allocationPage);
- }
return n;
isCheckpointBlock = (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT);
- bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
T(YAFFS_TRACE_TRACING,
(TSTR("Collecting block %d, in use %d, shrink %d, wholeBlock %d" TENDSTR),
/*yaffs_VerifyFreeChunks(dev); */
+ if(bi->blockState == YAFFS_BLOCK_STATE_FULL)
+ bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
+
bi->hasShrinkHeader = 0; /* clear the flag so that the block can erase */
/* Take off the number of soft deleted entries because
* they're going to get really deleted during GC.
*/
- dev->nFreeChunks -= bi->softDeletions;
+ if(dev->gcChunk == 0) /* first time through for this block */
+ dev->nFreeChunks -= bi->softDeletions;
dev->isDoingGC = 1;
if (block > 0) {
dev->garbageCollections++;
- if (!aggressive) {
+ if (!aggressive)
dev->passiveGarbageCollections++;
- }
T(YAFFS_TRACE_GC,
(TSTR
chunkInInode);
/* Delete the entry in the filestructure (if found) */
- if (retVal != -1) {
+ if (retVal != -1)
yaffs_PutLevel0Tnode(dev, tn, chunkInInode, 0);
- }
- } else {
- /*T(("No level 0 found for %d\n", chunkInInode)); */
}
- if (retVal == -1) {
- /* T(("Could not find %d to delete\n",chunkInInode)); */
- }
return retVal;
}
int theChunk;
int chunkDeleted;
- if (in->variantType != YAFFS_OBJECT_TYPE_FILE) {
- /* T(("Object not a file\n")); */
+ if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
return YAFFS_FAIL;
- }
objId = in->objectId;
fSize = in->variant.fileVariant.fileSize;
&in->variant.fileVariant,
chunkInInode,
NULL);
- if (!tn) {
+ if (!tn)
return YAFFS_FAIL;
- }
existingChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
}
- if (existingChunk == 0) {
+ if (existingChunk == 0)
in->nDataChunks++;
- }
yaffs_PutLevel0Tnode(dev, tn, chunkInInode, chunkInNAND);
{
int chunkInNAND = yaffs_FindChunkInFile(in, chunkInInode, NULL);
- if (chunkInNAND >= 0) {
+ if (chunkInNAND >= 0)
return yaffs_ReadChunkWithTagsFromNAND(in->myDev, chunkInNAND,
buffer, NULL);
- } else {
+ else {
T(YAFFS_TRACE_NANDACCESS,
(TSTR("Chunk %d not found zero instead" TENDSTR),
chunkInNAND));
if (chunkId <= 0)
return;
-
dev->nDeletions++;
block = chunkId / dev->nChunksPerBlock;
page = chunkId % dev->nChunksPerBlock;
yaffs_BlockBecameDirty(dev, block);
}
- } else {
- /* T(("Bad news deleting chunk %d\n",chunkId)); */
}
}
newTags.chunkId = chunkInInode;
newTags.objectId = in->objectId;
newTags.serialNumber =
- (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1;
+ (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));
- YBUG();
+ T(YAFFS_TRACE_ERROR,
+ (TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
+ YBUG();
}
newChunkId =
if (newChunkId >= 0) {
yaffs_PutChunkIntoFile(in, chunkInInode, newChunkId, 0);
- if (prevChunkId >= 0) {
+ if (prevChunkId > 0)
yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__);
- }
-
yaffs_CheckFileSanity(in);
}
return newChunkId;
oh->yst_ctime = in->yst_ctime;
oh->yst_rdev = in->yst_rdev;
#endif
- if (in->parent) {
+ if (in->parent)
oh->parentObjectId = in->parent->objectId;
- } else {
+ else
oh->parentObjectId = 0;
- }
if (name && *name) {
memset(oh->name, 0, sizeof(oh->name));
yaffs_strncpy(oh->name, name, YAFFS_MAX_NAME_LENGTH);
- } else if (prevChunkId >= 0) {
+ } else if (prevChunkId > 0)
memcpy(oh->name, oldName, sizeof(oh->name));
- } else {
+ else
memset(oh->name, 0, sizeof(oh->name));
- }
oh->isShrink = isShrink;
/* Create new chunk in NAND */
newChunkId =
yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
- (prevChunkId >= 0) ? 1 : 0);
+ (prevChunkId > 0) ? 1 : 0);
if (newChunkId >= 0) {
in->hdrChunk = newChunkId;
- if (prevChunkId >= 0) {
+ if (prevChunkId > 0) {
yaffs_DeleteChunk(dev, prevChunkId, 1,
__LINE__);
}
if (dev->srLastUse < 0 || dev->srLastUse > 100000000) {
/* Reset the cache usages */
int i;
- for (i = 1; i < dev->nShortOpCaches; i++) {
+ for (i = 1; i < dev->nShortOpCaches; i++)
dev->srCache[i].lastUse = 0;
- }
+
dev->srLastUse = 0;
}
cache->lastUse = dev->srLastUse;
- if (isAWrite) {
+ if (isAWrite)
cache->dirty = 1;
- }
}
}
if (object->myDev->nShortOpCaches > 0) {
yaffs_ChunkCache *cache = yaffs_FindChunkCache(object, chunkId);
- if (cache) {
+ if (cache)
cache->object = NULL;
- }
}
}
if (dev->nShortOpCaches > 0) {
/* Invalidate it. */
for (i = 0; i < dev->nShortOpCaches; i++) {
- if (dev->srCache[i].object == in) {
+ if (dev->srCache[i].object == in)
dev->srCache[i].object = NULL;
- }
}
}
}
ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
- if (ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
+ if (ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE)
ok = yaffs_WriteCheckpointTnodes(obj);
- }
}
}
}
ok = yaffs_WriteCheckpointValidityMarker(dev, 0);
}
- if (ok) {
+ if (ok)
ok = yaffs_WriteCheckpointSum(dev);
- }
-
if (!yaffs_CheckpointClose(dev))
ok = 0;
/* OK now check for the curveball where the start and end are in
* the same chunk.
*/
- if ((start + n) < dev->nDataBytesPerChunk) {
+ if ((start + n) < dev->nDataBytesPerChunk)
nToCopy = n;
- } else {
+ else
nToCopy = dev->nDataBytesPerChunk - start;
- }
cache = yaffs_FindChunkCache(in, chunk);
else
nBytesRead = in->variant.fileVariant.fileSize - chunkStart;
- if (nBytesRead > dev->nDataBytesPerChunk) {
+ if (nBytesRead > dev->nDataBytesPerChunk)
nBytesRead = dev->nDataBytesPerChunk;
- }
nToWriteBack =
(nBytesRead >
/* Update file object */
- if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize) {
+ if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize)
in->variant.fileVariant.fileSize = (startOfWrite + nDone);
- }
in->dirty = 1;
yaffs_CheckGarbageCollection(dev);
- if (in->variantType != YAFFS_OBJECT_TYPE_FILE) {
+ if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
return YAFFS_FAIL;
- }
- if (newSize == oldFileSize) {
+ if (newSize == oldFileSize)
return YAFFS_OK;
- }
if (newSize < oldFileSize) {
*/
if (in->parent &&
in->parent->objectId != YAFFS_OBJECTID_UNLINKED &&
- in->parent->objectId != YAFFS_OBJECTID_DELETED) {
+ in->parent->objectId != YAFFS_OBJECTID_DELETED)
yaffs_UpdateObjectHeader(in, NULL, 0,
(newSize < oldFileSize) ? 1 : 0, 0);
- }
return YAFFS_OK;
}
int immediateDeletion = 0;
#ifdef __KERNEL__
- if (!in->myInode) {
+ if (!in->myInode)
immediateDeletion = 1;
- }
#else
- if (in->inUse <= 0) {
+ if (in->inUse <= 0)
immediateDeletion = 1;
- }
#endif
if (immediateDeletion) {
in->objectId));
in->deleted = 1;
in->myDev->nDeletedFiles++;
- if (1 || in->myDev->isYaffs2) {
+ if (1 || in->myDev->isYaffs2)
yaffs_ResizeFile(in, 0);
- }
yaffs_SoftDeleteFile(in);
} else {
retVal =
/* 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) {
+ if (!in->unlinked)
retVal = yaffs_UnlinkFileIfNeeded(in);
- }
+
if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
- in->deleted = deleted = 1;
+ in->deleted = 1;
+ deleted = 1;
in->myDev->nDeletedFiles++;
yaffs_SoftDeleteFile(in);
}
}
}
-static int yaffs_DeleteDirectory(yaffs_Object *in)
+static int yaffs_IsNonEmptyDirectory(yaffs_Object *obj)
{
- /* First check that the directory is empty. */
- if (ylist_empty(&in->variant.directoryVariant.children)) {
- return yaffs_DoGenericObjectDeletion(in);
- }
+ return (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) &&
+ !(ylist_empty(&obj->variant.directoryVariant.children));
+}
- return YAFFS_FAIL;
+static int yaffs_DeleteDirectory(yaffs_Object *obj)
+{
+ /* First check that the directory is empty. */
+ if (yaffs_IsNonEmptyDirectory(obj))
+ return YAFFS_FAIL;
+ return yaffs_DoGenericObjectDeletion(obj);
}
static int yaffs_DeleteSymLink(yaffs_Object *in)
retVal = yaffs_DoGenericObjectDeletion(obj);
break;
case YAFFS_OBJECT_TYPE_UNKNOWN:
- retVal = 0;
+ retVal = 0;
break; /* should not happen. */
}
-
+
return retVal;
}
int immediateDeletion = 0;
#ifdef __KERNEL__
- if (!obj->myInode) {
+ if (!obj->myInode)
immediateDeletion = 1;
- }
#else
- if (obj->inUse <= 0) {
+ if (obj->inUse <= 0)
immediateDeletion = 1;
- }
#endif
- if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
- return yaffs_DeleteHardLink(obj);
- } else if (!ylist_empty(&obj->hardLinks)) {
- /* Curve ball: We're unlinking an object that has a hardlink.
- *
- * This problem arises because we are not strictly following
+ if(obj)
+ yaffs_UpdateParent(obj->parent);
+
+ if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
+ return yaffs_DeleteHardLink(obj);
+ } else if (!ylist_empty(&obj->hardLinks)) {
+ /* Curve ball: We're unlinking an object that has a hardlink.
+ *
+ * This problem arises because we are not strictly following
* The Linux link/inode model.
*
* We can't really delete the object.
retVal = yaffs_ChangeObjectName(obj, hl->parent, name, 0, 0);
- if (retVal == YAFFS_OK) {
+ if (retVal == YAFFS_OK)
retVal = yaffs_DoGenericObjectDeletion(hl);
- }
+
return retVal;
- } else if(immediateDeletion){
+ } else if (immediateDeletion) {
switch (obj->variantType) {
case YAFFS_OBJECT_TYPE_FILE:
return yaffs_DeleteFile(obj);
default:
return YAFFS_FAIL;
}
- } else {
+ } else if(yaffs_IsNonEmptyDirectory(obj))
+ return YAFFS_FAIL;
+ else
return yaffs_ChangeObjectName(obj, obj->myDev->unlinkedDir,
_Y("unlinked"), 0, 0);
- }
}
static int yaffs_UnlinkObject(yaffs_Object *obj)
{
- if (obj && obj->unlinkAllowed) {
+ if (obj && obj->unlinkAllowed)
return yaffs_UnlinkWorker(obj);
- }
return YAFFS_FAIL;
/* Handle YAFFS2 case (backward scanning)
* If the shadowed object exists then ignore.
*/
- if (yaffs_FindObjectByNumber(dev, objId)) {
+ if (yaffs_FindObjectByNumber(dev, objId))
return;
- }
}
/* Let's create it (if it does not exist) assuming it is a file so that it can do shrinking etc.
* then setting the object header to unshadowed.
*/
obj = yaffs_FindObjectByNumber(dev, fixer->shadowedId);
- if(obj)
+ if (obj)
yaffs_DeleteObject(obj);
-
+
obj = yaffs_FindObjectByNumber(dev, fixer->objectId);
- if(obj){
+
+ if (obj)
yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0);
- }
YFREE(fixer);
}
yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
- if (alloc_failed) {
+ if (alloc_failed)
return YAFFS_FAIL;
- }
T(YAFFS_TRACE_SCAN, (TSTR("yaffs_Scan ends" TENDSTR)));
yaffs_SetObjectName(in, oh->name);
if (in->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
- in->variant.symLinkVariant.alias =
+ in->variant.symLinkVariant.alias =
yaffs_CloneString(oh->alias);
if (!in->variant.symLinkVariant.alias)
alloc_failed = 1; /* Not returned to caller */
nBlocksToScan++;
- if (sequenceNumber >= dev->sequenceNumber) {
+ if (sequenceNumber >= dev->sequenceNumber)
dev->sequenceNumber = sequenceNumber;
- }
} else {
/* TODO: Nasty sequence number! */
T(YAFFS_TRACE_SCAN,
thisSize;
}
- if (isShrink) {
+ if (isShrink)
bi->hasShrinkHeader = 1;
- }
}
/* Use existing - destroy this one. */
yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
- if (alloc_failed) {
+ if (alloc_failed)
return YAFFS_FAIL;
- }
T(YAFFS_TRACE_SCAN, (TSTR("yaffs_ScanBackwards ends" TENDSTR)));
{
struct ylist_head *lh;
yaffs_Object *listObj;
-
+
if (!directory) {
YBUG();
return;
}
}
+/*
+ *yaffs_UpdateParent() handles fixing a directories mtime and ctime when a new
+ * link (ie. name) is created or deleted in the directory.
+ *
+ * ie.
+ * create dir/a : update dir's mtime/ctime
+ * rm dir/a: update dir's mtime/ctime
+ * modify dir/a: don't update dir's mtimme/ctime
+ */
+
+static void yaffs_UpdateParent(yaffs_Object *obj)
+{
+ if(!obj)
+ return;
+
+ obj->dirty = 1;
+ obj->yst_mtime = obj->yst_ctime = Y_CURRENT_TIME;
+
+ yaffs_UpdateObjectHeader(obj,NULL,0,0,0);
+}
static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj)
{
ylist_del_init(&obj->siblings);
obj->parent = NULL;
-
+
yaffs_VerifyDirectory(parent);
}
-
static void yaffs_AddObjectToDirectory(yaffs_Object *directory,
yaffs_Object *obj)
{
yaffs_Object *l;
- if (!name) {
+ if (!name)
return NULL;
- }
if (!directory) {
T(YAFFS_TRACE_ALWAYS,
/* Special case for lost-n-found */
if (l->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
- if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0) {
+ if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0)
return l;
- }
} else if (yaffs_SumCompare(l->sum, sum) || l->hdrChunk <= 0) {
/* LostnFound chunk called Objxxx
* Do a real check
*/
yaffs_GetObjectName(l, buffer,
- YAFFS_MAX_NAME_LENGTH);
- if (yaffs_strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0) {
+ YAFFS_MAX_NAME_LENGTH + 1);
+ if (yaffs_strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
return l;
- }
}
}
}
T(YAFFS_TRACE_ALWAYS,
(TSTR
("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR)));
- YBUG();
- return YAFFS_FAIL;
- }
+ YBUG();
+ return YAFFS_FAIL;
+ }
ylist_for_each(i, &theDir->variant.directoryVariant.children) {
if (i) {
l = ylist_entry(i, yaffs_Object, siblings);
- if (l && !fn(l)) {
+ if (l && !fn(l))
return YAFFS_FAIL;
- }
}
}
}
#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
- else if (obj->shortName[0]) {
+ else if (obj->shortName[0])
yaffs_strcpy(name, obj->shortName);
- }
#endif
else {
int result;
/* Dereference any hard linking */
obj = yaffs_GetEquivalentObject(obj);
- if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
+ if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
return obj->variant.fileVariant.fileSize;
- }
- if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
+ if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
return yaffs_strlen(obj->variant.symLinkVariant.alias);
- } else {
+ else {
/* Only a directory should drop through to here */
return obj->myDev->nDataBytesPerChunk;
}
int count = 0;
struct ylist_head *i;
- if (!obj->unlinked) {
+ if (!obj->unlinked)
count++; /* the object itself */
- }
- ylist_for_each(i, &obj->hardLinks) {
+
+ ylist_for_each(i, &obj->hardLinks)
count++; /* add the hard links; */
- }
+
return count;
}
YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj)
{
obj = yaffs_GetEquivalentObject(obj);
- if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
+ if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
return yaffs_CloneString(obj->variant.symLinkVariant.alias);
- } else {
+ else
return yaffs_CloneString(_Y(""));
- }
}
#ifndef CONFIG_YAFFS_WINCE
{
YCHAR name[257];
- yaffs_GetObjectName(obj, name, 256);
+ yaffs_GetObjectName(obj, name, YAFFS_MAX_NAME_LENGTH + 1);
T(YAFFS_TRACE_ALWAYS,
(TSTR
void *buf;
int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
- if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES) {
+ if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
- }
dev->srCache = YMALLOC(srCacheBytes);
init_failed = 1;
}
- if (dev->isYaffs2) {
+ if (dev->isYaffs2)
dev->useHeaderFileSize = 1;
- }
+
if (!init_failed && !yaffs_InitialiseBlocks(dev))
init_failed = 1;
YFREE(dev->gcCleanupList);
- for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
+ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
YFREE(dev->tempBuffer[i].buffer);
- }
-
dev->isMounted = 0;
int nFree;
int nDirtyCacheChunks;
int blocksForCheckpoint;
+ int i;
#if 1
nFree = dev->nFreeChunks;
/* Now count the number of dirty chunks in the cache and subtract those */
- {
- int i;
- for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
- if (dev->srCache[i].dirty)
- nDirtyCacheChunks++;
- }
+ for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
+ if (dev->srCache[i].dirty)
+ nDirtyCacheChunks++;
}
nFree -= nDirtyCacheChunks;
#define yaffs_CheckStruct(structure, syze, name) \
do { \
if (sizeof(structure) != syze) { \
- T(YAFFS_TRACE_ALWAYS, (TSTR("%s should be %d but is %d\n" TENDSTR),\
+ T(YAFFS_TRACE_ALWAYS, (TSTR("%s should be %d but is %d\n" TENDSTR),\
name, syze, sizeof(structure))); \
return YAFFS_FAIL; \
} \