10 typedef struct sCachedInode {
11 struct sCachedInode *Next;
14 typedef struct sInodeCache {
15 struct sInodeCache *Next;
17 tCachedInode *FirstNode; // Sorted List
18 Uint64 MaxCached; // Speeds up Searching
22 tInodeCache *Inode_int_GetFSCache(int Handle);
25 int gVFS_NextInodeHandle = 1;
26 tShortSpinlock glVFS_InodeCache;
27 tInodeCache *gVFS_InodeCache = NULL;
31 * \fn int Inode_GetHandle()
37 ent = malloc( sizeof(tInodeCache) );
39 ent->Handle = gVFS_NextInodeHandle++;
40 ent->Next = NULL; ent->FirstNode = NULL;
43 SHORTLOCK( &glVFS_InodeCache );
44 ent->Next = gVFS_InodeCache;
45 gVFS_InodeCache = ent;
46 SHORTREL( &glVFS_InodeCache );
48 return gVFS_NextInodeHandle-1;
52 * \fn tVFS_Node *Inode_GetCache(int Handle, Uint64 Inode)
53 * \brief Gets a node from the cache
55 tVFS_Node *Inode_GetCache(int Handle, Uint64 Inode)
60 cache = Inode_int_GetFSCache(Handle);
61 if(!cache) return NULL;
63 if(Inode > cache->MaxCached) return NULL;
66 ent = cache->FirstNode;
67 for( ; ent; ent = ent->Next )
69 if(ent->Node.Inode < Inode) continue;
70 if(ent->Node.Inode > Inode) return NULL;
71 ent->Node.ReferenceCount ++;
75 return NULL; // Should never be reached
79 * \fn tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
81 tVFS_Node *Inode_CacheNode(int Handle, tVFS_Node *Node)
84 tCachedInode *newEnt, *ent, *prev;
86 cache = Inode_int_GetFSCache(Handle);
87 if(!cache) return NULL;
89 if(Node->Inode > cache->MaxCached)
90 cache->MaxCached = Node->Inode;
93 ent = cache->FirstNode;
94 prev = (tCachedInode*) &cache->FirstNode;
95 for( ; ent; prev = ent, ent = ent->Next )
97 if(ent->Node.Inode < Node->Inode) continue;
98 if(ent->Node.Inode == Node->Inode) {
99 ent->Node.ReferenceCount ++;
106 newEnt = malloc(sizeof(tCachedInode));
108 memcpy(&newEnt->Node, Node, sizeof(tVFS_Node));
111 return &newEnt->Node;
115 * \fn void Inode_UncacheNode(int Handle, Uint64 Inode)
116 * \brief Dereferences/Removes a cached node
118 void Inode_UncacheNode(int Handle, Uint64 Inode)
121 tCachedInode *ent, *prev;
123 cache = Inode_int_GetFSCache(Handle);
126 if(Inode > cache->MaxCached) return ;
129 ent = cache->FirstNode;
130 prev = (tCachedInode*) &cache->FirstNode; // Special case removal
131 for( ; ent; prev = ent, ent = ent->Next )
133 if(ent->Node.Inode < Inode) continue;
134 if(ent->Node.Inode > Inode) return;
135 ent->Node.ReferenceCount --;
136 // Check if node needs to be freed
137 if(ent->Node.ReferenceCount == 0)
139 prev->Next = ent->Next;
140 if(ent->Node.Inode == cache->MaxCached)
142 if(ent != cache->FirstNode)
143 cache->MaxCached = prev->Node.Inode;
145 cache->MaxCached = 0;
157 * \fn void Inode_ClearCache(int Handle)
158 * \brief Removes a cache
160 void Inode_ClearCache(int Handle)
163 tInodeCache *prev = NULL;
164 tCachedInode *ent, *next;
168 cache = gVFS_InodeCache;
169 cache && cache->Handle < Handle;
170 prev = cache, cache = cache->Next
172 if(!cache || cache->Handle != Handle) return;
175 ent = cache->FirstNode;
178 ent->Node.ReferenceCount = 1;
182 ent->Node.Close( &ent->Node );
190 gVFS_InodeCache = cache->Next;
192 prev->Next = cache->Next;
197 * \fn tInodeCache *Inode_int_GetFSCache(int Handle)
198 * \brief Gets a cache given it's handle
200 tInodeCache *Inode_int_GetFSCache(int Handle)
202 tInodeCache *cache = gVFS_InodeCache;
204 for( ; cache; cache = cache->Next )
206 if(cache->Handle > Handle) continue;
207 if(cache->Handle < Handle) {
208 Warning("Inode_int_GetFSCache - Handle %i not in cache\n", Handle);
214 Warning("Inode_int_GetFSCache - Handle %i not in cache [NULL]\n", Handle);