aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/dev/pciide.c4
-rw-r--r--src/kernel/fs/iso9660.c4
-rw-r--r--src/kernel/include/vfs.h8
-rw-r--r--src/kernel/user/ipc.c47
-rw-r--r--src/kernel/user/nullfs.c6
-rw-r--r--src/kernel/user/vfs.c60
6 files changed, 79 insertions, 50 deletions
diff --git a/src/kernel/dev/pciide.c b/src/kernel/dev/pciide.c
index 8fcaf02..f9330f8 100644
--- a/src/kernel/dev/pciide.c
+++ b/src/kernel/dev/pciide.c
@@ -729,7 +729,7 @@ bool ide_vfs_stat(fs_node_ptr n, stat_t *st) {
}
size_t ide_vfs_read(fs_handle_t *h, size_t offset, size_t len, char* buf) {
- ide_vfs_dev_t *d = (ide_vfs_dev_t*)h->data;
+ ide_vfs_dev_t *d = (ide_vfs_dev_t*)h->node->data;
if (offset % d->block_size != 0) return 0;
if (len % d->block_size != 0) return 0;
@@ -741,7 +741,7 @@ size_t ide_vfs_read(fs_handle_t *h, size_t offset, size_t len, char* buf) {
}
size_t ide_vfs_write(fs_handle_t *h, size_t offset, size_t len, const char* buf) {
- ide_vfs_dev_t *d = (ide_vfs_dev_t*)h->data;
+ ide_vfs_dev_t *d = (ide_vfs_dev_t*)h->node->data;
if (offset % d->block_size != 0) return 0;
if (len % d->block_size != 0) return 0;
diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c
index a3db67e..9c9d31a 100644
--- a/src/kernel/fs/iso9660.c
+++ b/src/kernel/fs/iso9660.c
@@ -223,7 +223,7 @@ bool iso9660_file_open(fs_node_ptr n, int mode) {
}
size_t iso9660_file_read(fs_handle_t *h, size_t offset, size_t len, char* buf) {
- iso9660_node_t *node = (iso9660_node_t*)h->data;
+ iso9660_node_t *node = (iso9660_node_t*)h->node->data;
if (offset >= node->dr.size.lsb) return 0;
if (offset + len > node->dr.size.lsb) len = node->dr.size.lsb - offset;
@@ -267,7 +267,7 @@ void iso9660_file_close(fs_node_ptr f) {
bool iso9660_dir_readdir(fs_handle_t *h, size_t ent_no, dirent_t *d) {
// TODO : Very nonefficient !!
- iso9660_node_t *node = (iso9660_node_t*)h->data;
+ iso9660_node_t *node = (iso9660_node_t*)h->node->data;
char buffer[2048];
size_t dr_len = 0;
diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h
index a56ecae..cc6d11c 100644
--- a/src/kernel/include/vfs.h
+++ b/src/kernel/include/vfs.h
@@ -45,17 +45,13 @@ 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.
+// For IPC structures (sockets, channels), fs is null, but a node object is nevertheless
+// created by the IPC code.
typedef struct fs_handle {
struct fs *fs;
struct fs_node *node;
- fs_node_ops_t *ops;
- fs_node_ptr data;
-
int refs;
int mode;
diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c
index dce1847..ff4d5c8 100644
--- a/src/kernel/user/ipc.c
+++ b/src/kernel/user/ipc.c
@@ -12,15 +12,17 @@
static size_t channel_read(fs_handle_t *c, size_t offset, size_t len, char* buf);
static size_t channel_write(fs_handle_t *c, size_t offset, size_t len, const char* buf);
static int channel_poll(fs_handle_t *c, void** out_wait_obj);
+static bool channel_open(fs_node_ptr c, int mode);
static bool channel_stat(fs_node_ptr c, stat_t *st);
static void channel_close(fs_handle_t *c);
+static void channel_dispose(fs_node_ptr c);
static fs_node_ops_t channel_ops = {
.read = channel_read,
.write = channel_write,
.close = channel_close,
.poll = channel_poll,
- .open = 0,
+ .open = channel_open,
.readdir = 0,
.ioctl = 0,
.stat = channel_stat,
@@ -28,7 +30,7 @@ static fs_node_ops_t channel_ops = {
.create = 0,
.move = 0,
.delete = 0,
- .dispose = 0,
+ .dispose = channel_dispose,
};
typedef struct channel {
@@ -41,6 +43,7 @@ typedef struct channel {
} channel_t;
fs_handle_pair_t make_channel(bool blocking) {
+ fs_node_t *na = 0, *nb = 0;
fs_handle_pair_t ret = { .a = 0, .b = 0 };
channel_t *a = 0, *b = 0;
@@ -56,17 +59,28 @@ fs_handle_pair_t make_channel(bool blocking) {
ret.b = (fs_handle_t*)malloc(sizeof(fs_handle_t));
if (ret.b == 0) goto error;
+ na = (fs_node_t*)malloc(sizeof(fs_node_t));
+ if (na == 0) goto error;
+
+ nb = (fs_node_t*)malloc(sizeof(fs_node_t));
+ if (nb == 0) goto error;
+
a->other_side = b;
b->other_side = a;
a->lock = b->lock = MUTEX_UNLOCKED;
a->buf_use_begin = a->buf_used = 0;
b->buf_use_begin = b->buf_used = 0;
+ memset(na, 0, sizeof(fs_node_t));
+ memset(nb, 0, sizeof(fs_node_t));
+ na->refs = nb->refs = 1;
+ na->ops = nb->ops = &channel_ops;
+ na->data = a;
+ nb->data = b;
+
ret.a->fs = ret.b->fs = 0;
- ret.a->node = ret.b->node = 0;
- ret.a->ops = ret.b->ops = &channel_ops;
- ret.a->data = a;
- ret.b->data = b;
+ ret.a->node = na;
+ ret.b->node = nb;
ret.a->refs = ret.b->refs = 1;
ret.a->mode = ret.b->mode = FM_READ | FM_WRITE | (blocking ? FM_BLOCKING : 0);
@@ -77,12 +91,14 @@ error:
if (b) free(b);
if (ret.a) free(ret.a);
if (ret.b) free(ret.b);
+ if (na) free(na);
+ if (nb) free(nb);
ret.a = ret.b = 0;
return ret;
}
size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_buf) {
- channel_t *c = (channel_t*)h->data;
+ channel_t *c = (channel_t*)h->node->data;
size_t ret = 0;
@@ -119,7 +135,7 @@ size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_bu
}
size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char* orig_buf) {
- channel_t *tc = (channel_t*)h->data;
+ channel_t *tc = (channel_t*)h->node->data;
channel_t *c = tc->other_side;
if (c == 0) return 0;
@@ -160,7 +176,7 @@ size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char*
}
int channel_poll(fs_handle_t *h, void** out_wait_obj) {
- channel_t *c = (channel_t*)h->data;
+ channel_t *c = (channel_t*)h->node->data;
int ret = 0;
@@ -173,6 +189,13 @@ int channel_poll(fs_handle_t *h, void** out_wait_obj) {
return ret;
}
+bool channel_open(fs_node_ptr ch, int mode) {
+ int ok_modes = FM_READ | FM_WRITE | FM_BLOCKING;
+
+ if (mode & ~ok_modes) return false;
+ return true;
+}
+
bool channel_stat(fs_node_ptr ch, stat_t *st) {
channel_t *c = (channel_t*)ch;
@@ -188,7 +211,11 @@ bool channel_stat(fs_node_ptr ch, stat_t *st) {
}
void channel_close(fs_handle_t *ch) {
- channel_t *c = (channel_t*)ch->data;
+ // do nothing
+}
+
+void channel_dispose(fs_node_ptr ch) {
+ channel_t *c = (channel_t*)ch;
mutex_lock(&c->lock);
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index 0dc1b22..1f40d88 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -415,7 +415,7 @@ void nullfs_d_dispose(fs_node_ptr n) {
bool nullfs_d_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d) {
// Very nonefficient !!
- nullfs_dir_t *h = (nullfs_dir_t*)f->data;
+ nullfs_dir_t *h = (nullfs_dir_t*)f->node->data;
mutex_lock(&h->lock);
@@ -489,7 +489,7 @@ void nullfs_f_dispose(fs_node_ptr n) {
// -- File handle --
static size_t nullfs_f_read(fs_handle_t *h, size_t offset, size_t len, char* buf) {
- nullfs_file_t *f = (nullfs_file_t*)h->data;
+ nullfs_file_t *f = (nullfs_file_t*)h->node->data;
mutex_lock(&f->lock);
size_t ret = 0;
@@ -506,7 +506,7 @@ end_read:
}
static size_t nullfs_f_write(fs_handle_t *h, size_t offset, size_t len, const char* buf) {
- nullfs_file_t *f = (nullfs_file_t*)h->data;
+ nullfs_file_t *f = (nullfs_file_t*)h->node->data;
mutex_lock(&f->lock);
size_t ret = 0;
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index 05b4a2c..1fa1cc2 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -121,24 +121,32 @@ void unref_fs_node(fs_node_t *n) {
mutex_lock(&n->lock);
n->refs--;
if (n->refs == 0) {
- ASSERT (n != n->fs->root);
+ // delete object!
+ if (n->fs) {
+ ASSERT (n != n->fs->root);
- ASSERT(n->parent != 0);
- ASSERT(n->name != 0);
+ ASSERT(n->parent != 0);
+ ASSERT(n->name != 0);
- mutex_lock(&n->parent->lock);
- hashtbl_remove(n->parent->children, n->name);
- if (n->ops->dispose) n->ops->dispose(n->data);
- mutex_unlock(&n->parent->lock);
+ mutex_lock(&n->parent->lock);
+ hashtbl_remove(n->parent->children, n->name);
+ if (n->ops->dispose) n->ops->dispose(n->data);
+ mutex_unlock(&n->parent->lock);
- unref_fs_node(n->parent);
- unref_fs(n->fs);
+ unref_fs_node(n->parent);
+ unref_fs(n->fs);
- if (n->children != 0) {
- ASSERT(hashtbl_count(n->children) == 0);
- delete_hashtbl(n->children);
+ if (n->children != 0) {
+ ASSERT(hashtbl_count(n->children) == 0);
+ delete_hashtbl(n->children);
+ }
+ } else {
+ // stand-alone IPC/SHM object
+ ASSERT(n->parent == 0 && n->children == 0);
+
+ if (n->ops->dispose) n->ops->dispose(n->data);
}
- free(n->name);
+ if (n->name) free(n->name);
free(n);
} else {
mutex_unlock(&n->lock);
@@ -427,8 +435,6 @@ 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);
@@ -449,8 +455,8 @@ void ref_file(fs_handle_t *file) {
void unref_file(fs_handle_t *file) {
file->refs--;
if (file->refs == 0) {
- file->ops->close(file);
- if (file->node) unref_fs_node(file->node);
+ if (file->node->ops->close) file->node->ops->close(file);
+ unref_fs_node(file->node);
if (file->fs) unref_fs(file->fs);
free(file);
}
@@ -463,44 +469,44 @@ 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->ops->read == 0) return 0;
+ if (f->node->ops->read == 0) return 0;
- return f->ops->read(f, offset, len, buf);
+ return f->node->ops->read(f, 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->ops->write == 0) return 0;
+ if (f->node->ops->write == 0) return 0;
- return f->ops->write(f, offset, len, buf);
+ return f->node->ops->write(f, offset, len, buf);
}
bool file_stat(fs_handle_t *f, stat_t *st) {
- return f->ops->stat && f->ops->stat(f->data, st);
+ return f->node->ops->stat && f->node->ops->stat(f->node->data, st);
}
int file_ioctl(fs_handle_t *f, int command, void* data) {
if (!(f->mode & FM_IOCTL)) return -1;
- if (f->ops->ioctl == 0) return -1;
+ if (f->node->ops->ioctl == 0) return -1;
- return f->ops->ioctl(f->data, command, data);
+ return f->node->ops->ioctl(f->node->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->ops->readdir && f->ops->readdir(f, ent_no, d);
+ return f->node->ops->readdir && f->node->ops->readdir(f, ent_no, d);
}
int file_poll(fs_handle_t *f, void** out_wait_obj) {
- if (!f->ops->poll) {
+ if (!f->node->ops->poll) {
if (out_wait_obj) *out_wait_obj = 0;
return 0;
}
- return f->ops->poll(f, out_wait_obj);
+ return f->node->ops->poll(f, out_wait_obj);
}
/* vim: set ts=4 sw=4 tw=0 noet :*/