Exemple #1
0
/**
 * \brief Take a backup of a set of file descriptors
 */
void *VFS_SaveHandles(int NumFDs, int *FDs)
{
	tVFS_Handle	*ret;
	const int	max_handles = *Threads_GetMaxFD(NULL);
	
	// Check if this process has any handles
	if( MM_GetPhysAddr( gaUserHandles ) == 0 )
		return NULL;

	// Allocate
	ret = malloc( NumFDs * sizeof(tVFS_Handle) );
	if( !ret )
		return NULL;	

	if( NumFDs > max_handles )
		NumFDs = max_handles;

	// Take copies of the handles
	if( FDs == NULL ) {
		memcpy(ret, gaUserHandles, NumFDs * sizeof(tVFS_Handle));
	}
	else
	{
		for( int i = 0; i < NumFDs; i ++ )
		{
			if( FDs[i] < -1 )
			{
				Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (%i<0), ignorning",
					i, FDs[i]);
				memset(&ret[i], 0, sizeof(tVFS_Handle));
				continue ;
			}
			
			int fd = FDs[i] & (VFS_KERNEL_FLAG - 1);
			tVFS_Handle *h = VFS_GetHandle(fd);
			if(!h) {
				Log_Warning("VFS", "VFS_SaveHandles - Invalid FD 0x%x (%i) in slot %i",
					fd, FDs[i], i );
				free(ret);
				return NULL;
			}
//			Log("%i: Duplicate FD %i (%p)", i, fd, h->Node);
			memcpy( &ret[i], h, sizeof(tVFS_Handle) );
		}
	}
	
	// Reference nodes/mounts
	for( int i = 0; i < NumFDs; i ++ )
	{
		tVFS_Handle *h = &ret[i];
		// Reference node
		if( !h->Node )
			continue ;
//		Debug("VFS_SaveHandles: %i %p", i, h->Node);
		_ReferenceNode(h->Node);
		h->Mount->OpenHandleCount ++;
	}	

	return ret;
}
Exemple #2
0
/**
 * \brief Take a backup of a set of file descriptors
 */
