From 845fff4dad1159d3d5b94efaf8e547af8d280a5e Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sun, 8 Mar 2015 13:57:35 +0100 Subject: Change prototypes for read, write, readdir, close ; implement blocking IPC. --- src/kernel/dev/pciide.c | 16 +++---- src/kernel/fs/iso9660.c | 18 ++++---- src/kernel/include/ipc.h | 2 +- src/kernel/include/vfs.h | 8 ++-- src/kernel/user/ipc.c | 107 +++++++++++++++++++++++++++-------------------- src/kernel/user/nullfs.c | 26 ++++++------ src/kernel/user/vfs.c | 8 ++-- 7 files changed, 101 insertions(+), 84 deletions(-) diff --git a/src/kernel/dev/pciide.c b/src/kernel/dev/pciide.c index c357190..56d4e4f 100644 --- a/src/kernel/dev/pciide.c +++ b/src/kernel/dev/pciide.c @@ -659,10 +659,10 @@ typedef struct { static bool ide_vfs_open(fs_node_ptr n, int mode); static bool ide_vfs_stat(fs_node_ptr n, stat_t *st); -static size_t ide_vfs_read(fs_node_ptr f, size_t offset, size_t len, char* buf); -static size_t ide_vfs_write(fs_node_ptr f, size_t offset, size_t len, const char* buf); +static size_t ide_vfs_read(fs_handle_t *f, size_t offset, size_t len, char* buf); +static size_t ide_vfs_write(fs_handle_t *f, size_t offset, size_t len, const char* buf); static int ide_vfs_ioctl(fs_node_ptr f, int command, void* data); -static void ide_vfs_close(fs_node_ptr f); +static void ide_vfs_close(fs_handle_t *f); static fs_node_ops_t ide_vfs_node_ops = { .open = ide_vfs_open, @@ -727,8 +727,8 @@ bool ide_vfs_stat(fs_node_ptr n, stat_t *st) { return true; } -size_t ide_vfs_read(fs_node_ptr f, size_t offset, size_t len, char* buf) { - ide_vfs_dev_t *d = (ide_vfs_dev_t*)f; +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; if (offset % d->block_size != 0) return 0; if (len % d->block_size != 0) return 0; @@ -739,8 +739,8 @@ size_t ide_vfs_read(fs_node_ptr f, size_t offset, size_t len, char* buf) { return len; } -size_t ide_vfs_write(fs_node_ptr f, size_t offset, size_t len, const char* buf) { - ide_vfs_dev_t *d = (ide_vfs_dev_t*)f; +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; if (offset % d->block_size != 0) return 0; if (len % d->block_size != 0) return 0; @@ -764,7 +764,7 @@ int ide_vfs_ioctl(fs_node_ptr f, int command, void* data) { return ret; } -void ide_vfs_close(fs_node_ptr f) { +void ide_vfs_close(fs_handle_t *h) { // nothing to do } diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c index 192f8ae..89bfdf8 100644 --- a/src/kernel/fs/iso9660.c +++ b/src/kernel/fs/iso9660.c @@ -8,14 +8,14 @@ static void iso9660_fs_shutdown(fs_ptr f); static bool iso9660_node_stat(fs_node_ptr n, stat_t *st); static void iso9660_node_dispose(fs_node_ptr n); -static void iso9660_node_close(fs_node_ptr f); +static void iso9660_node_close(fs_handle_t *h); static bool iso9660_dir_open(fs_node_ptr n, int mode); static bool iso9660_dir_walk(fs_node_ptr n, const char* file, struct fs_node *node_d); -static bool iso9660_dir_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d); +static bool iso9660_dir_readdir(fs_handle_t *h, size_t ent_no, dirent_t *d); static bool iso9660_file_open(fs_node_ptr n, int mode); -static size_t iso9660_file_read(fs_node_ptr f, size_t offset, size_t len, char* buf); +static size_t iso9660_file_read(fs_handle_t *h, size_t offset, size_t len, char* buf); static fs_driver_ops_t iso9660_driver_ops = { .make = iso9660_make, @@ -156,7 +156,7 @@ void iso9660_node_dispose(fs_node_ptr n) { free(node); } -void iso9660_node_close(fs_node_ptr f) { +void iso9660_node_close(fs_handle_t *h) { // nothing to do } @@ -220,8 +220,8 @@ bool iso9660_file_open(fs_node_ptr n, int mode) { return true; } -size_t iso9660_file_read(fs_node_ptr f, size_t offset, size_t len, char* buf) { - iso9660_node_t *node = (iso9660_node_t*)f; +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; if (offset >= node->dr.size.lsb) return 0; if (offset + len > node->dr.size.lsb) len = node->dr.size.lsb - offset; @@ -262,10 +262,10 @@ void iso9660_file_close(fs_node_ptr f) { // nothing to do } -bool iso9660_dir_readdir(fs_node_ptr n, size_t ent_no, dirent_t *d) { - // Very nonefficient !! +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*)n; + iso9660_node_t *node = (iso9660_node_t*)h->data; char buffer[2048]; size_t dr_len = 0; diff --git a/src/kernel/include/ipc.h b/src/kernel/include/ipc.h index 5558120..c61ec93 100644 --- a/src/kernel/include/ipc.h +++ b/src/kernel/include/ipc.h @@ -11,7 +11,7 @@ typedef struct { fs_handle_t *a, *b; } fs_handle_pair_t; -fs_handle_pair_t make_channel(); +fs_handle_pair_t make_channel(bool blocking); // ---- Tokens for sharing file descriptors between processes diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index 90944b2..371ffb7 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -83,10 +83,10 @@ typedef struct fs_handle { 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); - bool (*readdir)(fs_node_ptr f, size_t ent_no, dirent_t *d); - void (*close)(fs_node_ptr f); + size_t (*read)(fs_handle_t *f, size_t offset, size_t len, char* buf); + size_t (*write)(fs_handle_t *f, size_t offset, size_t len, const char* buf); + bool (*readdir)(fs_handle_t *f, size_t ent_no, dirent_t *d); + void (*close)(fs_handle_t *f); bool (*stat)(fs_node_ptr n, stat_t *st); int (*ioctl)(fs_node_ptr f, int command, void* data); diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c index b23af56..a518304 100644 --- a/src/kernel/user/ipc.c +++ b/src/kernel/user/ipc.c @@ -4,10 +4,10 @@ #include #include -static size_t channel_read(fs_node_ptr c, size_t offset, size_t len, char* buf); -static size_t channel_write(fs_node_ptr c, size_t offset, size_t len, const char* buf); +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 bool channel_stat(fs_node_ptr c, stat_t *st); -static void channel_close(fs_node_ptr c); +static void channel_close(fs_handle_t *c); static fs_node_ops_t channel_ops = { .read = channel_read, @@ -33,7 +33,7 @@ typedef struct channel { size_t buf_use_begin, buf_used; // circular buffer } channel_t; -fs_handle_pair_t make_channel() { +fs_handle_pair_t make_channel(bool blocking) { fs_handle_pair_t ret = { .a = 0, .b = 0 }; channel_t *a = 0, *b = 0; @@ -61,7 +61,7 @@ fs_handle_pair_t make_channel() { ret.a->data = a; ret.b->data = b; ret.a->refs = ret.b->refs = 1; - ret.a->mode = ret.b->mode = FM_READ | FM_WRITE; + ret.a->mode = ret.b->mode = FM_READ | FM_WRITE | (blocking ? FM_BLOCKING : 0); return ret; @@ -74,65 +74,82 @@ error: return ret; } -size_t channel_read(fs_node_ptr ch, size_t offset, size_t len, char* buf) { - channel_t *c = (channel_t*)ch; +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; + + size_t ret = 0; - mutex_lock(&c->lock); + do { + size_t len = req_len - ret; + char *buf = orig_buf + ret; + + mutex_lock(&c->lock); - if (c->buf_used < len) len = c->buf_used; + if (c->buf_used < len) len = c->buf_used; - if (len) { - size_t len0 = len, len1 = 0; + if (len) { + size_t len0 = len, len1 = 0; - if (c->buf_use_begin + len > CHANNEL_BUFFER_SIZE) { - len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin; - len1 = len - len0; + if (c->buf_use_begin + len > CHANNEL_BUFFER_SIZE) { + len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin; + len1 = len - len0; + } + memcpy(buf, c->buf + c->buf_use_begin, len0); + if (len1) memcpy(buf + len0, c->buf, len1); + + c->buf_use_begin = (c->buf_use_begin + len) % CHANNEL_BUFFER_SIZE; + c->buf_used -= len; + + if (c->buf_used == 0) c->buf_use_begin = 0; } - memcpy(buf, c->buf + c->buf_use_begin, len0); - if (len1) memcpy(buf + len0, c->buf, len1); - c->buf_use_begin = (c->buf_use_begin + len) % CHANNEL_BUFFER_SIZE; - c->buf_used -= len; - - if (c->buf_used == 0) c->buf_use_begin = 0; - } + ret += len; - mutex_unlock(&c->lock); + mutex_unlock(&c->lock); + } while ((h->mode & FM_BLOCKING) && ret < req_len); - return len; + return ret; } -size_t channel_write(fs_node_ptr ch, size_t offset, size_t len, const char* buf) { - channel_t *tc = (channel_t*)ch; +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 *c = tc->other_side; if (c == 0) return 0; - while (!mutex_try_lock(&c->lock)) { - yield(); - if (tc->other_side == 0) return 0; - } - - if (c->buf_used + len > CHANNEL_BUFFER_SIZE) len = CHANNEL_BUFFER_SIZE - c->buf_used; + size_t ret = 0; - if (len) { - size_t len0 = len, len1 = 0; + do { + size_t len = req_len - ret; + const char* buf = orig_buf + ret; - if (c->buf_use_begin + c->buf_used + len > CHANNEL_BUFFER_SIZE) { - len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin - c->buf_used; - len1 = len - len0; + while (!mutex_try_lock(&c->lock)) { + yield(); + if (tc->other_side == 0) break; } - memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0); - if (len1) memcpy(c->buf, buf + len0, len1); - c->buf_used += len; - } + if (c->buf_used + len > CHANNEL_BUFFER_SIZE) len = CHANNEL_BUFFER_SIZE - c->buf_used; - mutex_unlock(&c->lock); + if (len) { + size_t len0 = len, len1 = 0; + + if (c->buf_use_begin + c->buf_used + len > CHANNEL_BUFFER_SIZE) { + len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin - c->buf_used; + len1 = len - len0; + } + memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0); + if (len1) memcpy(c->buf, buf + len0, len1); + + c->buf_used += len; + } - if (len) resume_on(c); // notify processes that may be waiting for data + mutex_unlock(&c->lock); - return len; + if (len) resume_on(c); // notify processes that may be waiting for data + ret += len; + } while ((h->mode & FM_BLOCKING) && ret < req_len); + + return ret; } bool channel_stat(fs_node_ptr ch, stat_t *st) { @@ -149,8 +166,8 @@ bool channel_stat(fs_node_ptr ch, stat_t *st) { return true; } -void channel_close(fs_node_ptr ch) { - channel_t *c = (channel_t*)ch; +void channel_close(fs_handle_t *ch) { + channel_t *c = (channel_t*)ch->data; mutex_lock(&c->lock); diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index 77bc3e8..60872ab 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -19,16 +19,16 @@ static bool nullfs_d_delete(fs_node_ptr n, const char* file); static bool nullfs_d_move(fs_node_ptr n, const char* old_name, fs_node_t *new_parent, const char *new_name); static bool nullfs_d_create(fs_node_ptr n, const char* file, int type); static void nullfs_d_dispose(fs_node_ptr n); -static bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d); -static void nullfs_d_close(fs_node_ptr f); +static bool nullfs_d_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d); +static void nullfs_d_close(fs_handle_t *f); // nullfs ram file node static bool nullfs_f_open(fs_node_ptr n, int mode); static bool nullfs_f_stat(fs_node_ptr n, stat_t *st); static void nullfs_f_dispose(fs_node_ptr n); -static size_t nullfs_f_read(fs_node_ptr f, size_t offset, size_t len, char* buf); -static size_t nullfs_f_write(fs_node_ptr f, size_t offset, size_t len, const char* buf); -static void nullfs_f_close(fs_node_ptr f); +static size_t nullfs_f_read(fs_handle_t *f, size_t offset, size_t len, char* buf); +static size_t nullfs_f_write(fs_handle_t *f, size_t offset, size_t len, const char* buf); +static void nullfs_f_close(fs_handle_t *f); // VTables that go with it static fs_driver_ops_t nullfs_driver_ops = { @@ -410,10 +410,10 @@ void nullfs_d_dispose(fs_node_ptr n) { // nothing to do } -bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d) { +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; + nullfs_dir_t *h = (nullfs_dir_t*)f->data; mutex_lock(&h->lock); @@ -442,7 +442,7 @@ bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d) { return ok; } -void nullfs_d_close(fs_node_ptr f) { +void nullfs_d_close(fs_handle_t *f) { // Nothing to do } @@ -486,8 +486,8 @@ void nullfs_f_dispose(fs_node_ptr n) { // -- File handle -- -static size_t nullfs_f_read(fs_node_ptr h, size_t offset, size_t len, char* buf) { - nullfs_file_t *f = (nullfs_file_t*)h; +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; mutex_lock(&f->lock); size_t ret = 0; @@ -503,8 +503,8 @@ end_read: return ret; } -static size_t nullfs_f_write(fs_node_ptr h, size_t offset, size_t len, const char* buf) { - nullfs_file_t *f = (nullfs_file_t*)h; +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; mutex_lock(&f->lock); size_t ret = 0; @@ -532,7 +532,7 @@ end_write: return ret; } -static void nullfs_f_close(fs_node_ptr h) { +static void nullfs_f_close(fs_handle_t *h) { // nothing to do } diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index 2af8cf0..4e8cf53 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -449,7 +449,7 @@ void ref_file(fs_handle_t *file) { void unref_file(fs_handle_t *file) { file->refs--; if (file->refs == 0) { - file->ops->close(file->data); + file->ops->close(file); if (file->node) unref_fs_node(file->node); if (file->fs) unref_fs(file->fs); free(file); @@ -465,7 +465,7 @@ size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) { if (f->ops->read == 0) return 0; - return f->ops->read(f->data, offset, len, buf); + return f->ops->read(f, offset, len, buf); } size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) { @@ -473,7 +473,7 @@ size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) { if (f->ops->write == 0) return 0; - return f->ops->write(f->data, offset, len, buf); + return f->ops->write(f, offset, len, buf); } bool file_stat(fs_handle_t *f, stat_t *st) { @@ -491,7 +491,7 @@ int file_ioctl(fs_handle_t *f, int command, void* 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->data, ent_no, d); + return f->ops->readdir && f->ops->readdir(f, ent_no, d); } /* vim: set ts=4 sw=4 tw=0 noet :*/ -- cgit v1.2.3