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] == '/') {
*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;
// Find Mountpoint
longestMount = gVFS_RootMount;
+ RWLock_AcquireRead( &glVFS_MountList );
for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next)
{
// Quick Check
// 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;
// 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);
// EVIL: Goto :)
LOG("Symlink -> '%s', restart", Path);
+ mnt->OpenHandleCount --; // Not in this mountpoint
goto restart_parse;
}
*MountPoint = mnt;
}
+ // Leave the mointpoint's count increased
+
LEAVE('p', tmpNode);
return tmpNode;
free(*TruePath);
*TruePath = NULL;
}
+ // Open failed, so decrement the open handle count
+ mnt->OpenHandleCount --;
+
LEAVE('n');
return NULL;
}
{
// 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);
}
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));
}
#endif
_CloseNode(h->Node);
-
+
+ h->Mount->OpenHandleCount --;
+
h->Node = NULL;
}