aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-09 19:24:42 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-09 19:24:42 +0100
commit440d9dc470703d20a55365b3a560196e71d450d4 (patch)
treebcc864c7aeb0af7a81c4fcd7430fa8c3001f8383 /src/kernel/user
parentcaf842864bdc0794e387f9580af96ab1036996f4 (diff)
downloadkogata-440d9dc470703d20a55365b3a560196e71d450d4.tar.gz
kogata-440d9dc470703d20a55365b3a560196e71d450d4.zip
Start work on filesystems.
Diffstat (limited to 'src/kernel/user')
-rw-r--r--src/kernel/user/nullfs.c30
-rw-r--r--src/kernel/user/process.c23
-rw-r--r--src/kernel/user/vfs.c126
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 :*/