From dfa46953df4e4c3717fb0fb216b144a787dcde59 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 13 Jul 2012 18:48:12 +0800 Subject: [PATCH] VFS - Bugfixes to nodecache - Now can tell if a node is deallocated when using UncacheNode (allows on-free actions) --- KernelLand/Kernel/include/vfs.h | 3 +- KernelLand/Kernel/vfs/nodecache.c | 84 ++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/KernelLand/Kernel/include/vfs.h b/KernelLand/Kernel/include/vfs.h index b746d0e7..0977e28c 100644 --- a/KernelLand/Kernel/include/vfs.h +++ b/KernelLand/Kernel/include/vfs.h @@ -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 diff --git a/KernelLand/Kernel/vfs/nodecache.c b/KernelLand/Kernel/vfs/nodecache.c index d2796c1b..ffad2437 100644 --- a/KernelLand/Kernel/vfs/nodecache.c +++ b/KernelLand/Kernel/vfs/nodecache.c @@ -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 #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 ; } /** -- 2.20.1