diff --git a/tasks/fs0/include/fs.h b/tasks/fs0/include/fs.h index 0081912..e256b7d 100644 --- a/tasks/fs0/include/fs.h +++ b/tasks/fs0/include/fs.h @@ -53,7 +53,8 @@ struct vnode_ops { vnode_op_t link; vnode_op_t unlink; int (*mkdir)(struct vnode *parent, const char *name); - int (*mknod)(struct vnode *parent, const char *name, unsigned int mode); + struct vnode *(*mknod)(struct vnode *parent, const char *name, + unsigned int mode); vnode_op_t rmdir; vnode_op_t rename; vnode_op_t getattr; diff --git a/tasks/fs0/src/memfs/vnode.c b/tasks/fs0/src/memfs/vnode.c index c1d1ef8..1eef0b4 100644 --- a/tasks/fs0/src/memfs/vnode.c +++ b/tasks/fs0/src/memfs/vnode.c @@ -208,9 +208,10 @@ int memfs_write_vnode(struct superblock *sb, struct vnode *v) /* * Creates ordinary files and directories at the moment. In the future, - * other file types will be added. + * other file types will be added. Returns the created node. */ -int memfs_vnode_mknod(struct vnode *v, const char *dirname, unsigned int mode) +struct vnode *memfs_vnode_mknod(struct vnode *v, const char *dirname, + unsigned int mode) { struct dentry *d, *parent = list_entry(v->dentries.next, struct dentry, vref); @@ -230,25 +231,25 @@ int memfs_vnode_mknod(struct vnode *v, const char *dirname, unsigned int mode) /* Populate the children */ if ((err = v->ops.readdir(v)) < 0) - return err; + return PTR_ERR(err); /* Check there's no existing child with same name */ list_for_each_entry(d, &parent->children, child) { /* Does the name exist as a child? */ if(d->ops.compare(d, dirname)) - return -EEXIST; + return PTR_ERR(-EEXIST); } /* Allocate a new vnode for the new directory */ if (IS_ERR(newv = v->sb->ops->alloc_vnode(v->sb))) - return (int)newv; + return newv; /* Initialise the vnode */ vfs_set_type(newv, S_IFDIR); /* Get the next directory entry available on the parent vnode */ if (v->dirbuf.npages * PAGE_SIZE <= v->size) - return -ENOSPC; + return PTR_ERR(-ENOSPC); /* Fill in the new entry to parent directory entry */ memfsd = (struct memfs_dentry *)&v->dirbuf.buffer[v->size]; @@ -267,7 +268,7 @@ int memfs_vnode_mknod(struct vnode *v, const char *dirname, unsigned int mode) /* Allocate a new vfs dentry */ if (!(newd = vfs_alloc_dentry())) - return -ENOMEM; + return PTR_ERR(-ENOMEM); /* Initialise it */ newd->ops = generic_dentry_operations; @@ -285,7 +286,7 @@ int memfs_vnode_mknod(struct vnode *v, const char *dirname, unsigned int mode) list_add(&newd->cache_list, &dentry_cache); list_add(&newv->cache_list, &vnode_cache); - return 0; + return newv; } /* diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index e6e50b1..c829720 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -58,35 +58,41 @@ void print_vnode(struct vnode *v) } /* Creates a node under a directory, e.g. a file, directory. */ -int vfs_create(struct tcb *task, struct pathdata *pdata, unsigned int mode) +struct vnode *vfs_create(struct tcb *task, struct pathdata *pdata, + unsigned int mode) { - struct vnode *vparent; + struct vnode *vparent, *newnode; const char *nodename; - int err; /* The last component is to be created */ nodename = pathdata_last_component(pdata); /* Check that the parent directory exists. */ if (IS_ERR(vparent = vfs_lookup_bypath(pdata))) - return (int)vparent; + return vparent; /* The parent vnode must be a directory. */ if (!vfs_isdir(vparent)) - return -ENOENT; + return PTR_ERR(-ENOENT); /* Create new directory under the parent */ - if ((err = vparent->ops.mknod(vparent, nodename, mode)) < 0) - return err; + if (IS_ERR(newnode = vparent->ops.mknod(vparent, nodename, mode))) + return newnode; // print_vnode(vparent); - return 0; + return newnode; } /* FIXME: * - Is it already open? * - Allocate a copy of path string since lookup destroys it * - Check flags and mode. + * + * TODO: + * - All return paths should return by destroying pdata. + * - Need another pdata for vfs_create since first lookup destroys it. + * - Or perhaps we check O_CREAT first, and do lookup once, without the + * last path component which is to be created. */ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) { @@ -94,7 +100,7 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) struct vnode *v; struct tcb *task; int fd; - int err; + int retval; /* Get the task */ BUG_ON(!(task = find_task(sender))); @@ -107,16 +113,17 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) return 0; } - /* Get the vnode */ - if (IS_ERR(v = vfs_lookup_bypath(pdata))) { - if (!(flags & O_CREAT)) { - l4_ipc_return((int)v); - return 0; - } else { - if ((err = vfs_create(task, pdata, mode)) < 0) { - l4_ipc_return(err); - return 0; - } + /* Creating new node, file or directory */ + if (flags & O_CREAT) { + if (IS_ERR(v = vfs_create(task, pdata, mode))) { + retval = (int)v; + goto out; + } + } else { + /* Not creating, just opening, get the vnode */ + if (IS_ERR(v = vfs_lookup_bypath(pdata))) { + retval = (int)v; + goto out; } } @@ -129,8 +136,9 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) /* Tell the pager about opened vnode information */ BUG_ON(pager_sys_open(sender, fd, v->vnum, v->size) < 0); +out: pathdata_destroy(pdata); - l4_ipc_return(fd); + l4_ipc_return(retval); return 0; } @@ -160,6 +168,7 @@ int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode) { struct tcb *task; struct pathdata *pdata; + struct vnode *v; /* Get the task */ BUG_ON(!(task = find_task(sender))); @@ -173,7 +182,10 @@ int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode) } /* Create the directory or fail */ - l4_ipc_return(vfs_create(task, pdata, mode)); + if (IS_ERR(v = vfs_create(task, pdata, mode))) + l4_ipc_return((int)v); + else + l4_ipc_return(0); /* Destroy extracted path data */ pathdata_destroy(pdata); diff --git a/tasks/mm0/src/file.c b/tasks/mm0/src/file.c index ed29d49..61a86da 100644 --- a/tasks/mm0/src/file.c +++ b/tasks/mm0/src/file.c @@ -268,6 +268,7 @@ int sys_read(l4id_t sender, int fd, void *buf, int count) int sys_write(l4id_t sender, int fd, void *buf, int count) { + BUG(); return 0; } diff --git a/tasks/test0/src/fileio.c b/tasks/test0/src/fileio.c index 7054cd3..c5453b6 100644 --- a/tasks/test0/src/fileio.c +++ b/tasks/test0/src/fileio.c @@ -12,22 +12,51 @@ int fileio(void) int fd; ssize_t cnt; int err; + char buf[128]; + off_t offset; char *str = "I WROTE TO THIS FILE\n"; if ((fd = open("/home/bahadir/newfile.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) { perror("OPEN"); - return 0; + return -1; } if ((int)(cnt = write(fd, str, strlen(str))) < 0) { perror("WRITE"); - return 0; + return -1; } - if ((err = close(fd)) < 0) + if ((int)(offset = lseek(fd, 0, SEEK_SET)) < 0) { + perror("LSEEK"); + return -1; + } + if ((int)(cnt = read(fd, buf, strlen(str))) < 0) { + perror("WRITE"); + return -1; + } + + printf("Read: %d bytes from file.\n", cnt); + if (cnt) { + printf("Read string: %s\n", buf); + } + + if ((err = close(fd)) < 0) { perror("CLOSE"); + return -1; + } return 0; } +#if defined(HOST_TESTS) +int main(void) +{ + printf("File IO test:\n"); + if (fileio() == 0) + printf("-- PASSED --\n"); + + return 0; +} +#endif +