X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fhandle.c;h=d500aa91b775d5edddab8515cd12fc7233d7caea;hb=85362e8a4c919b58cd261345d29f26bae4ad75e2;hp=6173c29ade9a15b5cf50449c8347c04eba9ad247;hpb=c34752b7ccc945a70a2d9b1e505aa4a4de43163b;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/handle.c b/KernelLand/Kernel/vfs/handle.c index 6173c29a..d500aa91 100644 --- a/KernelLand/Kernel/vfs/handle.c +++ b/KernelLand/Kernel/vfs/handle.c @@ -39,7 +39,7 @@ tVFS_Handle *VFS_GetHandle(int FD) if(FD >= MAX_KERNEL_FILES) return NULL; h = &gaKernelHandles[ FD ]; } else { - if(FD >= *Threads_GetMaxFD()) return NULL; + if(FD >= *Threads_GetMaxFD(NULL)) return NULL; h = &gaUserHandles[ FD ]; } @@ -59,7 +59,7 @@ int VFS_SetHandle(int FD, tVFS_Node *Node, int Mode) h = &gaKernelHandles[FD]; } else { - if( FD >= *Threads_GetMaxFD()) return -1; + if( FD >= *Threads_GetMaxFD(NULL)) return -1; h = &gaUserHandles[FD]; } h->Node = Node; @@ -72,19 +72,20 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) // Check for a user open if(bIsUser) { - int max_handles = *Threads_GetMaxFD(); + int max_handles = *Threads_GetMaxFD(NULL); // 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 ); } @@ -103,15 +104,15 @@ 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 ); } @@ -131,14 +132,13 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) void VFS_ReferenceUserHandles(void) { - int i; - int max_handles = *Threads_GetMaxFD(); + const int max_handles = *Threads_GetMaxFD(NULL); // Check if this process has any handles if( MM_GetPhysAddr( gaUserHandles ) == 0 ) return ; - for( i = 0; i < max_handles; i ++ ) + for( int i = 0; i < max_handles; i ++ ) { tVFS_Handle *h; h = &gaUserHandles[i]; @@ -149,23 +149,34 @@ void VFS_ReferenceUserHandles(void) } } -void VFS_CloseAllUserHandles(void) +void VFS_CloseAllUserHandles(struct sProcess *Process) { - int i; - int max_handles = *Threads_GetMaxFD(); + const int max_handles = *Threads_GetMaxFD(Process); + ENTER("pProcess", Process); + + if( max_handles >= PAGE_SIZE / sizeof(tVFS_Handle) ) + TODO("More than a page of handles"); + tVFS_Handle *handles = MM_MapTempFromProc(Process, gaUserHandles); + LOG("handles=%p", handles); // Check if this process has any handles - if( MM_GetPhysAddr( gaUserHandles ) == 0 ) + if( !handles ) { + LEAVE('-'); return ; + } - for( i = 0; i < max_handles; i ++ ) + for( int i = 0; i < max_handles; i ++ ) { - tVFS_Handle *h; - h = &gaUserHandles[i]; + tVFS_Handle *h = &handles[i]; + LOG("handles[%i].Node = %p", i, h->Node); if( !h->Node ) continue ; _CloseNode(h->Node); + h->Node = NULL; } + + MM_FreeTemp(handles); + LEAVE('-'); } /** @@ -174,8 +185,7 @@ void VFS_CloseAllUserHandles(void) void *VFS_SaveHandles(int NumFDs, int *FDs) { tVFS_Handle *ret; - int i; - int max_handles = *Threads_GetMaxFD(); + const int max_handles = *Threads_GetMaxFD(NULL); // Check if this process has any handles if( MM_GetPhysAddr( gaUserHandles ) == 0 ) @@ -190,32 +200,42 @@ void *VFS_SaveHandles(int NumFDs, int *FDs) NumFDs = max_handles; // Take copies of the handles - for( i = 0; i < NumFDs; i ++ ) + if( FDs == NULL ) { + memcpy(ret, gaUserHandles, NumFDs * sizeof(tVFS_Handle)); + } + else { - tVFS_Handle *h; - if( FDs == NULL ) - h = &gaUserHandles[i]; - else if( FDs[i] == -1 ) - { - Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i); - memset(&ret[i], 0, sizeof(tVFS_Handle)); - continue ; - } - else + for( int i = 0; i < NumFDs; i ++ ) { - h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1)); + if( FDs[i] < -1 ) + { + Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (%i<0), ignorning", + i, FDs[i]); + memset(&ret[i], 0, sizeof(tVFS_Handle)); + continue ; + } + + int fd = FDs[i] & (VFS_KERNEL_FLAG - 1); + tVFS_Handle *h = VFS_GetHandle(fd); if(!h) { - Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i", - FDs[i] & (VFS_KERNEL_FLAG - 1) ); + Log_Warning("VFS", "VFS_SaveHandles - Invalid FD 0x%x (%i) in slot %i", + fd, FDs[i], i ); free(ret); return NULL; } +// Log("%i: Duplicate FD %i (%p)", i, fd, h->Node); + 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 ++; } @@ -226,45 +246,63 @@ void *VFS_SaveHandles(int NumFDs, int *FDs) void VFS_RestoreHandles(int NumFDs, void *Handles) { tVFS_Handle *handles = Handles; - int i; + const int max_handles = *Threads_GetMaxFD(NULL); // 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 + if( NumFDs > max_handles ) { + Log_Notice("VFS", "RestoreHandles: Capping from %i FDs to %i", NumFDs, max_handles); + NumFDs = max_handles; + } + + // 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) ) + { + void *pg = (void*)( (tVAddr)h & ~(PAGE_SIZE-1) ); + if( !MM_Allocate( pg ) ) + { + // OOM? + return ; + } + memset(pg, 0, PAGE_SIZE); + } + // Safe to dereference, as Threads_CloneTCB references handles + #if 1 + else { - if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) ) + if(h->Node) { - Warning("OOM - VFS_AllocHandle"); - Threads_Exit(0, 0xFF); // Terminate user + _CloseNode(h->Node); + h->Mount->OpenHandleCount --; } } - memset( gaUserHandles, 0, size ); + #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)