X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fopen.c;h=e7d6e1e80d2aa7eb0271b125ea349ebd8e1c8690;hb=11dbd684e9a3d907d43d71a3145205f1a86992fb;hp=cfb296b643e9e5e0187523639e907832eb9d5a28;hpb=7dcbae6762b50bdd450559ca455f2374a09f1df9;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/open.c b/KernelLand/Kernel/vfs/open.c index cfb296b6..e7d6e1e8 100644 --- a/KernelLand/Kernel/vfs/open.c +++ b/KernelLand/Kernel/vfs/open.c @@ -214,6 +214,7 @@ restart_parse: // Find Mountpoint longestMount = gVFS_RootMount; + RWLock_AcquireRead( &glVFS_MountList ); for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next) { // Quick Check @@ -222,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; @@ -333,6 +338,7 @@ restart_parse: // EVIL: Goto :) LOG("Symlink -> '%s', restart", Path); + mnt->OpenHandleCount --; // Not in this mountpoint goto restart_parse; } @@ -402,6 +408,8 @@ restart_parse: *MountPoint = mnt; } + // Leave the mointpoint's count increased + LEAVE('p', tmpNode); return tmpNode; @@ -412,6 +420,9 @@ _error: free(*TruePath); *TruePath = NULL; } + // Open failed, so decrement the open handle count + mnt->OpenHandleCount --; + LEAVE('n'); return NULL; } @@ -485,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); } @@ -568,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)); } @@ -628,7 +645,9 @@ void VFS_Close(int FD) #endif _CloseNode(h->Node); - + + h->Mount->OpenHandleCount --; + h->Node = NULL; }