void *VFS_SaveHandles(int NumFDs, int *FDs)
{
	tVFS_Handle	*ret;
	 int	i;
	 int	max_handles = *Threads_GetMaxFD();
	
	// Check if this process has any handles
	if( MM_GetPhysAddr( gaUserHandles ) == 0 )
		return NULL;

	// Allocate
	ret = malloc( NumFDs * sizeof(tVFS_Handle) );
	if( !ret )
		return NULL;	

	if( NumFDs > max_handles )
		NumFDs = max_handles;

	// Take copies of the handles
	for( i = 0; i < NumFDs; i ++ )
	{
		tVFS_Handle	*h;
		if( FDs == NULL )
			h = &gaUserHandles[i];
		else if( FDs[i] == -1 )
		{
			Log_Warning("VFS", "VFS_SaveHandles - Slot %i error FD (-1), ignorning", i);
			memset(&ret[i], 0, sizeof(tVFS_Handle));
			continue ;
		}
		else
		{
			h = VFS_GetHandle(FDs[i] & (VFS_KERNEL_FLAG - 1));
			if(!h) {
				Log_Warning("VFS", "VFS_SaveHandles - Invalid FD %i",
					FDs[i] & (VFS_KERNEL_FLAG - 1) );
				free(ret);
				return NULL;
			}
		}
		memcpy( &ret[i], h, sizeof(tVFS_Handle) );
		
		// Reference node
		if( !h->Node )
			continue ;
		_ReferenceNode(h->Node);
		h->Mount->OpenHandleCount ++;
	}	

	return ret;
}
Exemple #3
0
void VFS_ReferenceUserHandles(void)
{
	const int	max_handles = *Threads_GetMaxFD(NULL);

	// Check if this process has any handles
	if( MM_GetPhysAddr( gaUserHandles ) == 0 )
		return ;
	
	for( int i = 0; i < max_handles; i ++ )
	{
		tVFS_Handle	*h;
		h = &gaUserHandles[i];
		if( !h->Node )
			continue ;
		_ReferenceNode(h->Node);
		h->Mount->OpenHandleCount ++;
	}
}
Exemple #4
0
void VFS_CloseAllUserHandles(void)
{
	 int	i;
	 int	max_handles = *Threads_GetMaxFD();

	// Check if this process has any handles
	if( MM_GetPhysAddr( gaUserHandles ) == 0 )
		return ;
	
	for( i = 0; i < max_handles; i ++ )
	{
		tVFS_Handle	*h;
		h = &gaUserHandles[i];
		if( !h->Node )
			continue ;
		_CloseNode(h->Node);
	}
}
Exemple #5
0
void VFS_RestoreHandles(int NumFDs, void *Handles)
{
	tVFS_Handle	*handles = Handles;
	 int	i;

	// NULL = nothing to do
	if( !Handles )
		return ;	

	// Check if there is already a set of handles
	if( MM_GetPhysAddr( gaUserHandles ) != 0 )
		return ;
	
	
	// Allocate user handle area
	{
		Uint	addr, size;
		 int	max_handles = *Threads_GetMaxFD();
		size = max_handles * sizeof(tVFS_Handle);
		for(addr = 0; addr < size; addr += 0x1000)
		{
			if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
			{
				Warning("OOM - VFS_AllocHandle");
				Threads_Exit(0, 0xFF);	// Terminate user
			}
		}
		memset( gaUserHandles, 0, size );
	}
	
	// Restore handles
	memcpy(	gaUserHandles, handles, NumFDs * sizeof(tVFS_Handle) );
	// Reference when copied
	for( i = 0; i < NumFDs; i ++ )
	{
		tVFS_Handle	*h = &handles[i];
	
		if( !h->Node )
			continue ;
		_ReferenceNode(h->Node);
		h->Mount->OpenHandleCount ++;
	}
}
Exemple #6
0
int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
{
	// Check for a user open
	if(bIsUser)
	{
		 int	max_handles = *Threads_GetMaxFD(NULL);
		// Allocate Buffer
		if( MM_GetPhysAddr( gaUserHandles ) == 0 )
		{
			tPage	*pageptr = (void*)gaUserHandles;
			size_t	size = max_handles * sizeof(tVFS_Handle);
			for( size_t ofs = 0; ofs < size; ofs ++)
			{
				if( !MM_Allocate( pageptr ) )
				{
					Warning("OOM - VFS_AllocHandle");
					Threads_Exit(0, 0xFF);	// Terminate user
				}
				pageptr ++;
			}
			memset( gaUserHandles, 0, size );
		}
		// Get a handle
		for( int i = 0; i < max_handles; i ++ )
		{
			if(gaUserHandles[i].Node)	continue;
			gaUserHandles[i].Node = Node;
			gaUserHandles[i].Position = 0;
			gaUserHandles[i].Mode = Mode;
			return i;
		}
	}
	else
	{
		// Allocate space if not already
		if( MM_GetPhysAddr( gaKernelHandles ) == 0 )
		{
			tPage	*pageptr = (void*)gaKernelHandles;
			size_t	size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
			for(size_t ofs = 0; ofs < size; ofs += size)
			{
				if( !MM_Allocate( pageptr ) )
				{
					Panic("OOM - VFS_AllocHandle");
				}
				pageptr ++;
			}
			memset( gaKernelHandles, 0, size );
		}
		// Get a handle
		for(int i=0;i<MAX_KERNEL_FILES;i++)
		{
			if(gaKernelHandles[i].Node)	continue;
			gaKernelHandles[i].Node = Node;
			gaKernelHandles[i].Position = 0;
			gaKernelHandles[i].Mode = Mode;
			return i|VFS_KERNEL_FLAG;
		}
	}
	
	return -1;
}
Exemple #7
0
void VFS_RestoreHandles(int NumFDs, void *Handles)
{
	tVFS_Handle	*handles = Handles;
	const int	max_handles = *Threads_GetMaxFD(NULL);

	// NULL = nothing to do
	if( !Handles )
		return ;
	
	if( NumFDs > max_handles ) {
		Log_Notice("VFS", "RestoreHandles: Capping from %i FDs to %i", NumFDs, max_handles);
		NumFDs = max_handles;
	}

	// Allocate user handle area (and dereference existing handles)
	for( int i = 0; i < NumFDs; i ++ )
	{
		tVFS_Handle *h = &gaUserHandles[i];
		
		if( !MM_GetPhysAddr(h) )
		{
			void	*pg = (void*)( (tVAddr)h & ~(PAGE_SIZE-1) );
			if( !MM_Allocate( pg ) ) 
			{
				// OOM?
				return ;
			}
			memset(pg, 0, PAGE_SIZE);
		}
		// Safe to dereference, as Threads_CloneTCB references handles
		#if 1
		else
		{
			if(h->Node)
			{
				_CloseNode(h->Node);
				h->Mount->OpenHandleCount --;
			}
		}
		#endif
	}
	
	// Clean up existing
	// Restore handles
	memcpy(	gaUserHandles, handles, NumFDs * sizeof(tVFS_Handle) );
	// Reference when copied
	for( int i = 0; i < NumFDs; i ++ )
	{
		tVFS_Handle	*h = &gaUserHandles[i];
	
		if( !h->Node )
			continue ;
//		Debug("VFS_RestoreHandles: %i %p", i, h->Node);
		_ReferenceNode(h->Node);
		h->Mount->OpenHandleCount ++;
	}
	for( int i = NumFDs; i < max_handles; i ++ )
	{
		gaUserHandles[i].Node = NULL;
	}
}
Exemple #8
0
int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
{
	// Check for a user open
	if(bIsUser)
	{
		 int	max_handles = *Threads_GetMaxFD();
		// Allocate Buffer
		if( MM_GetPhysAddr( gaUserHandles ) == 0 )
		{
			Uint	addr, size;
			size = max_handles * sizeof(tVFS_Handle);
			for(addr = 0; addr < size; addr += 0x1000)
			{
				if( !MM_Allocate( (tVAddr)gaUserHandles + addr ) )
				{
					Warning("OOM - VFS_AllocHandle");
					Threads_Exit(0, 0xFF);	// Terminate user
				}
			}
			memset( gaUserHandles, 0, size );
		}
		// Get a handle
		for( int i = 0; i < max_handles; i ++ )
		{
			if(gaUserHandles[i].Node)	continue;
			gaUserHandles[i].Node = Node;
			gaUserHandles[i].Position = 0;
			gaUserHandles[i].Mode = Mode;
			return i;
		}
	}
	else
	{
		// Allocate space if not already
		if( MM_GetPhysAddr( gaKernelHandles ) == 0 )
		{
			Uint	addr, size;
			size = MAX_KERNEL_FILES * sizeof(tVFS_Handle);
			for(addr = 0; addr < size; addr += 0x1000)
			{
				if( !MM_Allocate( (tVAddr)gaKernelHandles + addr ) )
				{
					Panic("OOM - VFS_AllocHandle");
					Threads_Exit(0, 0xFF);	// Terminate application (get some space back)
				}
			}
			memset( gaKernelHandles, 0, size );
		}
		// Get a handle
		for(int i=0;i<MAX_KERNEL_FILES;i++)
		{
			if(gaKernelHandles[i].Node)	continue;
			gaKernelHandles[i].Node = Node;
			gaKernelHandles[i].Position = 0;
			gaKernelHandles[i].Mode = Mode;
			return i|VFS_KERNEL_FLAG;
		}
	}
	
	return -1;
}
Exemple #9
0
// === CODE ===
int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd)
{
	 int	nPMemMapEnts = 0;
	
	ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd",
		MBInfo, MapOffset, Map, MapSize, KStart, KEnd);

	// Check that the memory map is present
	if( MBInfo->Flags & (1 << 6) )
	{
		tMBoot_MMapEnt	*ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
		tMBoot_MMapEnt	*last = (void*)((tVAddr)ent + MBInfo->MMapLength);
		// Build up memory map
		nPMemMapEnts = 0;
		while( ent < last && nPMemMapEnts < MapSize )
		{
			tPMemMapEnt	*nent = &Map[nPMemMapEnts];
			if( !MM_GetPhysAddr(ent) )
				Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
					nPMemMapEnts, ent);
			LOG("%llx+%llx", ent->Base, ent->Length);
	
			nent->Start = ent->Base;
			nent->Length = ent->Length;
			switch(ent->Type)
			{
			case 1:
				nent->Type = PMEMTYPE_FREE;
				break;
			default:
				nent->Type = PMEMTYPE_RESERVED;
				break;
			}
			nent->NUMADomain = 0;
			
			nPMemMapEnts ++;
			ent = (void*)( (tVAddr)ent + ent->Size + 4 );
		}
		if( ent < last )
		{
			Log_Warning("MBoot", "Memory map has >%i entries, internal version is truncated",
				MapSize);
		}
	}
	else if( MBInfo->Flags & (1 << 0) )
	{
		Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
		ASSERT(MapSize >= 2);
		nPMemMapEnts = 2;
		Map[0].Start = 0;
		Map[0].Length = MBInfo->LowMem * 1024;
		Map[0].Type = PMEMTYPE_FREE;
		Map[0].NUMADomain = 0;

		Map[1].Start = 0x100000;
		Map[1].Length = MBInfo->HighMem * 1024;
		Map[1].Type = PMEMTYPE_FREE;
		Map[1].NUMADomain = 0;
	}
	else
	{
		Log_KernelPanic("MBoot", "Multiboot didn't pass memory information");
	}

	// Ensure it's valid
	LOG("Validating");
	nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
	// TODO: Error handling

	// Replace kernel with PMEMTYPE_USED
	LOG("Marking kernel");
	nPMemMapEnts = PMemMap_MarkRangeUsed(
		Map, nPMemMapEnts, MapSize,
		KStart, KEnd - KStart
		);

	LOG("Dumping");
	PMemMap_DumpBlocks(Map, nPMemMapEnts);

	// Check if boot modules were passed
	if( MBInfo->Flags & (1 << 3) )
	{
		// Replace modules with PMEMTYPE_USED
		nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize,
			MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module)
			);
		LOG("MBInfo->Modules = %x", MBInfo->Modules);
		tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset);
		for( int i = 0; i < MBInfo->ModuleCount; i ++ )
		{
			LOG("&mods[%i] = %p", i, &mods[i]);
			LOG("mods[i] = {0x%x -> 0x%x}", mods[i].Start, mods[i].End);
			nPMemMapEnts = PMemMap_MarkRangeUsed(
				Map, nPMemMapEnts, MapSize,
				mods[i].Start, mods[i].End - mods[i].Start
				);
		}
	}
		
	// Debug - Output map
	PMemMap_DumpBlocks(Map, nPMemMapEnts);

	LEAVE('i', nPMemMapEnts);
	return nPMemMapEnts;
}