Change inode deletion to prevent issue raised by YBUG
authorcharles <charles>
Thu, 5 Mar 2009 01:45:28 +0000 (01:45 +0000)
committercharles <charles>
Thu, 5 Mar 2009 01:45:28 +0000 (01:45 +0000)
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h

index dd499f93337be1c6e3c6403669527914fae97cc5..5f0c7b29f73cef858d7bb0a8e1ad6065a178b9c2 100644 (file)
@@ -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 <linux/version.h>
@@ -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))
index 44eaed692cedb05ac60af308d4d4a3e999fee577..a09328e95b42ee1b70d34388841819a79d606245 100644 (file)
@@ -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) {
index 284e206040eb14c485d8fe55cf0a86307679b2f2..bef284f398f7173243e3a822fa22fb276c4fbda4 100644 (file)
@@ -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);