* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "UserlandFS.h"
#include <KernelExport.h>
#include "Compatibility.h"
#include "Debug.h"
#include "FileSystem.h"
#include "FileSystemInitializer.h"
#include "KernelDebug.h"
#include "RequestPort.h"
#include "Requests.h"
#include "UserlandFSDefs.h"
UserlandFS* UserlandFS::sUserlandFS = NULL;
UserlandFS::UserlandFS()
:
fFileSystems(NULL),
fDebuggerCommandsAdded(false)
{
}
UserlandFS::~UserlandFS()
{
PRINT(("UserlandFS::~UserlandFS()\n"))
delete fFileSystems;
if (fDebuggerCommandsAdded)
KernelDebug::RemoveDebuggerCommands();
}
status_t
UserlandFS::InitUserlandFS(UserlandFS** _userlandFS)
{
sUserlandFS = new(nothrow) UserlandFS;
if (!sUserlandFS)
return B_NO_MEMORY;
status_t error = sUserlandFS->_Init();
if (error != B_OK) {
delete sUserlandFS;
sUserlandFS = NULL;
return error;
}
*_userlandFS = sUserlandFS;
return B_OK;
}
void
UserlandFS::UninitUserlandFS()
{
delete sUserlandFS;
sUserlandFS = NULL;
}
UserlandFS*
UserlandFS::GetUserlandFS()
{
return sUserlandFS;
}
status_t
UserlandFS::RegisterFileSystem(const char* name, FileSystem** _fileSystem)
{
if (!name || !_fileSystem)
return B_BAD_VALUE;
FileSystemInitializer* fileSystemInitializer;
{
FileSystemLocker _(fFileSystems);
fileSystemInitializer = fFileSystems->Get(name);
if (fileSystemInitializer) {
fileSystemInitializer->AcquireReference();
} else {
fileSystemInitializer = new(nothrow) FileSystemInitializer(name);
if (!fileSystemInitializer)
return B_NO_MEMORY;
status_t error = fFileSystems->Put(name, fileSystemInitializer);
if (error != B_OK) {
delete fileSystemInitializer;
return error;
}
}
}
status_t error = fileSystemInitializer->Access();
if (error != B_OK) {
_UnregisterFileSystem(name);
return error;
}
*_fileSystem = fileSystemInitializer->GetFileSystem();
return error;
}
status_t
UserlandFS::UnregisterFileSystem(FileSystem* fileSystem)
{
if (!fileSystem)
return B_BAD_VALUE;
return _UnregisterFileSystem(fileSystem->GetName());
}
int32
UserlandFS::CountFileSystems() const
{
return fFileSystems->Size();
}
status_t
UserlandFS::_Init()
{
KernelDebug::AddDebuggerCommands();
fDebuggerCommandsAdded = true;
fFileSystems = new(nothrow) FileSystemMap;
if (!fFileSystems)
RETURN_ERROR(B_NO_MEMORY);
status_t error = fFileSystems->InitCheck();
if (error != B_OK)
RETURN_ERROR(error);
return B_OK;
}
status_t
UserlandFS::_UnregisterFileSystem(const char* name)
{
if (!name)
return B_BAD_VALUE;
FileSystemInitializer* fileSystemInitializer = NULL;
bool deleteFS = false;
{
FileSystemLocker _(fFileSystems);
fileSystemInitializer = fFileSystems->Get(name);
if (!fileSystemInitializer)
return B_BAD_VALUE;
deleteFS = fileSystemInitializer->ReleaseReference() == 1;
if (deleteFS)
fFileSystems->Remove(name);
}
if (deleteFS)
delete fileSystemInitializer;
return B_OK;
}