Merge branch 'master' of git://localhost/acess2
[tpg/acess2.git] / KernelLand / Kernel / vfs / open.c
index cfb296b..983a2b2 100644 (file)
@@ -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;
 }
 
@@ -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;
 }

UCC git Repository :: git.ucc.asn.au