X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fhandle.c;h=661ced8124adf7df94b85f09bd7600a6a81ad2fc;hb=b7d9f86f7a1c23be18b50d5c647fd5d3c08369c3;hp=1f3e379026d67f5e5e8cd826ec2c2f63f3d7b12d;hpb=36b950d17b828c7cd2e5e9dbe5fb4cbded89889c;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/handle.c b/KernelLand/Kernel/vfs/handle.c index 1f3e3790..661ced81 100644 --- a/KernelLand/Kernel/vfs/handle.c +++ b/KernelLand/Kernel/vfs/handle.c @@ -16,30 +16,12 @@ #define MAX_KERNEL_FILES 128 // === PROTOTYPES === -#if 0 -tVFS_Handle *VFS_GetHandle(int FD); -#endif -inline void _ReferenceNode(tVFS_Node *Node); - int VFS_AllocHandle(int FD, tVFS_Node *Node, int Mode); // === GLOBALS === tVFS_Handle *gaUserHandles = (void*)MM_PPD_HANDLES; tVFS_Handle *gaKernelHandles = (void*)MM_KERNEL_VFS; // === CODE === -inline void _ReferenceNode(tVFS_Node *Node) -{ - if( !MM_GetPhysAddr(Node->Type) ) { - Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted", - Node, Node->Type, MM_GetPhysAddr(&Node->Type)); - return ; - } - if( Node->Type && Node->Type->Reference ) - Node->Type->Reference( Node ); - else - Node->ReferenceCount ++; -} - /** * \fn tVFS_Handle *VFS_GetHandle(int FD) * \brief Gets a pointer to the handle information structure @@ -66,10 +48,27 @@ tVFS_Handle *VFS_GetHandle(int FD) return h; } -int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) +int VFS_SetHandle(int FD, tVFS_Node *Node, int Mode) { - int i; + tVFS_Handle *h; + if(FD < 0) return -1; + if( FD & VFS_KERNEL_FLAG ) { + FD &= (VFS_KERNEL_FLAG -1); + if( FD >= MAX_KERNEL_FILES ) return -1; + h = &gaKernelHandles[FD]; + } + else { + if( FD >= *Threads_GetMaxFD()) return -1; + h = &gaUserHandles[FD]; + } + h->Node = Node; + h->Mode = Mode; + return FD; +} + +int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) +{ // Check for a user open if(bIsUser) { @@ -77,20 +76,21 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) // Allocate Buffer if( MM_GetPhysAddr( gaUserHandles ) == 0 ) { - Uint addr, size; - size = max_handles * sizeof(tVFS_Handle); - for(addr = 0; addr < size; addr += 0x1000) + tPage *pageptr = (void*)gaUserHandles; + size_t size = max_handles * sizeof(tVFS_Handle); + for( size_t ofs = 0; ofs < size; ofs ++) { - if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) ) + if( !MM_Allocate( pageptr ) ) { Warning("OOM - VFS_AllocHandle"); Threads_Exit(0, 0xFF); // Terminate user } + pageptr ++; } memset( gaUserHandles, 0, size ); } // Get a handle - for( i = 0; i < max_handles; i ++ ) + for( int i = 0; i < max_handles; i ++ ) { if(gaUserHandles[i].Node) continue; gaUserHandles[i].Node = Node; @@ -104,20 +104,20 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) // Allocate space if not already if( MM_GetPhysAddr( gaKernelHandles ) == 0 ) { - Uint addr, size; - size = MAX_KERNEL_FILES * sizeof(tVFS_Handle); - for(addr = 0; addr < size; addr += 0x1000) + tPage *pageptr = (void*)gaKernelHandles; + size_t size = MAX_KERNEL_FILES * sizeof(tVFS_Handle); + for(size_t ofs = 0; ofs < size; ofs += size) { - if( !MM_Allocate( (tVAddr)gaKernelHandles + addr ) ) + if( !MM_Allocate( pageptr ) ) { Panic("OOM - VFS_AllocHandle"); - Threads_Exit(0, 0xFF); // Terminate application (get some space back) } + pageptr ++; } memset( gaKernelHandles, 0, size ); } // Get a handle - for(i=0;iNode); + memcpy( &ret[i], h, sizeof(tVFS_Handle) ); } - memcpy( &ret[i], h, sizeof(tVFS_Handle) ); - + } + + // Reference nodes/mounts + for( int i = 0; i < NumFDs; i ++ ) + { + tVFS_Handle *h = &ret[i]; // Reference node if( !h->Node ) continue ; +// Debug("VFS_SaveHandles: %i %p", i, h->Node); _ReferenceNode(h->Node); h->Mount->OpenHandleCount ++; } @@ -220,45 +235,58 @@ void *VFS_SaveHandles(int NumFDs, int *FDs) void VFS_RestoreHandles(int NumFDs, void *Handles) { tVFS_Handle *handles = Handles; - int i; + int max_handles = *Threads_GetMaxFD(); // NULL = nothing to do if( !Handles ) return ; - // Check if there is already a set of handles - if( MM_GetPhysAddr( gaUserHandles ) != 0 ) - return ; - - - // Allocate user handle area + // Allocate user handle area (and dereference existing handles) + for( int i = 0; i < NumFDs; i ++ ) { - Uint addr, size; - int max_handles = *Threads_GetMaxFD(); - size = max_handles * sizeof(tVFS_Handle); - for(addr = 0; addr < size; addr += 0x1000) + tVFS_Handle *h = &gaUserHandles[i]; + + if( !MM_GetPhysAddr(h) ) { - if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) ) + void *pg = (void*)( (tVAddr)h & ~(PAGE_SIZE-1) ); + if( !MM_Allocate( pg ) ) { - Warning("OOM - VFS_AllocHandle"); - Threads_Exit(0, 0xFF); // Terminate user + // OOM? + return ; } + memset(pg, 0, PAGE_SIZE); } - memset( gaUserHandles, 0, size ); + // Safe to dereference, as Threads_CloneTCB references handles + #if 1 + else + { + if(h->Node) + { + _CloseNode(h->Node); + h->Mount->OpenHandleCount --; + } + } + #endif } + // Clean up existing // Restore handles memcpy( gaUserHandles, handles, NumFDs * sizeof(tVFS_Handle) ); // Reference when copied - for( i = 0; i < NumFDs; i ++ ) + for( int i = 0; i < NumFDs; i ++ ) { - tVFS_Handle *h = &handles[i]; + tVFS_Handle *h = &gaUserHandles[i]; if( !h->Node ) continue ; +// Debug("VFS_RestoreHandles: %i %p", i, h->Node); _ReferenceNode(h->Node); h->Mount->OpenHandleCount ++; } + for( int i = NumFDs; i < max_handles; i ++ ) + { + gaUserHandles[i].Node = NULL; + } } void VFS_FreeSavedHandles(int NumFDs, void *Handles)