3 * - AllocHandle, GetHandle
12 #include <threads.h> // GetMaxFD
13 #include <vfs_threads.h> // Handle maintainance
16 #define MAX_KERNEL_FILES 128
21 tVFS_Handle *gaUserHandles = (void*)MM_PPD_HANDLES;
22 tVFS_Handle *gaKernelHandles = (void*)MM_KERNEL_VFS;
26 * \fn tVFS_Handle *VFS_GetHandle(int FD)
27 * \brief Gets a pointer to the handle information structure
29 tVFS_Handle *VFS_GetHandle(int FD)
33 //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD);
35 if(FD < 0) return NULL;
37 if(FD & VFS_KERNEL_FLAG) {
38 FD &= (VFS_KERNEL_FLAG - 1);
39 if(FD >= MAX_KERNEL_FILES) return NULL;
40 h = &gaKernelHandles[ FD ];
42 if(FD >= *Threads_GetMaxFD()) return NULL;
43 h = &gaUserHandles[ FD ];
46 if(h->Node == NULL) return NULL;
47 //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h);
51 int VFS_SetHandle(int FD, tVFS_Node *Node, int Mode)
56 if( FD & VFS_KERNEL_FLAG ) {
57 FD &= (VFS_KERNEL_FLAG -1);
58 if( FD >= MAX_KERNEL_FILES ) return -1;
59 h = &gaKernelHandles[FD];
62 if( FD >= *Threads_GetMaxFD()) return -1;
63 h = &gaUserHandles[FD];
70 int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
72 // Check for a user open
75 int max_handles = *Threads_GetMaxFD();
77 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
80 size = max_handles * sizeof(tVFS_Handle);
81 for(addr = 0; addr < size; addr += 0x1000)
83 if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
85 Warning("OOM - VFS_AllocHandle");
86 Threads_Exit(0, 0xFF); // Terminate user
89 memset( gaUserHandles, 0, size );
92 for( int i = 0; i < max_handles; i ++ )
94 if(gaUserHandles[i].Node) continue;
95 gaUserHandles[i].Node = Node;
96 gaUserHandles[i].Position = 0;
97 gaUserHandles[i].Mode = Mode;
103 // Allocate space if not already
104 if( MM_GetPhysAddr( gaKernelHandles ) == 0 )
107 size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
108 for(addr = 0; addr < size; addr += 0x1000)
110 if( !MM_Allocate( (tVAddr)gaKernelHandles + addr ) )
112 Panic("OOM - VFS_AllocHandle");
113 Threads_Exit(0, 0xFF); // Terminate application (get some space back)
116 memset( gaKernelHandles, 0, size );
119 for(int i=0;i<MAX_KERNEL_FILES;i++)
121 if(gaKernelHandles[i].Node) continue;
122 gaKernelHandles[i].Node = Node;
123 gaKernelHandles[i].Position = 0;
124 gaKernelHandles[i].Mode = Mode;
125 return i|VFS_KERNEL_FLAG;
132 void VFS_ReferenceUserHandles(void)
135 int max_handles = *Threads_GetMaxFD();
137 // Check if this process has any handles
138 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
141 for( i = 0; i < max_handles; i ++ )
144 h = &gaUserHandles[i];
147 _ReferenceNode(h->Node);
148 h->Mount->OpenHandleCount ++;
152 void VFS_CloseAllUserHandles(void)
155 int max_handles = *Threads_GetMaxFD();
157 // Check if this process has any handles
158 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
161 for( i = 0; i < max_handles; i ++ )
164 h = &gaUserHandles[i];
172 * \brief Take a backup of a set of file descriptors
174 void *VFS_SaveHandles(int NumFDs, int *FDs)
178 int max_handles = *Threads_GetMaxFD();
180 // Check if this process has any handles
181 if( MM_GetPhysAddr( gaUserHandles ) == 0 )
185 ret = malloc( NumFDs * sizeof(tVFS_Handle) );
189 if( NumFDs > max_handles )
190 NumFDs = max_handles;
192 // Take copies of the handles
193 for( i = 0; i < NumFDs; i ++ )
197 h = &gaUserHandles[i];
198 else if( FDs[i] == -1 )
200 Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i);
201 memset(&ret[i], 0, sizeof(tVFS_Handle));
206 h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1));
208 Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i",
209 FDs[i] & (VFS_KERNEL_FLAG - 1) );
214 memcpy( &ret[i], h, sizeof(tVFS_Handle) );
219 _ReferenceNode(h->Node);
220 h->Mount->OpenHandleCount ++;
226 void VFS_RestoreHandles(int NumFDs, void *Handles)
228 tVFS_Handle *handles = Handles;
231 // NULL = nothing to do
235 // Check if there is already a set of handles
236 if( MM_GetPhysAddr( gaUserHandles ) != 0 )
240 // Allocate user handle area
243 int max_handles = *Threads_GetMaxFD();
244 size = max_handles * sizeof(tVFS_Handle);
245 for(addr = 0; addr < size; addr += 0x1000)
247 if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
249 Warning("OOM - VFS_AllocHandle");
250 Threads_Exit(0, 0xFF); // Terminate user
253 memset( gaUserHandles, 0, size );
257 memcpy( gaUserHandles, handles, NumFDs * sizeof(tVFS_Handle) );
258 // Reference when copied
259 for( i = 0; i < NumFDs; i ++ )
261 tVFS_Handle *h = &handles[i];
265 _ReferenceNode(h->Node);
266 h->Mount->OpenHandleCount ++;
270 void VFS_FreeSavedHandles(int NumFDs, void *Handles)
272 tVFS_Handle *handles = Handles;
275 // NULL = nothing to do
279 // Dereference all saved nodes
280 for( i = 0; i < NumFDs; i ++ )
282 tVFS_Handle *h = &handles[i];
288 ASSERT(h->Mount->OpenHandleCount > 0);
289 LOG("dec. mntpt '%s' to %i", h->Mount->MountPoint, h->Mount->OpenHandleCount-1);
290 h->Mount->OpenHandleCount --;