/* * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #include "UserlandFS.h" #include #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; // constructor UserlandFS::UserlandFS() : fFileSystems(NULL), fDebuggerCommandsAdded(false) { } // destructor UserlandFS::~UserlandFS() { PRINT(("UserlandFS::~UserlandFS()\n")) delete fFileSystems; if (fDebuggerCommandsAdded) KernelDebug::RemoveDebuggerCommands(); } // InitUserlandFS status_t UserlandFS::InitUserlandFS(UserlandFS** _userlandFS) { // create the singleton instance sUserlandFS = new(nothrow) UserlandFS; if (!sUserlandFS) return B_NO_MEMORY; // init the thing status_t error = sUserlandFS->_Init(); if (error != B_OK) { delete sUserlandFS; sUserlandFS = NULL; return error; } *_userlandFS = sUserlandFS; return B_OK; } // UninitUserlandFS void UserlandFS::UninitUserlandFS() { delete sUserlandFS; sUserlandFS = NULL; } // GetUserlandFS UserlandFS* UserlandFS::GetUserlandFS() { return sUserlandFS; } // RegisterFileSystem status_t UserlandFS::RegisterFileSystem(const char* name, FileSystem** _fileSystem) { // check parameters if (!name || !_fileSystem) return B_BAD_VALUE; // check, if we do already know this file system, and create it, if not 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; } } } // prepare the file system status_t error = fileSystemInitializer->Access(); if (error != B_OK) { _UnregisterFileSystem(name); return error; } *_fileSystem = fileSystemInitializer->GetFileSystem(); return error; } // UnregisterFileSystem status_t UserlandFS::UnregisterFileSystem(FileSystem* fileSystem) { if (!fileSystem) return B_BAD_VALUE; return _UnregisterFileSystem(fileSystem->GetName()); } // CountFileSystems int32 UserlandFS::CountFileSystems() const { return fFileSystems->Size(); } // _Init status_t UserlandFS::_Init() { // add debugger commands KernelDebug::AddDebuggerCommands(); fDebuggerCommandsAdded = true; // create file system map 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; } // _UnregisterFileSystem status_t UserlandFS::_UnregisterFileSystem(const char* name) { if (!name) return B_BAD_VALUE; // find the FS and decrement its reference counter 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); } // delete the FS, if the last reference has been removed if (deleteFS) delete fileSystemInitializer; return B_OK; }