diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-08 12:16:48 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-08 12:16:48 +0100 |
commit | 5e3d036d3a10d919e54035b1365005f26886ed75 (patch) | |
tree | ca6b2057457603abd4339f918a8879fb4dc4957b | |
parent | 3995fb8aee32783d3386d82a5a6910a86c7bf38c (diff) | |
download | kogata-5e3d036d3a10d919e54035b1365005f26886ed75.tar.gz kogata-5e3d036d3a10d919e54035b1365005f26886ed75.zip |
Change VFS a bit in preparation for IPC code : ...
Handles now have a copy of data and ops, and may reference a null node
in the case of an IPC channel.
-rw-r--r-- | src/kernel/config.h | 2 | ||||
-rw-r--r-- | src/kernel/include/prng.h | 2 | ||||
-rw-r--r-- | src/kernel/include/vfs.h | 9 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 24 |
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 :*/ |