diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-13 15:50:09 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-13 15:50:09 +0100 |
commit | 1df9fff83a0025421e50b2fcecd0f69997178fe0 (patch) | |
tree | c79b4280b796848a4eb076f8a4b59573679eb835 /src/kernel/user/vfs.c | |
parent | be645920ae72ae7d407e8d976506f617a7d40355 (diff) | |
download | kogata-1df9fff83a0025421e50b2fcecd0f69997178fe0.tar.gz kogata-1df9fff83a0025421e50b2fcecd0f69997178fe0.zip |
Complete nullfs : create, delete, trunc, read, write
Diffstat (limited to 'src/kernel/user/vfs.c')
-rw-r--r-- | src/kernel/user/vfs.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index 5ba2064..0624a38 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -95,6 +95,7 @@ void unref_fs_node(fs_node_t *n) { unref_fs_node(n->parent); unref_fs(n->fs); + if (n->children != 0) delete_hashtbl(n->children, 0); free(n->name); free(n); } @@ -304,8 +305,15 @@ int fs_ioctl(fs_t *fs, const char* file, int command, void* data) { fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) { fs_node_t *n = fs_walk_path(&fs->root, file); + if (n == 0 && (mode & FM_CREATE)) { + if (fs_create(fs, file, FT_REGULAR)) { + n = fs_walk_path(&fs->root, file); + } + } if (n == 0) return false; + mode &= ~FM_CREATE; + fs_handle_t *h = (fs_handle_t*)malloc(sizeof(fs_handle_t)); if (h == 0) { unref_fs_node(n); @@ -346,14 +354,14 @@ 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->mode & FM_READ)) return 0; if (f->ops->read == 0) return 0; 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->mode & FM_WRITE)) return 0; if (f->ops->write == 0) return 0; return f->ops->write(f->data, offset, len, buf); @@ -364,6 +372,8 @@ bool file_stat(fs_handle_t *f, stat_t *st) { } bool file_readdir(fs_handle_t *f, dirent_t *d) { + if (!(f->mode & FM_READDIR)) return 0; + return f->ops->readdir && f->ops->readdir(f->data, d); } |