X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fopen.c;h=983a2b238bb38b79476c34a1ef9fa2cb12434752;hb=eb44a9b9c61d2b3a16884cb88805a6f5263539e5;hp=2865f7811de4552ef1d812a89bd8004d0290b230;hpb=3d16754198031c1fe2e5b012f7313aff4261ec2a;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/open.c b/KernelLand/Kernel/vfs/open.c index 2865f781..983a2b23 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 @@ -223,6 +225,8 @@ restart_parse: if(mnt->MountPointLen < longestMount->MountPointLen) continue; // String Compare cmp = strncmp(Path, mnt->MountPoint, mnt->MountPointLen); + // Not a match, continue + if(cmp != 0) continue; #if OPEN_MOUNT_ROOT // Fast Break - Request Mount Root @@ -233,14 +237,16 @@ restart_parse: } 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 != 0) 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; } @@ -674,7 +702,7 @@ int VFS_ChDir(const char *Dest) *cwdptr = buf; } - Log("Updated CWD to '%s'", buf); + Log_Debug("VFS", "Updated CWD to '%s'", buf); return 1; }