FS shell changes:
* Added basic built-in module support. * Added rootfs. * Added "kernel" initialization. * Exposed the FS syscalls. * Mounting/unmounting the FS works now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20873 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -40,23 +40,16 @@ typedef struct fssh_module_dependency {
|
|||||||
} fssh_module_dependency;
|
} fssh_module_dependency;
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern status_t get_module(const char *path, module_info **_info);
|
extern fssh_status_t fssh_get_module(const char *path,
|
||||||
extern status_t put_module(const char *path);
|
fssh_module_info **_info);
|
||||||
extern status_t get_next_loaded_module_name(uint32 *cookie, char *buffer, size_t *_bufferSize);
|
extern fssh_status_t fssh_put_module(const char *path);
|
||||||
extern void *open_module_list(const char *prefix);
|
|
||||||
extern status_t close_module_list(void *cookie);
|
|
||||||
extern status_t read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
#endif /* _FSSH_MODULE_H */
|
#endif /* _FSSH_MODULE_H */
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ BuildPlatformStaticLibrary <build2>fs_shell.a :
|
|||||||
hash.cpp
|
hash.cpp
|
||||||
list.cpp
|
list.cpp
|
||||||
lock.cpp
|
lock.cpp
|
||||||
|
module.cpp
|
||||||
node_monitor.cpp
|
node_monitor.cpp
|
||||||
|
rootfs.cpp
|
||||||
sem.cpp
|
sem.cpp
|
||||||
stat.cpp
|
stat.cpp
|
||||||
stat_util.cpp
|
stat_util.cpp
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "fssh_kernel_priv.h"
|
#include "fssh_kernel_priv.h"
|
||||||
#include "fssh_string.h"
|
#include "fssh_string.h"
|
||||||
#include "fssh_uio.h"
|
#include "fssh_uio.h"
|
||||||
|
#include "syscalls.h"
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_FD
|
//#define TRACE_FD
|
||||||
|
|||||||
+107
-1
@@ -3,9 +3,115 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <BeOSBuildCompatibility.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fssh_errors.h"
|
||||||
|
#include "fssh_module.h"
|
||||||
|
#include "module.h"
|
||||||
|
#include "syscalls.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace FSShell;
|
||||||
|
|
||||||
|
namespace FSShell {
|
||||||
|
extern fssh_file_system_module_info gRootFileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern fssh_module_info *modules[];
|
||||||
|
|
||||||
|
|
||||||
|
static fssh_status_t
|
||||||
|
init_kernel()
|
||||||
|
{
|
||||||
|
fssh_status_t error;
|
||||||
|
|
||||||
|
// init module subsystem
|
||||||
|
error = module_init(NULL);
|
||||||
|
if (error != FSSH_B_OK) {
|
||||||
|
fprintf(stderr, "module_init() failed: %s\n", strerror(error));
|
||||||
|
return error;
|
||||||
|
} else
|
||||||
|
printf("module_init() succeeded!\n");
|
||||||
|
|
||||||
|
// register built-in modules, i.e. the rootfs and the client FS
|
||||||
|
register_builtin_module(&gRootFileSystem.info);
|
||||||
|
for (int i = 0; modules[i]; i++)
|
||||||
|
register_builtin_module(modules[i]);
|
||||||
|
|
||||||
|
// init VFS
|
||||||
|
error = vfs_init(NULL);
|
||||||
|
if (error != FSSH_B_OK) {
|
||||||
|
fprintf(stderr, "initializing VFS failed: %s\n", strerror(error));
|
||||||
|
return error;
|
||||||
|
} else
|
||||||
|
printf("VFS initialized successfully!\n");
|
||||||
|
|
||||||
|
// mount root FS
|
||||||
|
fssh_dev_t rootDev = _kern_mount("/", NULL, "rootfs", 0, NULL, 0);
|
||||||
|
if (rootDev < 0) {
|
||||||
|
fprintf(stderr, "mounting rootfs failed: %s\n", strerror(rootDev));
|
||||||
|
return rootDev;
|
||||||
|
} else
|
||||||
|
printf("mounted rootfs successfully!\n");
|
||||||
|
|
||||||
|
// create mount point for the client FS
|
||||||
|
error = _kern_create_dir(-1, "/myfs", 0775);
|
||||||
|
if (error != FSSH_B_OK) {
|
||||||
|
fprintf(stderr, "creating mount point failed: %s\n", strerror(error));
|
||||||
|
return error;
|
||||||
|
} else
|
||||||
|
printf("mount point created successfully!\n");
|
||||||
|
|
||||||
|
return FSSH_B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main(int argc, const char* const* argv)
|
||||||
{
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "Usage: ...\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* device = argv[1];
|
||||||
|
|
||||||
|
// get FS module
|
||||||
|
if (!modules[0]) {
|
||||||
|
fprintf(stderr, "Couldn't find FS module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const char* fsName = modules[0]->name;
|
||||||
|
|
||||||
|
fssh_status_t error;
|
||||||
|
|
||||||
|
// init kernel
|
||||||
|
error = init_kernel();
|
||||||
|
if (error != FSSH_B_OK) {
|
||||||
|
fprintf(stderr, "initializing kernel failed: %s\n", strerror(error));
|
||||||
|
return error;
|
||||||
|
} else
|
||||||
|
printf("kernel initialized successfully!\n");
|
||||||
|
|
||||||
|
// mount FS
|
||||||
|
fssh_dev_t fsDev = _kern_mount("/myfs", device, fsName, 0, NULL, 0);
|
||||||
|
if (fsDev < 0) {
|
||||||
|
fprintf(stderr, "mounting FS failed: %s\n", strerror(fsDev));
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
printf("mounted FS successfully!\n");
|
||||||
|
|
||||||
|
// unmount FS
|
||||||
|
error = _kern_unmount("/myfs", 0);
|
||||||
|
if (error != FSSH_B_OK) {
|
||||||
|
fprintf(stderr, "unmounting FS failed: %s\n", strerror(error));
|
||||||
|
return error;
|
||||||
|
} else
|
||||||
|
printf("FS unmounted successfully!\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2007, Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright 2001, Thomas Kurschel. All rights reserved.
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Manages kernel add-ons and their exported modules. */
|
||||||
|
|
||||||
|
#include "module.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "fssh_errors.h"
|
||||||
|
#include "fssh_kernel_export.h"
|
||||||
|
#include "fssh_module.h"
|
||||||
|
#include "fssh_string.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "lock.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#define TRACE_MODULE
|
||||||
|
#ifdef TRACE_MODULE
|
||||||
|
# define TRACE(x) fssh_dprintf x
|
||||||
|
#else
|
||||||
|
# define TRACE(x) ;
|
||||||
|
#endif
|
||||||
|
#define FATAL(x) fssh_dprintf x
|
||||||
|
|
||||||
|
|
||||||
|
namespace FSShell {
|
||||||
|
|
||||||
|
|
||||||
|
#define MODULE_HASH_SIZE 16
|
||||||
|
|
||||||
|
enum module_state {
|
||||||
|
MODULE_QUERIED = 0,
|
||||||
|
MODULE_LOADED,
|
||||||
|
MODULE_INIT,
|
||||||
|
MODULE_READY,
|
||||||
|
MODULE_UNINIT,
|
||||||
|
MODULE_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Each known module will have this structure which is put in the
|
||||||
|
* gModulesHash, and looked up by name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct module {
|
||||||
|
struct module *next;
|
||||||
|
char *name;
|
||||||
|
char *file;
|
||||||
|
int32_t ref_count;
|
||||||
|
fssh_module_info *info; /* will only be valid if ref_count > 0 */
|
||||||
|
int32_t offset; /* this is the offset in the headers */
|
||||||
|
module_state state; /* state of module */
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FSSH_B_BUILT_IN_MODULE 2
|
||||||
|
|
||||||
|
|
||||||
|
/* locking scheme: there is a global lock only; having several locks
|
||||||
|
* makes trouble if dependent modules get loaded concurrently ->
|
||||||
|
* they have to wait for each other, i.e. we need one lock per module;
|
||||||
|
* also we must detect circular references during init and not dead-lock
|
||||||
|
*/
|
||||||
|
static recursive_lock sModulesLock;
|
||||||
|
|
||||||
|
/* we store the loaded modules by directory path, and all known modules by module name
|
||||||
|
* in a hash table for quick access
|
||||||
|
*/
|
||||||
|
static hash_table *sModulesHash;
|
||||||
|
|
||||||
|
|
||||||
|
/** calculates hash for a module using its name */
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
module_hash(void *_module, const void *_key, uint32_t range)
|
||||||
|
{
|
||||||
|
module *module = (struct module *)_module;
|
||||||
|
const char *name = (const char *)_key;
|
||||||
|
|
||||||
|
if (module != NULL)
|
||||||
|
return hash_hash_string(module->name) % range;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
return hash_hash_string(name) % range;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** compares a module to a given name */
|
||||||
|
|
||||||
|
static int
|
||||||
|
module_compare(void *_module, const void *_key)
|
||||||
|
{
|
||||||
|
module *module = (struct module *)_module;
|
||||||
|
const char *name = (const char *)_key;
|
||||||
|
if (name == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return fssh_strcmp(module->name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
inc_module_ref_count(struct module *module)
|
||||||
|
{
|
||||||
|
module->ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dec_module_ref_count(struct module *module)
|
||||||
|
{
|
||||||
|
module->ref_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Extract the information from the module_info structure pointed at
|
||||||
|
* by "info" and create the entries required for access to it's details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static fssh_status_t
|
||||||
|
create_module(fssh_module_info *info, const char *file, int offset, module **_module)
|
||||||
|
{
|
||||||
|
module *module;
|
||||||
|
|
||||||
|
TRACE(("create_module(info = %p, file = \"%s\", offset = %d, _module = %p)\n",
|
||||||
|
info, file, offset, _module));
|
||||||
|
|
||||||
|
if (!info->name)
|
||||||
|
return FSSH_B_BAD_VALUE;
|
||||||
|
|
||||||
|
module = (struct module *)hash_lookup(sModulesHash, info->name);
|
||||||
|
if (module) {
|
||||||
|
FATAL(("Duplicate module name (%s) detected... ignoring new one\n", info->name));
|
||||||
|
return FSSH_B_FILE_EXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((module = (struct module *)malloc(sizeof(struct module))) == NULL)
|
||||||
|
return FSSH_B_NO_MEMORY;
|
||||||
|
|
||||||
|
TRACE(("create_module: name = \"%s\", file = \"%s\"\n", info->name, file));
|
||||||
|
|
||||||
|
module->name = fssh_strdup(info->name);
|
||||||
|
if (module->name == NULL) {
|
||||||
|
free(module);
|
||||||
|
return FSSH_B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
module->file = fssh_strdup(file);
|
||||||
|
if (module->file == NULL) {
|
||||||
|
free(module->name);
|
||||||
|
free(module);
|
||||||
|
return FSSH_B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
module->state = MODULE_QUERIED;
|
||||||
|
module->info = info;
|
||||||
|
module->offset = offset;
|
||||||
|
// record where the module_info can be found in the module_info array
|
||||||
|
module->ref_count = 0;
|
||||||
|
module->flags = info->flags;
|
||||||
|
|
||||||
|
recursive_lock_lock(&sModulesLock);
|
||||||
|
hash_insert(sModulesHash, module);
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
|
||||||
|
if (_module)
|
||||||
|
*_module = module;
|
||||||
|
|
||||||
|
return FSSH_B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Initializes a loaded module depending on its state */
|
||||||
|
|
||||||
|
static inline fssh_status_t
|
||||||
|
init_module(module *module)
|
||||||
|
{
|
||||||
|
switch (module->state) {
|
||||||
|
case MODULE_QUERIED:
|
||||||
|
case MODULE_LOADED:
|
||||||
|
{
|
||||||
|
fssh_status_t status;
|
||||||
|
module->state = MODULE_INIT;
|
||||||
|
|
||||||
|
// init module
|
||||||
|
|
||||||
|
TRACE(("initializing module %s (at %p)... \n", module->name, module->info->std_ops));
|
||||||
|
status = module->info->std_ops(FSSH_B_MODULE_INIT);
|
||||||
|
TRACE(("...done (%s)\n", strerror(status)));
|
||||||
|
|
||||||
|
if (status >= FSSH_B_OK)
|
||||||
|
module->state = MODULE_READY;
|
||||||
|
else {
|
||||||
|
module->state = MODULE_LOADED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MODULE_READY:
|
||||||
|
return FSSH_B_OK;
|
||||||
|
|
||||||
|
case MODULE_INIT:
|
||||||
|
FATAL(("circular reference to %s\n", module->name));
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
|
||||||
|
case MODULE_UNINIT:
|
||||||
|
FATAL(("tried to load module %s which is currently unloading\n", module->name));
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
|
||||||
|
case MODULE_ERROR:
|
||||||
|
FATAL(("cannot load module %s because its earlier unloading failed\n", module->name));
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
}
|
||||||
|
// never trespasses here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Uninitializes a module depeding on its state */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
uninit_module(module *module)
|
||||||
|
{
|
||||||
|
TRACE(("uninit_module(%s)\n", module->name));
|
||||||
|
|
||||||
|
switch (module->state) {
|
||||||
|
case MODULE_QUERIED:
|
||||||
|
case MODULE_LOADED:
|
||||||
|
return FSSH_B_NO_ERROR;
|
||||||
|
|
||||||
|
case MODULE_INIT:
|
||||||
|
fssh_panic("Trying to unload module %s which is initializing\n", module->name);
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
|
||||||
|
case MODULE_UNINIT:
|
||||||
|
fssh_panic("Trying to unload module %s which is un-initializing\n", module->name);
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
|
||||||
|
case MODULE_READY:
|
||||||
|
{
|
||||||
|
fssh_status_t status;
|
||||||
|
|
||||||
|
module->state = MODULE_UNINIT;
|
||||||
|
|
||||||
|
TRACE(("uninitializing module %s...\n", module->name));
|
||||||
|
status = module->info->std_ops(FSSH_B_MODULE_UNINIT);
|
||||||
|
TRACE(("...done (%s)\n", strerror(status)));
|
||||||
|
|
||||||
|
if (status == FSSH_B_NO_ERROR) {
|
||||||
|
module->state = MODULE_LOADED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FATAL(("Error unloading module %s (%s)\n", module->name, fssh_strerror(status)));
|
||||||
|
|
||||||
|
module->state = MODULE_ERROR;
|
||||||
|
module->flags |= FSSH_B_KEEP_LOADED;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
}
|
||||||
|
// never trespasses here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
register_builtin_module(struct fssh_module_info *info)
|
||||||
|
{
|
||||||
|
info->flags |= FSSH_B_BUILT_IN_MODULE;
|
||||||
|
// this is an internal flag, it doesn't have to be set by modules itself
|
||||||
|
|
||||||
|
if (create_module(info, "", -1, NULL) != FSSH_B_OK)
|
||||||
|
fssh_dprintf("creation of built-in module \"%s\" failed!\n", info->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
dump_modules(int argc, char **argv)
|
||||||
|
{
|
||||||
|
hash_iterator iterator;
|
||||||
|
struct module *module;
|
||||||
|
|
||||||
|
hash_rewind(sModulesHash, &iterator);
|
||||||
|
fssh_dprintf("-- known modules:\n");
|
||||||
|
|
||||||
|
while ((module = (struct module *)hash_next(sModulesHash, &iterator)) != NULL) {
|
||||||
|
fssh_dprintf("%p: \"%s\", \"%s\" (%d), refcount = %d, state = %d\n",
|
||||||
|
module, module->name, module->file, (int)module->offset, (int)module->ref_count,
|
||||||
|
module->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
// Exported Kernel API (private part)
|
||||||
|
|
||||||
|
|
||||||
|
/** Setup the module structures and data for use - must be called
|
||||||
|
* before any other module call.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fssh_status_t
|
||||||
|
module_init(kernel_args *args)
|
||||||
|
{
|
||||||
|
if (recursive_lock_init(&sModulesLock, "modules rlock") < FSSH_B_OK)
|
||||||
|
return FSSH_B_ERROR;
|
||||||
|
|
||||||
|
sModulesHash = hash_init(MODULE_HASH_SIZE, 0, module_compare, module_hash);
|
||||||
|
if (sModulesHash == NULL)
|
||||||
|
return FSSH_B_NO_MEMORY;
|
||||||
|
|
||||||
|
fssh_add_debugger_command("modules", &dump_modules, "list all known & loaded modules");
|
||||||
|
|
||||||
|
return FSSH_B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace FSShell
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
// Exported Kernel API (public part)
|
||||||
|
|
||||||
|
|
||||||
|
using namespace FSShell;
|
||||||
|
|
||||||
|
|
||||||
|
fssh_status_t
|
||||||
|
fssh_get_module(const char *path, fssh_module_info **_info)
|
||||||
|
{
|
||||||
|
module *module;
|
||||||
|
fssh_status_t status;
|
||||||
|
|
||||||
|
TRACE(("get_module(%s)\n", path));
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
return FSSH_B_BAD_VALUE;
|
||||||
|
|
||||||
|
recursive_lock_lock(&sModulesLock);
|
||||||
|
|
||||||
|
module = (struct module *)hash_lookup(sModulesHash, path);
|
||||||
|
if (module == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
// The state will be adjusted by the call to init_module
|
||||||
|
// if we have just loaded the file
|
||||||
|
if (module->ref_count == 0)
|
||||||
|
status = init_module(module);
|
||||||
|
else
|
||||||
|
status = FSSH_B_OK;
|
||||||
|
|
||||||
|
if (status == FSSH_B_OK) {
|
||||||
|
inc_module_ref_count(module);
|
||||||
|
*_info = module->info;
|
||||||
|
}
|
||||||
|
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
return status;
|
||||||
|
|
||||||
|
err:
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
return FSSH_B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fssh_status_t
|
||||||
|
fssh_put_module(const char *path)
|
||||||
|
{
|
||||||
|
module *module;
|
||||||
|
|
||||||
|
TRACE(("put_module(path = %s)\n", path));
|
||||||
|
|
||||||
|
recursive_lock_lock(&sModulesLock);
|
||||||
|
|
||||||
|
module = (struct module *)hash_lookup(sModulesHash, path);
|
||||||
|
if (module == NULL) {
|
||||||
|
FATAL(("module: We don't seem to have a reference to module %s\n", path));
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
return FSSH_B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((module->flags & FSSH_B_KEEP_LOADED) == 0) {
|
||||||
|
dec_module_ref_count(module);
|
||||||
|
|
||||||
|
if (module->ref_count == 0)
|
||||||
|
uninit_module(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
recursive_lock_unlock(&sModulesLock);
|
||||||
|
return FSSH_B_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FSSH_MODULE_PRIVATE_H
|
||||||
|
#define _FSSH_MODULE_PRIVATE_H
|
||||||
|
|
||||||
|
#include "fssh_defs.h"
|
||||||
|
|
||||||
|
struct fssh_module_info;
|
||||||
|
|
||||||
|
namespace FSShell {
|
||||||
|
|
||||||
|
struct kernel_args;
|
||||||
|
|
||||||
|
fssh_status_t module_init(kernel_args *args);
|
||||||
|
void register_builtin_module(struct fssh_module_info *info);
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace FSShell
|
||||||
|
|
||||||
|
#endif // _FSSH_MODULE_PRIVATE_H
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FSSH_SYSCALLS_H
|
||||||
|
#define _FSSH_SYSCALLS_H
|
||||||
|
|
||||||
|
#include "fssh_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct fssh_iovec;
|
||||||
|
|
||||||
|
|
||||||
|
// defined in vfs.cpp
|
||||||
|
fssh_dev_t _kern_mount(const char *path, const char *device,
|
||||||
|
const char *fsName, uint32_t flags, const char *args,
|
||||||
|
fssh_size_t argsLength);
|
||||||
|
fssh_status_t _kern_unmount(const char *path, uint32_t flags);
|
||||||
|
fssh_status_t _kern_read_fs_info(fssh_dev_t device,
|
||||||
|
struct fssh_fs_info *info);
|
||||||
|
fssh_status_t _kern_write_fs_info(fssh_dev_t device,
|
||||||
|
const struct fssh_fs_info *info, int mask);
|
||||||
|
fssh_status_t _kern_sync(void);
|
||||||
|
fssh_dev_t _kern_next_device(int32_t *_cookie);
|
||||||
|
int _kern_open_entry_ref(fssh_dev_t device, fssh_ino_t inode,
|
||||||
|
const char *name, int openMode, int perms);
|
||||||
|
int _kern_open(int fd, const char *path, int openMode, int perms);
|
||||||
|
int _kern_open_dir_entry_ref(fssh_dev_t device, fssh_ino_t inode,
|
||||||
|
const char *name);
|
||||||
|
int _kern_open_dir(int fd, const char *path);
|
||||||
|
fssh_status_t _kern_fcntl(int fd, int op, uint32_t argument);
|
||||||
|
fssh_status_t _kern_fsync(int fd);
|
||||||
|
fssh_status_t _kern_lock_node(int fd);
|
||||||
|
fssh_status_t _kern_unlock_node(int fd);
|
||||||
|
fssh_status_t _kern_create_dir_entry_ref(fssh_dev_t device, fssh_ino_t inode,
|
||||||
|
const char *name, int perms);
|
||||||
|
fssh_status_t _kern_create_dir(int fd, const char *path, int perms);
|
||||||
|
fssh_status_t _kern_remove_dir(int fd, const char *path);
|
||||||
|
fssh_status_t _kern_read_link(int fd, const char *path, char *buffer,
|
||||||
|
fssh_size_t *_bufferSize);
|
||||||
|
fssh_status_t _kern_create_symlink(int fd, const char *path,
|
||||||
|
const char *toPath, int mode);
|
||||||
|
fssh_status_t _kern_create_link(const char *path, const char *toPath);
|
||||||
|
fssh_status_t _kern_unlink(int fd, const char *path);
|
||||||
|
fssh_status_t _kern_rename(int oldFD, const char *oldPath, int newFD,
|
||||||
|
const char *newPath);
|
||||||
|
fssh_status_t _kern_access(const char *path, int mode);
|
||||||
|
fssh_status_t _kern_read_stat(int fd, const char *path, bool traverseLeafLink,
|
||||||
|
struct fssh_stat *stat, fssh_size_t statSize);
|
||||||
|
fssh_status_t _kern_write_stat(int fd, const char *path,
|
||||||
|
bool traverseLeafLink, const struct fssh_stat *stat,
|
||||||
|
fssh_size_t statSize, int statMask);
|
||||||
|
int _kern_open_attr_dir(int fd, const char *path);
|
||||||
|
int _kern_create_attr(int fd, const char *name, uint32_t type,
|
||||||
|
int openMode);
|
||||||
|
int _kern_open_attr(int fd, const char *name, int openMode);
|
||||||
|
fssh_status_t _kern_remove_attr(int fd, const char *name);
|
||||||
|
fssh_status_t _kern_rename_attr(int fromFile, const char *fromName,
|
||||||
|
int toFile, const char *toName);
|
||||||
|
int _kern_open_index_dir(fssh_dev_t device);
|
||||||
|
fssh_status_t _kern_create_index(fssh_dev_t device, const char *name,
|
||||||
|
uint32_t type, uint32_t flags);
|
||||||
|
fssh_status_t _kern_read_index_stat(fssh_dev_t device, const char *name,
|
||||||
|
struct fssh_stat *stat);
|
||||||
|
fssh_status_t _kern_remove_index(fssh_dev_t device, const char *name);
|
||||||
|
fssh_status_t _kern_getcwd(char *buffer, fssh_size_t size);
|
||||||
|
fssh_status_t _kern_setcwd(int fd, const char *path);
|
||||||
|
|
||||||
|
// defined in fd.cpp
|
||||||
|
fssh_ssize_t _kern_read(int fd, fssh_off_t pos, void *buffer,
|
||||||
|
fssh_size_t length);
|
||||||
|
fssh_ssize_t _kern_readv(int fd, fssh_off_t pos, const fssh_iovec *vecs,
|
||||||
|
fssh_size_t count);
|
||||||
|
fssh_ssize_t _kern_write(int fd, fssh_off_t pos, const void *buffer,
|
||||||
|
fssh_size_t length);
|
||||||
|
fssh_ssize_t _kern_writev(int fd, fssh_off_t pos, const fssh_iovec *vecs,
|
||||||
|
fssh_size_t count);
|
||||||
|
fssh_off_t _kern_seek(int fd, fssh_off_t pos, int seekType);
|
||||||
|
fssh_status_t _kern_ioctl(int fd, uint32_t op, void *buffer,
|
||||||
|
fssh_size_t length);
|
||||||
|
fssh_ssize_t _kern_read_dir(int fd, struct fssh_dirent *buffer,
|
||||||
|
fssh_size_t bufferSize, uint32_t maxCount);
|
||||||
|
fssh_status_t _kern_rewind_dir(int fd);
|
||||||
|
fssh_status_t _kern_close(int fd);
|
||||||
|
int _kern_dup(int fd);
|
||||||
|
int _kern_dup2(int ofd, int nfd);
|
||||||
|
|
||||||
|
#endif // _FSSH_SYSCALLS_H
|
||||||
@@ -20,11 +20,14 @@
|
|||||||
#include "fssh_fs_info.h"
|
#include "fssh_fs_info.h"
|
||||||
#include "fssh_fs_volume.h"
|
#include "fssh_fs_volume.h"
|
||||||
#include "fssh_kernel_export.h"
|
#include "fssh_kernel_export.h"
|
||||||
|
#include "fssh_module.h"
|
||||||
#include "fssh_stat.h"
|
#include "fssh_stat.h"
|
||||||
|
#include "fssh_stdio.h"
|
||||||
#include "fssh_string.h"
|
#include "fssh_string.h"
|
||||||
#include "fssh_unistd.h"
|
#include "fssh_unistd.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "KPath.h"
|
#include "KPath.h"
|
||||||
|
#include "syscalls.h"
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_VFS
|
//#define TRACE_VFS
|
||||||
@@ -459,8 +462,7 @@ put_mount(struct fs_mount *mount)
|
|||||||
static fssh_status_t
|
static fssh_status_t
|
||||||
put_file_system(fssh_file_system_module_info *fs)
|
put_file_system(fssh_file_system_module_info *fs)
|
||||||
{
|
{
|
||||||
// return put_module(fs->info.name);
|
return fssh_put_module(fs->info.name);
|
||||||
return FSSH_B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -473,22 +475,19 @@ put_file_system(fssh_file_system_module_info *fs)
|
|||||||
static fssh_file_system_module_info *
|
static fssh_file_system_module_info *
|
||||||
get_file_system(const char *fsName)
|
get_file_system(const char *fsName)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
char name[FSSH_B_FILE_NAME_LENGTH];
|
char name[FSSH_B_FILE_NAME_LENGTH];
|
||||||
if (strncmp(fsName, "file_systems/", strlen("file_systems/"))) {
|
if (fssh_strncmp(fsName, "file_systems/", fssh_strlen("file_systems/"))) {
|
||||||
// construct module name if we didn't get one
|
// construct module name if we didn't get one
|
||||||
// (we currently support only one API)
|
// (we currently support only one API)
|
||||||
snprintf(name, sizeof(name), "file_systems/%s/v1", fsName);
|
fssh_snprintf(name, sizeof(name), "file_systems/%s/v1", fsName);
|
||||||
fsName = NULL;
|
fsName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fssh_file_system_module_info *info;
|
fssh_file_system_module_info *info;
|
||||||
if (get_module(fsName ? fsName : name, (module_info **)&info) != FSSH_B_OK)
|
if (fssh_get_module(fsName ? fsName : name, (fssh_module_info **)&info) != FSSH_B_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
#endif // 0
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -4068,7 +4067,9 @@ fs_mount(char *path, const char *device, const char *fsName, uint32_t flags,
|
|||||||
|
|
||||||
if (!(flags & FSSH_B_MOUNT_VIRTUAL_DEVICE) && device) {
|
if (!(flags & FSSH_B_MOUNT_VIRTUAL_DEVICE) && device) {
|
||||||
// normalize the device path
|
// normalize the device path
|
||||||
status = normalizedDevice.SetTo(device, true);
|
// status = normalizedDevice.SetTo(device, true);
|
||||||
|
// NOTE: normalizing works only in our namespace.
|
||||||
|
status = normalizedDevice.SetTo(device, false);
|
||||||
if (status != FSSH_B_OK)
|
if (status != FSSH_B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user