diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/FileSystem.h b/src/add-ons/kernel/file_systems/userlandfs/server/FileSystem.h index 3bdd594653..08c7173d0d 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/FileSystem.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/FileSystem.h @@ -4,7 +4,8 @@ #define USERLAND_FS_FILE_SYSTEM_H #include -#include +#include +#include #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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile b/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile index 5bc1cec566..920c93e829 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile +++ b/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile @@ -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 ] ; diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp index 625aa7c993..6c06aea0ee 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp @@ -13,6 +13,8 @@ #include #include +#include + #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 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//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 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; -} diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h index c3e7bf02f9..8dd7089c30 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.cpp index 880baaf078..e308994b2a 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.cpp @@ -5,23 +5,46 @@ #include #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; +} diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.h b/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.h index 3859045478..d74cf7a43c 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/beos/BeOSKernelFileSystem.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/HaikuKernelFileSystem.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/HaikuKernelFileSystem.cpp index 3fbb69bbf2..3024dd1931 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/HaikuKernelFileSystem.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/HaikuKernelFileSystem.cpp @@ -2,13 +2,16 @@ #include "HaikuKernelFileSystem.h" +#include + #include #include +#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//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; +}