Moved the creation and initialization of the FileSystem subclass instance

into the FS interface specific libraries, thus making the server completely
independent of those.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29359 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-02-28 18:56:35 +00:00
parent dd0eadec73
commit afd265501f
7 changed files with 166 additions and 149 deletions
@@ -4,7 +4,8 @@
#define USERLAND_FS_FILE_SYSTEM_H
#include <fs_interface.h>
#include <SupportDefs.h>
#include <image.h>
#include <OS.h>
#include "FSCapabilities.h"
@@ -35,4 +36,9 @@ protected:
using UserlandFS::FileSystem;
// implemented by the interface implementations
extern "C" status_t userlandfs_create_file_system(const char* fsName,
image_id image, FileSystem** _fileSystem);
#endif // USERLAND_FS_FILE_SYSTEM_H
@@ -5,6 +5,7 @@ local userlandFSTop = [ FDirName $(HAIKU_TOP) src add-ons kernel
local userlandFSIncludes = [ PrivateHeaders userlandfs ] ;
SubDirSysHdrs [ FDirName $(userlandFSIncludes) ] ;
UsePrivateHeaders libroot ;
SubDirHdrs [ FDirName $(userlandFSIncludes) private ] ;
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
@@ -13,6 +13,8 @@
#include <Locker.h>
#include <Path.h>
#include <image_private.h>
#include "AutoDeleter.h"
#include "AutoLocker.h"
#include "Compatibility.h"
@@ -23,20 +25,9 @@
#include "RequestThread.h"
#include "ServerDefs.h"
#if 0
#include "beos_fs_cache.h"
#include "beos_fs_interface.h"
#include "BeOSKernelFileSystem.h"
#include "haiku_block_cache.h"
#include "haiku_condition_variable.h"
#include "haiku_fs_cache.h"
#include "HaikuKernelFileSystem.h"
#endif
static const int32 kRequestThreadCount = 10;
static const int32 kMaxBlockCacheBlocks = 16384;
// constructor
UserlandFSServer::UserlandFSServer(const char* signature)
@@ -44,8 +35,7 @@ UserlandFSServer::UserlandFSServer(const char* signature)
fAddOnImage(-1),
fFileSystem(NULL),
fNotificationRequestPort(NULL),
fRequestThreads(NULL),
fBlockCacheInitialized(false)
fRequestThreads(NULL)
{
}
@@ -61,11 +51,6 @@ UserlandFSServer::~UserlandFSServer()
}
delete fNotificationRequestPort;
delete fFileSystem;
// TODO:...
#if 0
if (fBlockCacheInitialized)
beos_shutdown_block_cache();
#endif
if (fAddOnImage >= 0)
unload_add_on(fAddOnImage);
}
@@ -91,17 +76,21 @@ UserlandFSServer::Init(const char* fileSystem)
if (fAddOnImage < 0)
RETURN_ERROR(fAddOnImage);
// Get the FS creation function -- the add-on links against one of our
// libraries exporting that function, so we search recursively.
union {
void* address;
status_t (*function)(const char*, image_id, FileSystem**);
} createFSFunction;
error = get_image_symbol_etc(fAddOnImage, "userlandfs_create_file_system",
B_SYMBOL_TYPE_TEXT, true, NULL, &createFSFunction.address);
if (error != B_OK)
RETURN_ERROR(error);
// create the FileSystem interface
// BeOS kernel interface
if (_CreateBeOSKernelInterface(fileSystem, fAddOnImage, &fFileSystem)
== B_OK) {
// BeOS interface
} else if (_CreateHaikuKernelInterface(fileSystem, fAddOnImage,
&fFileSystem) == B_OK) {
// Haiku interface
} else {
ERROR(("Add-on doesn't has a supported interface.\n"));
}
error = createFSFunction.function(fileSystem, fAddOnImage, &fFileSystem);
if (error != B_OK)
RETURN_ERROR(error);
// create the notification request port
fNotificationRequestPort = new(nothrow) RequestPort(kRequestPortSize);
@@ -211,110 +200,3 @@ UserlandFSServer::_RegisterWithDispatcher(const char* fsName)
}
return error;
}
// _CreateBeOSKernelInterface
status_t
UserlandFSServer::_CreateBeOSKernelInterface(const char* fsName, image_id image,
FileSystem** _fileSystem)
{
// TODO: Implement!
#if 0
// get the symbols "fs_entry" and "api_version"
beos_vnode_ops* fsOps;
status_t error = get_image_symbol(image, "fs_entry", B_SYMBOL_TYPE_DATA,
(void**)&fsOps);
if (error != B_OK)
RETURN_ERROR(error);
int32* apiVersion;
error = get_image_symbol(image, "api_version", B_SYMBOL_TYPE_DATA,
(void**)&apiVersion);
if (error != B_OK)
RETURN_ERROR(error);
// check api version
if (*apiVersion != BEOS_FS_API_VERSION)
RETURN_ERROR(B_ERROR);
// create the file system
BeOSKernelFileSystem* fileSystem = new(nothrow) BeOSKernelFileSystem(fsOps);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
ObjectDeleter<BeOSKernelFileSystem> fsDeleter(fileSystem);
// init the block cache
error = beos_init_block_cache(kMaxBlockCacheBlocks, 0);
if (error != B_OK)
RETURN_ERROR(error);
fBlockCacheInitialized = true;
// everything went fine
fsDeleter.Detach();
*_fileSystem = fileSystem;
return B_OK;
#endif
return B_ERROR;
}
// _CreateHaikuKernelInterface
status_t
UserlandFSServer::_CreateHaikuKernelInterface(const char* fsName,
image_id image, FileSystem** _fileSystem)
{
// TODO: Implement!
#if 0
// get the modules
module_info** modules;
status_t error = get_image_symbol(image, "modules", B_SYMBOL_TYPE_DATA,
(void**)&modules);
if (error != B_OK)
RETURN_ERROR(error);
// module name must match "file_systems/<name>/v1"
char moduleName[B_PATH_NAME_LENGTH];
snprintf(moduleName, sizeof(moduleName), "file_systems/%s/v1", fsName);
// find the module
file_system_module_info* module = NULL;
for (int32 i = 0; modules[i]->name; i++) {
if (strcmp(modules[i]->name, moduleName) == 0) {
module = (file_system_module_info*)modules[i];
break;
}
}
if (!module)
RETURN_ERROR(B_ERROR);
// create the file system
HaikuKernelFileSystem* fileSystem
= new(nothrow) HaikuKernelFileSystem(module);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
ObjectDeleter<HaikuKernelFileSystem> fsDeleter(fileSystem);
// init condition variables
error = UserlandFS::HaikuKernelEmu::condition_variable_init();
if (error != B_OK)
RETURN_ERROR(error);
// init block cache
error = UserlandFS::HaikuKernelEmu::block_cache_init();
if (error != B_OK)
RETURN_ERROR(error);
// init file cache
error = UserlandFS::HaikuKernelEmu::file_cache_init();
if (error != B_OK)
RETURN_ERROR(error);
// init the FS
error = fileSystem->Init();
if (error != B_OK)
return error;
// everything went fine
fsDeleter.Detach();
*_fileSystem = fileSystem;
return B_OK;
#endif
return B_ERROR;
}
@@ -28,17 +28,12 @@ public:
private:
status_t _RegisterWithDispatcher(const char* fsName);
status_t _CreateBeOSKernelInterface(const char* fsName,
image_id image, FileSystem** fileSystem);
status_t _CreateHaikuKernelInterface(const char* fsName,
image_id image, FileSystem** fileSystem);
private:
image_id fAddOnImage;
FileSystem* fFileSystem;
RequestPort* fNotificationRequestPort;
RequestThread* fRequestThreads;
bool fBlockCacheInitialized;
};
} // namespace UserlandFS
@@ -5,23 +5,46 @@
#include <new>
#include "BeOSKernelVolume.h"
#include "fs_cache.h"
#include "fs_interface.h"
using std::nothrow;
static const int32 kMaxBlockCacheBlocks = 16384;
// constructor
BeOSKernelFileSystem::BeOSKernelFileSystem(beos_vnode_ops* fsOps)
: FileSystem(),
fFSOps(fsOps)
:
FileSystem(),
fFSOps(fsOps),
fBlockCacheInitialized(false)
{
_InitCapabilities();
}
// destructor
BeOSKernelFileSystem::~BeOSKernelFileSystem()
{
if (fBlockCacheInitialized)
beos_shutdown_block_cache();
}
// Init
status_t
BeOSKernelFileSystem::Init()
{
// init the block cache
status_t error = beos_init_block_cache(kMaxBlockCacheBlocks, 0);
if (error != B_OK)
RETURN_ERROR(error);
fBlockCacheInitialized = true;
return B_OK;
}
// CreateVolume
status_t
BeOSKernelFileSystem::CreateVolume(Volume** volume, dev_t id)
@@ -31,7 +54,7 @@ BeOSKernelFileSystem::CreateVolume(Volume** volume, dev_t id)
return B_BAD_VALUE;
// create the volume
*volume = new(nothrow) BeOSKernelVolume(this, id, fFSOps);
*volume = new(std::nothrow) BeOSKernelVolume(this, id, fFSOps);
if (!*volume)
return B_NO_MEMORY;
return B_OK;
@@ -181,3 +204,43 @@ BeOSKernelFileSystem::_InitCapabilities()
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME_ATTR, fFSOps->rename_attr);
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_ATTR, fFSOps->remove_attr);
}
// #pragma mark - bootstrapping
status_t
userlandfs_create_file_system(const char* fsName, image_id image,
FileSystem** _fileSystem)
{
// get the symbols "fs_entry" and "api_version"
beos_vnode_ops* fsOps;
status_t error = get_image_symbol(image, "fs_entry", B_SYMBOL_TYPE_DATA,
(void**)&fsOps);
if (error != B_OK)
RETURN_ERROR(error);
int32* apiVersion;
error = get_image_symbol(image, "api_version", B_SYMBOL_TYPE_DATA,
(void**)&apiVersion);
if (error != B_OK)
RETURN_ERROR(error);
// check api version
if (*apiVersion != BEOS_FS_API_VERSION)
RETURN_ERROR(B_ERROR);
// create the file system
BeOSKernelFileSystem* fileSystem
= new(std::nothrow) BeOSKernelFileSystem(fsOps);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
error = fileSystem->Init();
if (error != B_OK) {
delete fileSystem;
return error;
}
*_fileSystem = fileSystem;
return B_OK;
}
@@ -14,6 +14,8 @@ public:
BeOSKernelFileSystem(beos_vnode_ops* fsOps);
virtual ~BeOSKernelFileSystem();
status_t Init();
virtual status_t CreateVolume(Volume** volume, dev_t id);
virtual status_t DeleteVolume(Volume* volume);
@@ -31,6 +33,7 @@ private:
beos_vnode_ops* fFSOps;
FSVolumeCapabilities fVolumeCapabilities;
FSVNodeCapabilities fNodeCapabilities;
bool fBlockCacheInitialized;
};
} // namespace UserlandFS
@@ -2,13 +2,16 @@
#include "HaikuKernelFileSystem.h"
#include <string.h>
#include <new>
#include <fs_interface.h>
#include "block_cache.h"
#include "condition_variable.h"
#include "HaikuKernelVolume.h"
using std::nothrow;
// constructor
HaikuKernelFileSystem::HaikuKernelFileSystem(file_system_module_info* fsModule)
@@ -24,16 +27,34 @@ HaikuKernelFileSystem::~HaikuKernelFileSystem()
// call the kernel module uninitialization
if (fFSModule->info.std_ops)
fFSModule->info.std_ops(B_MODULE_UNINIT);
// TODO: Call the cleanup methods (condition vars, block cache)!
}
// Init
status_t
HaikuKernelFileSystem::Init()
{
// call the kernel module initialization
// init condition variables
status_t error = condition_variable_init();
if (error != B_OK)
RETURN_ERROR(error);
// TODO: Call the cleanup methods, if something goes wrong!
// init block cache
error = block_cache_init();
if (error != B_OK)
RETURN_ERROR(error);
// call the kernel module initialization (if any)
if (!fFSModule->info.std_ops)
return B_OK;
return fFSModule->info.std_ops(B_MODULE_INIT);
error = fFSModule->info.std_ops(B_MODULE_INIT);
if (error != B_OK)
RETURN_ERROR(error);
return B_OK;
}
// CreateVolume
@@ -45,7 +66,7 @@ HaikuKernelFileSystem::CreateVolume(Volume** volume, dev_t id)
return B_BAD_VALUE;
// create the volume
*volume = new(nothrow) HaikuKernelVolume(this, id, fFSModule);
*volume = new(std::nothrow) HaikuKernelVolume(this, id, fFSModule);
if (!*volume)
return B_NO_MEMORY;
return B_OK;
@@ -73,3 +94,49 @@ HaikuKernelFileSystem::_InitCapabilities()
// FS operations
fCapabilities.Set(FS_CAPABILITY_MOUNT, fFSModule->mount);
}
// #pragma mark - bootstrapping
status_t
userlandfs_create_file_system(const char* fsName, image_id image,
FileSystem** _fileSystem)
{
// get the modules
module_info** modules;
status_t error = get_image_symbol(image, "modules", B_SYMBOL_TYPE_DATA,
(void**)&modules);
if (error != B_OK)
RETURN_ERROR(error);
// module name must match "file_systems/<name>/v1"
char moduleName[B_PATH_NAME_LENGTH];
snprintf(moduleName, sizeof(moduleName), "file_systems/%s/v1", fsName);
// find the module
file_system_module_info* module = NULL;
for (int32 i = 0; modules[i]->name; i++) {
if (strcmp(modules[i]->name, moduleName) == 0) {
module = (file_system_module_info*)modules[i];
break;
}
}
if (!module)
RETURN_ERROR(B_ERROR);
// create the file system
HaikuKernelFileSystem* fileSystem
= new(std::nothrow) HaikuKernelFileSystem(module);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
error = fileSystem->Init();
if (error != B_OK) {
delete fileSystem;
return error;
}
*_fileSystem = fileSystem;
return B_OK;
}