diff --git a/tasks/fs0/include/fs.h b/tasks/fs0/include/fs.h index 1b0829b..2c22004 100644 --- a/tasks/fs0/include/fs.h +++ b/tasks/fs0/include/fs.h @@ -51,6 +51,7 @@ struct vnode_ops { vnode_op_t link; vnode_op_t unlink; int (*mkdir)(struct vnode *parent, char *name); + int (*mknod)(struct vnode *parent, char *name, unsigned int mode); vnode_op_t rmdir; vnode_op_t rename; vnode_op_t getattr; diff --git a/tasks/fs0/include/stat.h b/tasks/fs0/include/stat.h index c77f0b3..b930791 100644 --- a/tasks/fs0/include/stat.h +++ b/tasks/fs0/include/stat.h @@ -43,4 +43,23 @@ #define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) #define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) +#define O_ACCMODE 00000003 +#define O_RDONLY 00000000 +#define O_WRONLY 00000001 +#define O_RDWR 00000002 +#define O_CREAT 00000100 +#define O_EXCL 00000200 +#define O_NOCTTY 00000400 +#define O_TRUNC 00001000 +#define O_APPEND 00002000 +#define O_NONBLOCK 00004000 +#define O_SYNC 00010000 +#define FASYNC 00020000 +#define O_DIRECT 00040000 +#define O_LARGEFILE 00100000 +#define O_DIRECTORY 00200000 +#define O_NOFOLLOW 00400000 +#define O_NOATIME 01000000 +#define O_NDELAY O_NONBLOCK + #endif /* __FS0_STAT_H__ */ diff --git a/tasks/fs0/src/memfs/vnode.c b/tasks/fs0/src/memfs/vnode.c index c50d7eb..df548ec 100644 --- a/tasks/fs0/src/memfs/vnode.c +++ b/tasks/fs0/src/memfs/vnode.c @@ -204,7 +204,11 @@ int memfs_write_vnode(struct superblock *sb, struct vnode *v) return 0; } -int memfs_vnode_mkdir(struct vnode *v, char *dirname) +/* + * Creates ordinary files and directories at the moment. In the future, + * other file types will be added. + */ +int memfs_vnode_mknod(struct vnode *v, char *dirname, unsigned int mode) { struct dentry *d, *parent = list_entry(v->dentries.next, struct dentry, vref); @@ -368,7 +372,7 @@ int memfs_vnode_readdir(struct vnode *v) struct vnode_ops memfs_vnode_operations = { .readdir = memfs_vnode_readdir, - .mkdir = memfs_vnode_mkdir, + .mknod = memfs_vnode_mknod, }; struct superblock_ops memfs_superblock_operations = { diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index 3f359e3..1e3c380 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include /* * This notifies mm0 that this is the fd that refers to this vnode number @@ -23,7 +25,7 @@ * for handling syscalls that access file content (i.e. read/write) since * it maintains the page cache. */ -int send_pager_opendata(l4id_t sender, int fd, unsigned long vnum) +int send_pager_sys_open(l4id_t sender, int fd, unsigned long vnum) { int err; @@ -31,7 +33,7 @@ int send_pager_opendata(l4id_t sender, int fd, unsigned long vnum) write_mr(L4SYS_ARG1, fd); write_mr(L4SYS_ARG2, vnum); - if ((err = l4_send(PAGER_TID, L4_IPC_TAG_OPENDATA)) < 0) { + if ((err = l4_send(PAGER_TID, L4_IPC_TAG_PAGER_SYSOPEN)) < 0) { printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); return err; } @@ -39,6 +41,35 @@ int send_pager_opendata(l4id_t sender, int fd, unsigned long vnum) return 0; } +/* Creates a node under a directory, e.g. a file, directory. */ +int vfs_create(const char *pathname, unsigned int mode) +{ + char *pathbuf = alloca(strlen(pathname) + 1); + char *parentpath = pathbuf; + struct vnode *vparent; + char *nodename; + int err; + + strcpy(pathbuf, pathname); + + /* The last component is to be created */ + nodename = splitpath_end(&parentpath, '/'); + + /* Check that the parent directory exists. */ + if (IS_ERR(vparent = vfs_lookup_bypath(vfs_root.pivot->sb, parentpath))) + return (int)vparent; + + /* The parent vnode must be a directory. */ + if (!vfs_isdir(vparent)) + return -ENOENT; + + /* Create new directory under the parent */ + if ((err = vparent->ops.mknod(vparent, nodename, mode)) < 0) + return err; + + return 0; +} + /* FIXME: * - Is it already open? * - Allocate a copy of path string since lookup destroys it @@ -46,17 +77,23 @@ int send_pager_opendata(l4id_t sender, int fd, unsigned long vnum) */ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) { + char *pathbuf = alloca(strlen(pathname) + 1); struct vnode *v; struct tcb *t; int fd; - char *copypath = kmalloc(strlen(pathname) + 1); + int err; - strcpy(copypath, pathname); + strcpy(pathbuf, pathname); /* Get the vnode */ - if (IS_ERR(v = vfs_lookup_bypath(vfs_root.pivot->sb, copypath))) - return (int)v; - + if (IS_ERR(v = vfs_lookup_bypath(vfs_root.pivot->sb, pathbuf))) { + if (!flags & O_CREAT) { + return (int)v; + } else { + if ((err = vfs_create(pathname, mode)) < 0) + return err; + } + } /* Get the task */ BUG_ON(!(t = find_task(sender))); @@ -66,39 +103,15 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode) /* Assign the new fd with the vnode's number */ t->fd[fd] = v->vnum; - /* Tell mm0 about opened vnode information */ - BUG_ON(send_pager_opendata(sender, fd, v->vnum) < 0); + /* Tell the pager about opened vnode information */ + BUG_ON(send_pager_sys_open(sender, fd, v->vnum) < 0); - kfree(copypath); return 0; } int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode) { - char *parentpath, *pathbuf = kmalloc(strlen(pathname) + 1); - struct vnode *vparent; - char *newdir_name; - int err; - - strcpy(pathbuf, pathname); - parentpath = pathbuf; - - /* The last component is to be created */ - newdir_name = splitpath_end(&parentpath, '/'); - - /* Check that the parentdir exists. */ - if (IS_ERR(vparent = vfs_lookup_bypath(vfs_root.pivot->sb, parentpath))) - return (int)vparent; - - /* The parent vnode must be a directory. */ - if (!vfs_isdir(vparent)) - return -ENOENT; - - /* Create new directory under the parent */ - if ((err = vparent->ops.mkdir(vparent, newdir_name)) < 0) - return err; - kfree(pathbuf); - return 0; + return vfs_create(pathname, mode); } int sys_read(l4id_t sender, int fd, void *buf, int count) diff --git a/tasks/libl4/include/l4lib/ipcdefs.h b/tasks/libl4/include/l4lib/ipcdefs.h index 74e16e8..6e91472 100644 --- a/tasks/libl4/include/l4lib/ipcdefs.h +++ b/tasks/libl4/include/l4lib/ipcdefs.h @@ -42,7 +42,7 @@ #define L4_IPC_TAG_READDIR 18 /* Tags for ipc between fs0 and mm0 */ -#define L4_IPC_TAG_OPENDATA 25 +#define L4_IPC_TAG_PAGER_SYSOPEN 25 #define L4_IPC_TAG_TASKDATA 26 #endif /* __IPCDEFS_H__ */