aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/config.h2
-rw-r--r--src/kernel/include/prng.h2
-rw-r--r--src/kernel/include/vfs.h9
-rw-r--r--src/kernel/user/vfs.c24
4 files changed, 25 insertions, 12 deletions
diff --git a/src/kernel/config.h b/src/kernel/config.h
index 96e9aa1..e7b9591 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -1,3 +1,5 @@
+#pragma once
+
#if !defined(__cplusplus)
#include <stdbool.h>
#endif
diff --git a/src/kernel/include/prng.h b/src/kernel/include/prng.h
index 0a9e036..4321ada 100644
--- a/src/kernel/include/prng.h
+++ b/src/kernel/include/prng.h
@@ -1,3 +1,5 @@
+#pragma once
+
#include <stdint.h>
#include <stddef.h>
diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h
index a34681b..90944b2 100644
--- a/src/kernel/include/vfs.h
+++ b/src/kernel/include/vfs.h
@@ -40,15 +40,22 @@ struct fs;
struct fs_node;
typedef struct user_region user_region_t;
+typedef struct fs_node_ops fs_node_ops_t;
// -------------------------------------------
// Structure defining a handle to an open file
// This structure is entirely managed by the VFS, the underlying filesystem does not see it
+// For IPC structures (sockets, channels), fs and node are null because the handle does not reference
+// an underlying object. The ops and data fields are filled in by the IPC code with corresponding
+// data structures. All VFS calls are done on ops and data as specified in the handle and not the node.
typedef struct fs_handle {
struct fs *fs;
struct fs_node *node;
+ fs_node_ops_t *ops;
+ fs_node_ptr data;
+
int refs;
int mode;
@@ -74,7 +81,7 @@ typedef struct fs_handle {
// - dispose() is not called on the root node when a filesystem is shutdown
// - delete() is not expected to delete recursively : it should fail on a non-empty directory
-typedef struct {
+typedef struct fs_node_ops {
bool (*open)(fs_node_ptr n, int mode);
size_t (*read)(fs_node_ptr f, size_t offset, size_t len, char* buf);
size_t (*write)(fs_node_ptr f, size_t offset, size_t len, const char* buf);
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index a02dc9b..2af8cf0 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -427,6 +427,8 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) {
h->fs = fs;
h->node = n;
h->mode = mode;
+ h->ops = n->ops;
+ h->data = n->data;
// our reference to node n is transferred to the file handle
mutex_unlock(&n->lock);
@@ -447,9 +449,9 @@ void ref_file(fs_handle_t *file) {
void unref_file(fs_handle_t *file) {
file->refs--;
if (file->refs == 0) {
- file->node->ops->close(file->node->data);
- unref_fs_node(file->node);
- unref_fs(file->fs);
+ file->ops->close(file->data);
+ if (file->node) unref_fs_node(file->node);
+ if (file->fs) unref_fs(file->fs);
free(file);
}
}
@@ -461,35 +463,35 @@ int file_get_mode(fs_handle_t *f) {
size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) {
if (!(f->mode & FM_READ)) return 0;
- if (f->node->ops->read == 0) return 0;
+ if (f->ops->read == 0) return 0;
- return f->node->ops->read(f->node->data, offset, len, buf);
+ return 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) {
if (!(f->mode & FM_WRITE)) return 0;
- if (f->node->ops->write == 0) return 0;
+ if (f->ops->write == 0) return 0;
- return f->node->ops->write(f->node->data, offset, len, buf);
+ return f->ops->write(f->data, offset, len, buf);
}
bool file_stat(fs_handle_t *f, stat_t *st) {
- return f->node->ops->stat && f->node->ops->stat(f->node->data, st);
+ return f->ops->stat && f->ops->stat(f->data, st);
}
int file_ioctl(fs_handle_t *f, int command, void* data) {
if (!(f->mode & FM_IOCTL)) return -1;
- if (f->node->ops->ioctl == 0) return -1;
+ if (f->ops->ioctl == 0) return -1;
- return f->node->ops->ioctl(f->node->data, command, data);
+ return f->ops->ioctl(f->data, command, data);
}
bool file_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d) {
if (!(f->mode & FM_READDIR)) return 0;
- return f->node->ops->readdir && f->node->ops->readdir(f->node->data, ent_no, d);
+ return f->ops->readdir && f->ops->readdir(f->data, ent_no, d);
}
/* vim: set ts=4 sw=4 tw=0 noet :*/