*/
const char *yaffs_guts_c_version =
- "$Id: yaffs_guts.c,v 1.77 2009-01-27 02:00:42 charles Exp $";
+ "$Id: yaffs_guts.c,v 1.79 2009-03-05 01:45:28 charles Exp $";
#include "yportenv.h"
int chunkInNAND);
static int yaffs_UnlinkWorker(yaffs_Object * obj);
-static void yaffs_DestroyObject(yaffs_Object * obj);
static int yaffs_TagsMatch(const yaffs_ExtendedTags * tags, int objectId,
int chunkInObject);
if (dev->writeChunkWithTagsToNAND(dev, chunkId -
dev->chunkOffset, buffer, &tags) != YAFFS_OK)
T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Failed to "
- "write bad block marker to block %d"
+ TCONT("write bad block marker to block %d")
TENDSTR), blockInNAND));
yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
yaffs_Device *dev = tn->myDev;
+#ifdef __KERNEL__
+ T(YAFFS_TRACE_OS,(TSTR("FreeObject %p inode %p"TENDSTR),tn,tn->myInode));
+#endif
if(tn->parent)
YBUG();
if (yaffs_UpdateObjectHeader(in, name, 0, 0, 0) < 0) {
/* Could not create the object header, fail the creation */
- yaffs_DestroyObject(in);
+ yaffs_DeleteObject(in);
in = NULL;
}
if(nBytes < 1 || nBytes > dev->totalBytesPerChunk){
T(YAFFS_TRACE_ERROR,
(TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
- while(1){}
- }
+ YBUG();
+ }
if (obj->variantType != cp->variantType) {
T(YAFFS_TRACE_ERROR,(TSTR("Checkpoint read object %d type %d "
- "chunk %d does not match existing object type %d"
+ TCONT("chunk %d does not match existing object type %d")
TENDSTR), cp->objectId, cp->variantType, cp->hdrChunk,
obj->variantType));
return 0;
if(parent) {
if (parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
- T(YAFFS_TRACE_ALWAYS,(TSTR("Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory"TENDSTR),
+ T(YAFFS_TRACE_ALWAYS,(TSTR("Checkpoint read object %d parent %d type %d"
+ TCONT(" chunk %d Parent type, %d, not directory")
+ TENDSTR),
cp->objectId,cp->parentId,cp->variantType,cp->hdrChunk,parent->variantType));
return 0;
}
if(chunk * dev->nDataBytesPerChunk + start != offset ||
start >= dev->nDataBytesPerChunk){
- T(YAFFS_TRACE_ERROR,(TSTR("AddrToChunk of offset %d gives chunk %d start %d"TENDSTR),
- (int)offset, chunk,start));
+ T(YAFFS_TRACE_ERROR,(
+ TSTR("AddrToChunk of offset %d gives chunk %d start %d"
+ TENDSTR),
+ (int)offset, chunk,start));
}
chunk++;
* and the inode associated with the file.
* It does not delete the links associated with the file.
*/
-static int yaffs_UnlinkFile(yaffs_Object * in)
+static int yaffs_UnlinkFileIfNeeded(yaffs_Object * in)
{
int retVal;
* That won't be the case if it has been resized to zero.
*/
if (!in->unlinked) {
- retVal = yaffs_UnlinkFile(in);
+ retVal = yaffs_UnlinkFileIfNeeded(in);
}
if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
in->deleted = deleted = 1;
return yaffs_DoGenericObjectDeletion(in);
}
-static void yaffs_DestroyObject(yaffs_Object * obj)
+int yaffs_DeleteObject(yaffs_Object * obj)
{
+int retVal = -1;
switch (obj->variantType) {
case YAFFS_OBJECT_TYPE_FILE:
- yaffs_DeleteFile(obj);
+ retVal = yaffs_DeleteFile(obj);
break;
case YAFFS_OBJECT_TYPE_DIRECTORY:
- yaffs_DeleteDirectory(obj);
+ return yaffs_DeleteDirectory(obj);
break;
case YAFFS_OBJECT_TYPE_SYMLINK:
- yaffs_DeleteSymLink(obj);
+ retVal = yaffs_DeleteSymLink(obj);
break;
case YAFFS_OBJECT_TYPE_HARDLINK:
- yaffs_DeleteHardLink(obj);
+ retVal = yaffs_DeleteHardLink(obj);
break;
case YAFFS_OBJECT_TYPE_SPECIAL:
- yaffs_DoGenericObjectDeletion(obj);
+ retVal = yaffs_DoGenericObjectDeletion(obj);
break;
case YAFFS_OBJECT_TYPE_UNKNOWN:
+ retVal = 0;
break; /* should not happen. */
}
+
+ return retVal;
}
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->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
return yaffs_DeleteHardLink(obj);
} else if (!ylist_empty(&obj->hardLinks)) {
}
return retVal;
- } else {
+ } else if(immediateDeletion){
switch (obj->variantType) {
case YAFFS_OBJECT_TYPE_FILE:
- return yaffs_UnlinkFile(obj);
+ return yaffs_DeleteFile(obj);
break;
case YAFFS_OBJECT_TYPE_DIRECTORY:
return yaffs_DeleteDirectory(obj);
default:
return YAFFS_FAIL;
}
+ } else {
+ return yaffs_ChangeObjectName(obj, obj->myDev->unlinkedDir,
+ _Y("unlinked"), 0, 0);
}
}
&dev->unlinkedDir->variant.directoryVariant.children) {
if (i) {
l = ylist_entry(i, yaffs_Object, siblings);
- yaffs_DestroyObject(l);
+ yaffs_DeleteObject(l);
}
}
&dev->deletedDir->variant.directoryVariant.children) {
if (i) {
l = ylist_entry(i, yaffs_Object, siblings);
- yaffs_DestroyObject(l);
+ yaffs_DeleteObject(l);
}
}
* deleted, and worse still it has changed type. Delete the old object.
*/
- yaffs_DestroyObject(in);
+ yaffs_DeleteObject(in);
in = 0;
}
*/
obj = yaffs_FindObjectByNumber(dev,fixer->shadowedId);
if(obj)
- yaffs_DestroyObject(obj);
+ yaffs_DeleteObject(obj);
obj = yaffs_FindObjectByNumber(dev,fixer->objectId);
if(obj){
if (!in->valid && in->variantType !=
(oh ? oh->type : tags.extraObjectType))
- T(YAFFS_TRACE_ERROR, (TSTR
- ("yaffs tragedy: Bad object type, "
- "%d != %d, for object %d at chunk "
- "%d during scan" TENDSTR), oh ?
+ T(YAFFS_TRACE_ERROR, (
+ TSTR("yaffs tragedy: Bad object type, "
+ TCONT("%d != %d, for object %d at chunk ")
+ TCONT("%d during scan")
+ TENDSTR), oh ?
oh->type : tags.extraObjectType,
in->variantType, tags.objectId,
chunk));
if(!obj){
T(YAFFS_TRACE_ALWAYS, (TSTR("No object to verify" TENDSTR)));
YBUG();
+ return;
}
if(yaffs_SkipVerification(obj->myDev))
if(!obj->parent){
T(YAFFS_TRACE_ALWAYS, (TSTR("Object does not have parent" TENDSTR)));
YBUG();
+ return;
}
if(obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY){
struct ylist_head *lh;
yaffs_Object *listObj;
- if(!directory)
+ if(!directory){
YBUG();
+ return;
+ }
if(yaffs_SkipFullVerification(directory->myDev))
return;
("tragedy: Trying to add an object to a null pointer directory"
TENDSTR)));
YBUG();
+ return;
}
if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_ALWAYS,
("tragedy: yaffs_FindObjectByName: null pointer directory"
TENDSTR)));
YBUG();
+ return NULL;
}
if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_ALWAYS,
("tragedy: yaffs_FindObjectByName: null pointer directory"
TENDSTR)));
YBUG();
+ return YAFFS_FAIL;
}
if (theDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
T(YAFFS_TRACE_ALWAYS,
(TSTR
("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR)));
YBUG();
+ return YAFFS_FAIL;
}
ylist_for_each(i, &theDir->variant.directoryVariant.children) {