diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-09 11:49:30 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-09 11:49:30 +0100 |
commit | 8c1f280c1bc948a20e244b32d824780b08bf85c9 (patch) | |
tree | 6288a0c801c05a2c06378d75a912f06b86438c3d | |
parent | 6dd488b87fdc47fb377ba648a6cd598bdab87f59 (diff) | |
download | kogata-8c1f280c1bc948a20e244b32d824780b08bf85c9.tar.gz kogata-8c1f280c1bc948a20e244b32d824780b08bf85c9.zip |
Require all fs_handle_t objects to point to a node.
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | src/kernel/dev/pciide.c | 4 | ||||
-rw-r--r-- | src/kernel/fs/iso9660.c | 4 | ||||
-rw-r--r-- | src/kernel/include/vfs.h | 8 | ||||
-rw-r--r-- | src/kernel/user/ipc.c | 47 | ||||
-rw-r--r-- | src/kernel/user/nullfs.c | 6 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 60 | ||||
-rw-r--r-- | src/rules.make | 1 |
8 files changed, 80 insertions, 51 deletions
@@ -110,7 +110,6 @@ running the tests): ### Plans for soon -* `select` system call * Write device drivers : VESA, keyboard, FAT (or EXT2 ?) * Work on userland : init, terminal emulator, shell * GUI server with help from kernel for framebuffer management 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 :*/ diff --git a/src/rules.make b/src/rules.make index 5de3f1d..b8a3287 100644 --- a/src/rules.make +++ b/src/rules.make @@ -30,3 +30,4 @@ mrproper: clean rm $(OUT) || true rebuild: mrproper all + |