diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-09 19:24:42 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-09 19:24:42 +0100 |
commit | 440d9dc470703d20a55365b3a560196e71d450d4 (patch) | |
tree | bcc864c7aeb0af7a81c4fcd7430fa8c3001f8383 /src/kernel/user | |
parent | caf842864bdc0794e387f9580af96ab1036996f4 (diff) | |
download | kogata-440d9dc470703d20a55365b3a560196e71d450d4.tar.gz kogata-440d9dc470703d20a55365b3a560196e71d450d4.zip |
Start work on filesystems.
Diffstat (limited to 'src/kernel/user')
-rw-r--r-- | src/kernel/user/nullfs.c | 30 | ||||
-rw-r--r-- | src/kernel/user/process.c | 23 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 126 |
3 files changed, 159 insertions, 20 deletions
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c new file mode 100644 index 0000000..3c11198 --- /dev/null +++ b/src/kernel/user/nullfs.c @@ -0,0 +1,30 @@ +#include <nullfs.h> + +bool nullfs_i_make(fs_handle_t *source, char* opts, fs_t *d); + +fs_driver_ops_t nullfs_driver_ops = { + .make = nullfs_i_make, + .detect = 0, +}; + +fs_ops_t nullfs_ops = { + 0 //TODO +}; + +void register_nullfs_driver() { + register_fs_driver("nullfs", &nullfs_driver_ops); +} + +nullfs_t *make_nullfs(char* options) { + fs_t *it = make_fs("nullfs", 0, options); + if (it == 0) return 0; + if (it->ops != &nullfs_ops) return 0; + return (nullfs_t*)it->data; +} + +bool nullfs_i_make(fs_handle_t *source, char* opts, fs_t *d) { + // TODO + return false; +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index 7519dae..22295ef 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -2,29 +2,12 @@ #include <process.h> typedef struct process { - thread_t *thread; - int pid; - - mutex_t com_mutex; + pagedir_t *pd; - hashtbl_t *chans; - chan_id_t next_chan_id; - - message_t mbox[PROCESS_MAILBOX_SIZE]; - int mbox_size; // number of messages in queue - int mbox_first; // first message in queue (circular buffer) + thread_t *thread; - // a process can be in several waiting states : - // - wait for any message - // - wait for a message on a particular channel - // in this case, if a message is pushed on this particular channel, - // then it is put in front of the queue, so that it is the next message read - // (it is guaranteed that doing await_message_on_chan() immediately followed by get_message() - // gets the message whose size was returned by await_...) - int wait_state; - chan_id_t wait_chan_id; // when waiting for a message on a particular channel + int pid, ppid; } process_t; -int push_message(process_t *proc, message_t msg); // nonnull on error (process queue is full) /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c new file mode 100644 index 0000000..ebd5808 --- /dev/null +++ b/src/kernel/user/vfs.c @@ -0,0 +1,126 @@ +#include <debug.h> +#include <vfs.h> +#include <string.h> + +// ============================= // +// FILESYSTEM DRIVER REGISTERING // +// ============================= // + +typedef struct fs_driver { + const char* name; + fs_driver_ops_t *ops; + struct fs_driver *next; +} fs_driver_t; + +fs_driver_t *drivers = 0; + +void register_fs_driver(const char* name, fs_driver_ops_t *ops) { + fs_driver_t *d = (fs_driver_t*)malloc(sizeof(fs_driver_t)); + ASSERT(d != 0); // should we fail in a more graceful manner ? + + d->name = name; + d->ops = ops; + d->next = drivers; + drivers = d; +} + +// ================================== // +// CREATING AND DELETINF FILE SYSTEMS // +// ================================== // + +fs_t *make_fs(const char* drv_name, fs_handle_t *source, char* opts) { + // Look for driver + fs_driver_t *d = 0; + for(fs_driver_t *i = drivers; i != 0; i = i->next) { + if (drv_name != 0 && strcmp(i->name, drv_name) == 0) d = i; + if (drv_name == 0 && source != 0 && i->ops->detect && i->ops->detect(source)) d = i; + if (d != 0) break; + } + + // Open file system + fs_t *fs = (fs_t*)malloc(sizeof(fs_t)); + if (fs == 0) return 0; + + if (d->ops->make(source, opts, fs)) { + return fs; + } else { + free(fs); + return 0; + } +} + +bool fs_add_source(fs_t *fs, fs_handle_t *source) { + return fs->ops->add_source && fs->ops->add_source(fs->data, source); +} + +void ref_fs(fs_t *fs) { + fs->refs++; +} + +void unref_fs(fs_t *fs) { + fs->refs--; + if (fs->refs == 0) { + fs->ops->shutdown(fs->data); + free(fs); + } +} + +// DOING THINGS IN FLESYSTEMS // + +bool fs_delete(fs_t *fs, const char* file) { + return fs->ops->delete && fs->ops->delete(fs->data, file); +} + +bool fs_rename(fs_t *fs, const char* from, const char* to) { + return fs->ops->rename && fs->ops->rename(fs->data, from, to); +} + +bool fs_stat(fs_t *fs, const char* name, stat_t *st) { + return fs->ops->stat && fs->ops->stat(fs->data, name, st); +} + +int fs_ioctl(fs_t *fs, const char* file, int command, void* data) { + return fs->ops->ioctl && fs->ops->ioctl(fs->data, file, command, data); +} + +// =================== // +// OPERATIONS ON FILES // +// =================== // + +fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) { + fs_handle_t *h = (fs_handle_t*)malloc(sizeof(fs_handle_t)); + if (h == 0) return 0; + + if (fs->ops->open(fs->data, file, mode, h)) { + return h; + } else { + free(h); + return 0; + } +} + +void ref_file(fs_handle_t *file) { + file->refs++; +} + +void unrefe_file(fs_handle_t *file) { + file->refs--; + if (file->refs == 0) { + file->ops->close(file->data); + free(file); + } +} + +size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) { + return f->ops->read && f->ops->read(f->data, offset, len, buf); +} + +size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) { + return f->ops->write && f->ops->write(f->data, offset, len, buf); +} + +int file_get_mode(fs_handle_t *f) { + return f->mode; +} + +/* vim: set ts=4 sw=4 tw=0 noet :*/ |