VFS - Bugfixes to nodecache
authorJohn Hodge <[email protected]>
Fri, 13 Jul 2012 10:48:12 +0000 (18:48 +0800)
committerJohn Hodge <[email protected]>
Fri, 13 Jul 2012 10:48:12 +0000 (18:48 +0800)
- Now can tell if a node is deallocated when using UncacheNode (allows on-free actions)

KernelLand/Kernel/include/vfs.h
KernelLand/Kernel/vfs/nodecache.c

index b746d0e..0977e28 100644 (file)
@@ -486,8 +486,9 @@ extern tVFS_Node    *Inode_CacheNode(int Handle, tVFS_Node *Node);
  * \brief Dereferences (and removes if needed) a node from the cache
  * \param Handle       A handle returned by Inode_GetHandle()
  * \param Inode        Value of the Inode field of the ::tVFS_Node you want to remove
+ * \return -1: Error (not present), 0: Not freed, 1: Freed
  */
-extern void    Inode_UncacheNode(int Handle, Uint64 Inode);
+extern int     Inode_UncacheNode(int Handle, Uint64 Inode);
 /**
  * \fn void Inode_ClearCache(int Handle)
  * \brief Clears the cache for a handle
index d2796c1..ffad243 100644 (file)
@@ -1,7 +1,11 @@
 /*
- * AcessMicro VFS
- * - File IO Passthru's
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * vfs/nodecache.c
+ * - VFS Node Caching facility
  */
+#define DEBUG  0
 #include <acess.h>
 #include "vfs.h"
 #include "vfs_int.h"
@@ -45,7 +49,7 @@ int Inode_GetHandle()
        gVFS_InodeCache = ent;
        SHORTREL( &glVFS_InodeCache );
        
-       return gVFS_NextInodeHandle-1;
+       return ent->Handle;
 }
 
 /**
@@ -107,7 +111,10 @@ tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
        newEnt->Next = ent;
        memcpy(&newEnt->Node, Node, sizeof(tVFS_Node));
        prev->Next = newEnt;
-               
+       newEnt->Node.ReferenceCount = 1;
+
+       LOG("Cached %llx as %p", Node->Inode, &newEnt->Node);
+
        return &newEnt->Node;
 }
 
@@ -115,15 +122,23 @@ tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
  * \fn void Inode_UncacheNode(int Handle, Uint64 Inode)
  * \brief Dereferences/Removes a cached node
  */
-void Inode_UncacheNode(int Handle, Uint64 Inode)
+int Inode_UncacheNode(int Handle, Uint64 Inode)
 {
        tInodeCache     *cache;
        tCachedInode    *ent, *prev;
        
        cache = Inode_int_GetFSCache(Handle);
-       if(!cache)      return ;
-       
-       if(Inode > cache->MaxCached)    return ;
+       if(!cache) {
+               Log_Notice("Inode", "Invalid cache handle %i used", Handle);
+               return -1;
+       }
+
+       ENTER("iHandle XInode", Handle, Inode);
+
+       if(Inode > cache->MaxCached) {
+               LEAVE('i', -1);
+               return -1;
+       }
        
        // Search Cache
        ent = cache->FirstNode;
@@ -131,26 +146,45 @@ void Inode_UncacheNode(int Handle, Uint64 Inode)
        for( ; ent; prev = ent, ent = ent->Next )
        {
                if(ent->Node.Inode < Inode)     continue;
-               if(ent->Node.Inode > Inode)     return;
-               ent->Node.ReferenceCount --;
-               // Check if node needs to be freed
-               if(ent->Node.ReferenceCount == 0)
+               if(ent->Node.Inode > Inode) {
+                       LEAVE('i', -1);
+                       return -1;
+               }
+               break;
+       }
+
+       LOG("ent = %p", ent);
+
+       if( !ent ) {
+               LEAVE('i', -1);
+               return -1;
+       }
+
+       ent->Node.ReferenceCount --;
+       // Check if node needs to be freed
+       if(ent->Node.ReferenceCount == 0)
+       {
+               prev->Next = ent->Next;
+               if(ent->Node.Inode == cache->MaxCached)
                {
-                       prev->Next = ent->Next;
-                       if(ent->Node.Inode == cache->MaxCached)
-                       {
-                               if(ent != cache->FirstNode)
-                                       cache->MaxCached = prev->Node.Inode;
-                               else
-                                       cache->MaxCached = 0;
-                       }
-                               
-                       free(ent);
+                       if(ent != cache->FirstNode)
+                               cache->MaxCached = prev->Node.Inode;
+                       else
+                               cache->MaxCached = 0;
                }
-               return ;
+               
+               if(ent->Node.Data)
+                       free(ent->Node.Data);   
+               free(ent);
+               LOG("Freed");
+               LEAVE('i', 1);
+               return 1;
+       }
+       else
+       {
+               LEAVE('i', 0);
+               return 0;
        }
-       
-       return ;
 }
 
 /**

UCC git Repository :: git.ucc.asn.au