3 * - AllocHandle, GetHandle
12 #include <threads.h> // GetMaxFD
13 #include <vfs_threads.h> // Handle maintainance
16 #define MAX_KERNEL_FILES 128
19 inline void _ReferenceNode(tVFS_Node *Node);
22 tVFS_Handle *gaUserHandles = (void*)MM_PPD_HANDLES;
23 tVFS_Handle *gaKernelHandles = (void*)MM_KERNEL_VFS;
26 inline void _ReferenceNode(tVFS_Node *Node)
28 if( !MM_GetPhysAddr(Node->Type) ) {
29 Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted",
30 Node, Node->Type, MM_GetPhysAddr(&Node->Type));
33 if( Node->Type && Node->Type->Reference )
34 Node->Type->Reference( Node );
36 Node->ReferenceCount ++;
40 * \fn tVFS_Handle *VFS_GetHandle(int FD)
41 * \brief Gets a pointer to the handle information structure
43 tVFS_Handle *VFS_GetHandle(int FD)
47 //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
49 if(FD < 0) return NULL;
51 if(FD & VFS_KERNEL_FLAG) {
52 FD &= (VFS_KERNEL_FLAG - 1);
53 if(FD >= MAX_KERNEL_FILES) return NULL;
54 h = &gaKernelHandles[ FD ];
56 if(FD >= *Threads_GetMaxFD()) return NULL;
57 h = &gaUserHandles[ FD ];
60 if(h->Node == NULL) return NULL;
61 //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
65 int VFS_SetHandle(int FD, tVFS_Node *Node, int Mode)
70 if( FD & VFS_KERNEL_FLAG ) {
71 FD &= (VFS_KERNEL_FLAG -1);
72 if( FD >= MAX_KERNEL_FILES ) return -1;
73 h = &gaKernelHandles[FD];
76 if( FD >= *Threads_GetMaxFD()) return -1;
77 h = &gaUserHandles[FD];
84 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
86 // Check for a user open
89 int max_handles = *Threads_GetMaxFD();
91 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
94 size = max_handles * sizeof(tVFS_Handle);
95 for(addr = 0; addr < size; addr += 0x1000)
97 if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
99 Warning("OOM - VFS_AllocHandle");
100 Threads_Exit(0, 0xFF); // Terminate user
103 memset( gaUserHandles, 0, size );
106 for( int i = 0; i < max_handles; i ++ )
108 if(gaUserHandles[i].Node) continue;
109 gaUserHandles[i].Node = Node;
110 gaUserHandles[i].Position = 0;
111 gaUserHandles[i].Mode = Mode;
117 // Allocate space if not already
118 if( MM_GetPhysAddr( gaKernelHandles ) == 0 )
121 size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
122 for(addr = 0; addr < size; addr += 0x1000)
124 if( !MM_Allocate( (tVAddr)gaKernelHandles + addr ) )
126 Panic("OOM - VFS_AllocHandle");
127 Threads_Exit(0, 0xFF); // Terminate application (get some space back)
130 memset( gaKernelHandles, 0, size );
133 for(int i=0;i<MAX_KERNEL_FILES;i++)
135 if(gaKernelHandles[i].Node) continue;
136 gaKernelHandles[i].Node = Node;
137 gaKernelHandles[i].Position = 0;
138 gaKernelHandles[i].Mode = Mode;
139 return i|VFS_KERNEL_FLAG;
146 void VFS_ReferenceUserHandles(void)
149 int max_handles = *Threads_GetMaxFD();
151 // Check if this process has any handles
152 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
155 for( i = 0; i < max_handles; i ++ )
158 h = &gaUserHandles[i];
161 _ReferenceNode(h->Node);
162 h->Mount->OpenHandleCount ++;
166 void VFS_CloseAllUserHandles(void)
169 int max_handles = *Threads_GetMaxFD();
171 // Check if this process has any handles
172 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
175 for( i = 0; i < max_handles; i ++ )
178 h = &gaUserHandles[i];
186 * \brief Take a backup of a set of file descriptors
188 void *VFS_SaveHandles(int NumFDs, int *FDs)
192 int max_handles = *Threads_GetMaxFD();
194 // Check if this process has any handles
195 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
199 ret = malloc( NumFDs * sizeof(tVFS_Handle) );
203 if( NumFDs > max_handles )
204 NumFDs = max_handles;
206 // Take copies of the handles
207 for( i = 0; i < NumFDs; i ++ )
211 h = &gaUserHandles[i];
212 else if( FDs[i] == -1 )
214 Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i);
215 memset(&ret[i], 0, sizeof(tVFS_Handle));
220 h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1));
222 Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i",
223 FDs[i] & (VFS_KERNEL_FLAG - 1) );
228 memcpy( &ret[i], h, sizeof(tVFS_Handle) );
233 _ReferenceNode(h->Node);
234 h->Mount->OpenHandleCount ++;
240 void VFS_RestoreHandles(int NumFDs, void *Handles)
242 tVFS_Handle *handles = Handles;
245 // NULL = nothing to do
249 // Check if there is already a set of handles
250 if( MM_GetPhysAddr( gaUserHandles ) != 0 )
254 // Allocate user handle area
257 int max_handles = *Threads_GetMaxFD();
258 size = max_handles * sizeof(tVFS_Handle);
259 for(addr = 0; addr < size; addr += 0x1000)
261 if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
263 Warning("OOM - VFS_AllocHandle");
264 Threads_Exit(0, 0xFF); // Terminate user
267 memset( gaUserHandles, 0, size );
271 memcpy( gaUserHandles, handles, NumFDs * sizeof(tVFS_Handle) );
272 // Reference when copied
273 for( i = 0; i < NumFDs; i ++ )
275 tVFS_Handle *h = &handles[i];
279 _ReferenceNode(h->Node);
280 h->Mount->OpenHandleCount ++;
284 void VFS_FreeSavedHandles(int NumFDs, void *Handles)
286 tVFS_Handle *handles = Handles;
289 // NULL = nothing to do
293 // Dereference all saved nodes
294 for( i = 0; i < NumFDs; i ++ )
296 tVFS_Handle *h = &handles[i];
302 ASSERT(h->Mount->OpenHandleCount > 0);
303 LOG("dec. mntpt '%s' to %i", h->Mount->MountPoint, h->Mount->OpenHandleCount-1);
304 h->Mount->OpenHandleCount --;