From 18fcce7fefa7e3d67ac8a7455056395567564617 Mon Sep 17 00:00:00 2001 From: charles Date: Thu, 5 Mar 2009 01:45:28 +0000 Subject: [PATCH] Change inode deletion to prevent issue raised by YBUG --- yaffs_fs.c | 4 ++-- yaffs_guts.c | 65 +++++++++++++++++++++++++++++++++++++--------------- yaffs_guts.h | 2 +- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/yaffs_fs.c b/yaffs_fs.c index dd499f9..5f0c7b2 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -32,7 +32,7 @@ */ const char *yaffs_fs_c_version = - "$Id: yaffs_fs.c,v 1.74 2009-03-05 01:05:28 charles Exp $"; + "$Id: yaffs_fs.c,v 1.75 2009-03-05 01:45:28 charles Exp $"; extern const char *yaffs_guts_c_version; #include @@ -566,7 +566,7 @@ static void yaffs_delete_inode(struct inode *inode) if (obj) { dev = obj->myDev; yaffs_GrossLock(dev); - yaffs_DeleteFile(obj); + yaffs_DeleteObject(obj); yaffs_GrossUnlock(dev); } #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) diff --git a/yaffs_guts.c b/yaffs_guts.c index 44eaed6..a09328e 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -12,7 +12,7 @@ */ const char *yaffs_guts_c_version = - "$Id: yaffs_guts.c,v 1.78 2009-01-27 02:52:45 charles Exp $"; + "$Id: yaffs_guts.c,v 1.79 2009-03-05 01:45:28 charles Exp $"; #include "yportenv.h" @@ -79,7 +79,6 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev, 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); @@ -2023,6 +2022,9 @@ 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->parent) YBUG(); @@ -2396,7 +2398,7 @@ static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type, 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; } @@ -5211,7 +5213,7 @@ static int yaffs_DoGenericObjectDeletion(yaffs_Object * in) * 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; @@ -5262,7 +5264,7 @@ int yaffs_DeleteFile(yaffs_Object * in) * 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; @@ -5307,32 +5309,48 @@ static int yaffs_DeleteHardLink(yaffs_Object * in) 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)) { @@ -5368,10 +5386,10 @@ static int yaffs_UnlinkWorker(yaffs_Object * obj) } 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); @@ -5387,6 +5405,9 @@ static int yaffs_UnlinkWorker(yaffs_Object * obj) default: return YAFFS_FAIL; } + } else { + return yaffs_ChangeObjectName(obj, obj->myDev->unlinkedDir, + _Y("unlinked"), 0, 0); } } @@ -5518,7 +5539,7 @@ static void yaffs_StripDeletedObjects(yaffs_Device *dev) &dev->unlinkedDir->variant.directoryVariant.children) { if (i) { l = ylist_entry(i, yaffs_Object, siblings); - yaffs_DestroyObject(l); + yaffs_DeleteObject(l); } } @@ -5526,7 +5547,7 @@ static void yaffs_StripDeletedObjects(yaffs_Device *dev) &dev->deletedDir->variant.directoryVariant.children) { if (i) { l = ylist_entry(i, yaffs_Object, siblings); - yaffs_DestroyObject(l); + yaffs_DeleteObject(l); } } @@ -5722,7 +5743,7 @@ static int yaffs_Scan(yaffs_Device * dev) * deleted, and worse still it has changed type. Delete the old object. */ - yaffs_DestroyObject(in); + yaffs_DeleteObject(in); in = 0; } @@ -5950,7 +5971,7 @@ static int yaffs_Scan(yaffs_Device * dev) */ obj = yaffs_FindObjectByNumber(dev,fixer->shadowedId); if(obj) - yaffs_DestroyObject(obj); + yaffs_DeleteObject(obj); obj = yaffs_FindObjectByNumber(dev,fixer->objectId); if(obj){ @@ -6720,6 +6741,7 @@ static void yaffs_VerifyObjectInDirectory(yaffs_Object *obj) if(!obj){ T(YAFFS_TRACE_ALWAYS, (TSTR("No object to verify" TENDSTR))); YBUG(); + return; } if(yaffs_SkipVerification(obj->myDev)) @@ -6728,6 +6750,7 @@ static void yaffs_VerifyObjectInDirectory(yaffs_Object *obj) if(!obj->parent){ T(YAFFS_TRACE_ALWAYS, (TSTR("Object does not have parent" TENDSTR))); YBUG(); + return; } if(obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY){ @@ -6759,8 +6782,10 @@ static void yaffs_VerifyDirectory(yaffs_Object *directory) struct ylist_head *lh; yaffs_Object *listObj; - if(!directory) + if(!directory){ YBUG(); + return; + } if(yaffs_SkipFullVerification(directory->myDev)) return; @@ -6819,6 +6844,7 @@ static void yaffs_AddObjectToDirectory(yaffs_Object * directory, ("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, @@ -6879,6 +6905,7 @@ yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory, ("tragedy: yaffs_FindObjectByName: null pointer directory" TENDSTR))); YBUG(); + return NULL; } if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) { T(YAFFS_TRACE_ALWAYS, @@ -6934,12 +6961,14 @@ int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir, ("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) { diff --git a/yaffs_guts.h b/yaffs_guts.h index 284e206..bef284f 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -824,7 +824,7 @@ int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName, yaffs_Object * newDir, const YCHAR * newName); int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name); -int yaffs_DeleteFile(yaffs_Object * obj); +int yaffs_DeleteObject(yaffs_Object * obj); int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize); int yaffs_GetObjectFileLength(yaffs_Object * obj); -- 2.30.2