X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fopen.c;h=e7d6e1e80d2aa7eb0271b125ea349ebd8e1c8690;hb=4842e2d6740bcb81da4e94019285bfd2c45425b8;hp=1536d1a0f2c21a6c5a02c3db7e1387c8a7b2222f;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/open.c b/KernelLand/Kernel/vfs/open.c index 1536d1a0..e7d6e1e8 100644 --- a/KernelLand/Kernel/vfs/open.c +++ b/KernelLand/Kernel/vfs/open.c @@ -59,6 +59,9 @@ char *VFS_GetAbsPath(const char *Path) if( chroot == NULL ) chroot = ""; chrootLen = strlen(chroot); + // Trim trailing slash off chroot + if( chrootLen && chroot[chrootLen - 1] == '/' ) + chrootLen -= 1; // Check if the path is already absolute if(Path[0] == '/') { @@ -211,6 +214,7 @@ restart_parse: // Find Mountpoint longestMount = gVFS_RootMount; + RWLock_AcquireRead( &glVFS_MountList ); for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next) { // Quick Check @@ -219,25 +223,29 @@ restart_parse: // Length Check - If the length is smaller than the longest match sofar if(mnt->MountPointLen < longestMount->MountPointLen) continue; // String Compare - cmp = strcmp(Path, mnt->MountPoint); + cmp = strncmp(Path, mnt->MountPoint, mnt->MountPointLen); + // Not a match, continue + if(cmp != 0) continue; #if OPEN_MOUNT_ROOT // Fast Break - Request Mount Root - if(cmp == 0) { + if(Path[mnt->MountPointLen] == '\0') { if(TruePath) { *TruePath = malloc( mnt->MountPointLen+1 ); strcpy(*TruePath, mnt->MountPoint); } if(MountPoint) *MountPoint = mnt; + RWLock_Release( &glVFS_MountList ); + LOG("Mount %p root", mnt); LEAVE('p', mnt->RootNode); return mnt->RootNode; } #endif - // Not a match, continue - if(cmp != '/') continue; longestMount = mnt; } + longestMount->OpenHandleCount ++; // Increment assuimg it worked + RWLock_Release( &glVFS_MountList ); // Save to shorter variable mnt = longestMount; @@ -269,14 +277,14 @@ restart_parse: // Check permissions on root of filesystem if( !VFS_CheckACL(curNode, VFS_PERM_EXECUTE) ) { - //Log("Permissions fail on '%s'", Path); + LOG("Permissions failure on '%s'", Path); goto _error; } // Check if the node has a FindDir method if( !curNode->Type->FindDir ) { - //Log("FindDir fail on '%s'", Path); + LOG("Finddir failure on '%s'", Path); goto _error; } LOG("FindDir{=%p}(%p, '%s')", curNode->Type->FindDir, curNode, pathEle); @@ -330,6 +338,7 @@ restart_parse: // EVIL: Goto :) LOG("Symlink -> '%s', restart", Path); + mnt->OpenHandleCount --; // Not in this mountpoint goto restart_parse; } @@ -399,6 +408,8 @@ restart_parse: *MountPoint = mnt; } + // Leave the mointpoint's count increased + LEAVE('p', tmpNode); return tmpNode; @@ -409,6 +420,9 @@ _error: free(*TruePath); *TruePath = NULL; } + // Open failed, so decrement the open handle count + mnt->OpenHandleCount --; + LEAVE('n'); return NULL; } @@ -482,7 +496,10 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode) { // TODO: Translate `Mode` into ACL and node flags // Get parent, create node - VFS_MkNod(absPath, 0); + if( VFS_MkNod(absPath, 0) ) { + free(absPath); + return -1; + } node = VFS_ParsePath(absPath, NULL, &mnt); } @@ -565,6 +582,9 @@ int VFS_OpenChild(int FD, const char *Name, Uint Mode) LEAVE_RET('i', -1); } + // Increment open handle count, no problems with the mount going away as `h` is already open on it + h->Mount->OpenHandleCount ++; + LEAVE_RET('x', VFS_int_CreateHandle(node, h->Mount, Mode)); } @@ -625,7 +645,9 @@ void VFS_Close(int FD) #endif _CloseNode(h->Node); - + + h->Mount->OpenHandleCount --; + h->Node = NULL; }