X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fopen.c;h=344b2a14510dea9b897a6c794bd3d119b4b29cdb;hb=12dead97026f98253325bb6fa90500c89f792d61;hp=cfb296b643e9e5e0187523639e907832eb9d5a28;hpb=7dcbae6762b50bdd450559ca455f2374a09f1df9;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/open.c b/KernelLand/Kernel/vfs/open.c index cfb296b6..344b2a14 100644 --- a/KernelLand/Kernel/vfs/open.c +++ b/KernelLand/Kernel/vfs/open.c @@ -201,6 +201,7 @@ restart_parse: *TruePath = malloc( gVFS_RootMount->MountPointLen+1 ); strcpy(*TruePath, gVFS_RootMount->MountPoint); } + gVFS_RootMount->OpenHandleCount ++; if(MountPoint) *MountPoint = gVFS_RootMount; LEAVE('p', gVFS_RootMount->RootNode); return gVFS_RootMount->RootNode; @@ -214,6 +215,7 @@ restart_parse: // Find Mountpoint longestMount = gVFS_RootMount; + RWLock_AcquireRead( &glVFS_MountList ); for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next) { // Quick Check @@ -222,25 +224,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; @@ -277,9 +283,16 @@ restart_parse: } // Check if the node has a FindDir method + if( !curNode->Type ) + { + LOG("Finddir failure on '%s' - No type", Path); + Log_Error("VFS", "Node at '%s' has no type (mount %s:%s)", + Path, mnt->Filesystem->Name, mnt->MountPoint); + goto _error; + } if( !curNode->Type->FindDir ) { - LOG("Finddir failure on '%s'", Path); + LOG("Finddir failure on '%s' - No FindDir method in %s", Path, curNode->Type->Name); goto _error; } LOG("FindDir{=%p}(%p, '%s')", curNode->Type->FindDir, curNode, pathEle); @@ -333,6 +346,7 @@ restart_parse: // EVIL: Goto :) LOG("Symlink -> '%s', restart", Path); + mnt->OpenHandleCount --; // Not in this mountpoint goto restart_parse; } @@ -402,6 +416,8 @@ restart_parse: *MountPoint = mnt; } + // Leave the mointpoint's count increased + LEAVE('p', tmpNode); return tmpNode; @@ -412,6 +428,9 @@ _error: free(*TruePath); *TruePath = NULL; } + // Open failed, so decrement the open handle count + mnt->OpenHandleCount --; + LEAVE('n'); return NULL; } @@ -485,7 +504,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); } @@ -568,6 +590,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)); } @@ -628,7 +653,10 @@ void VFS_Close(int FD) #endif _CloseNode(h->Node); - + + if( h->Mount ) + h->Mount->OpenHandleCount --; + h->Node = NULL; }