mirror of
https://github.com/drasko/codezero.git
synced 2026-02-28 01:33:13 +01:00
Added vfs_create() to create files and directories.
Moved mkdir to mknod so that mknod is the common handler for all node creation.
This commit is contained in:
@@ -51,6 +51,7 @@ struct vnode_ops {
|
|||||||
vnode_op_t link;
|
vnode_op_t link;
|
||||||
vnode_op_t unlink;
|
vnode_op_t unlink;
|
||||||
int (*mkdir)(struct vnode *parent, char *name);
|
int (*mkdir)(struct vnode *parent, char *name);
|
||||||
|
int (*mknod)(struct vnode *parent, char *name, unsigned int mode);
|
||||||
vnode_op_t rmdir;
|
vnode_op_t rmdir;
|
||||||
vnode_op_t rename;
|
vnode_op_t rename;
|
||||||
vnode_op_t getattr;
|
vnode_op_t getattr;
|
||||||
|
|||||||
@@ -43,4 +43,23 @@
|
|||||||
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
|
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
|
||||||
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
|
#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__ */
|
#endif /* __FS0_STAT_H__ */
|
||||||
|
|||||||
@@ -204,7 +204,11 @@ int memfs_write_vnode(struct superblock *sb, struct vnode *v)
|
|||||||
return 0;
|
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 *d, *parent = list_entry(v->dentries.next,
|
||||||
struct dentry, vref);
|
struct dentry, vref);
|
||||||
@@ -368,7 +372,7 @@ int memfs_vnode_readdir(struct vnode *v)
|
|||||||
|
|
||||||
struct vnode_ops memfs_vnode_operations = {
|
struct vnode_ops memfs_vnode_operations = {
|
||||||
.readdir = memfs_vnode_readdir,
|
.readdir = memfs_vnode_readdir,
|
||||||
.mkdir = memfs_vnode_mkdir,
|
.mknod = memfs_vnode_mknod,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct superblock_ops memfs_superblock_operations = {
|
struct superblock_ops memfs_superblock_operations = {
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
|
#include <stat.h>
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This notifies mm0 that this is the fd that refers to this vnode number
|
* 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
|
* for handling syscalls that access file content (i.e. read/write) since
|
||||||
* it maintains the page cache.
|
* 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;
|
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_ARG1, fd);
|
||||||
write_mr(L4SYS_ARG2, vnum);
|
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);
|
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -39,6 +41,35 @@ int send_pager_opendata(l4id_t sender, int fd, unsigned long vnum)
|
|||||||
return 0;
|
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:
|
/* FIXME:
|
||||||
* - Is it already open?
|
* - Is it already open?
|
||||||
* - Allocate a copy of path string since lookup destroys it
|
* - 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)
|
int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
||||||
{
|
{
|
||||||
|
char *pathbuf = alloca(strlen(pathname) + 1);
|
||||||
struct vnode *v;
|
struct vnode *v;
|
||||||
struct tcb *t;
|
struct tcb *t;
|
||||||
int fd;
|
int fd;
|
||||||
char *copypath = kmalloc(strlen(pathname) + 1);
|
int err;
|
||||||
|
|
||||||
strcpy(copypath, pathname);
|
strcpy(pathbuf, pathname);
|
||||||
|
|
||||||
/* Get the vnode */
|
/* Get the vnode */
|
||||||
if (IS_ERR(v = vfs_lookup_bypath(vfs_root.pivot->sb, copypath)))
|
if (IS_ERR(v = vfs_lookup_bypath(vfs_root.pivot->sb, pathbuf))) {
|
||||||
return (int)v;
|
if (!flags & O_CREAT) {
|
||||||
|
return (int)v;
|
||||||
|
} else {
|
||||||
|
if ((err = vfs_create(pathname, mode)) < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Get the task */
|
/* Get the task */
|
||||||
BUG_ON(!(t = find_task(sender)));
|
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 */
|
/* Assign the new fd with the vnode's number */
|
||||||
t->fd[fd] = v->vnum;
|
t->fd[fd] = v->vnum;
|
||||||
|
|
||||||
/* Tell mm0 about opened vnode information */
|
/* Tell the pager about opened vnode information */
|
||||||
BUG_ON(send_pager_opendata(sender, fd, v->vnum) < 0);
|
BUG_ON(send_pager_sys_open(sender, fd, v->vnum) < 0);
|
||||||
|
|
||||||
kfree(copypath);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode)
|
int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode)
|
||||||
{
|
{
|
||||||
char *parentpath, *pathbuf = kmalloc(strlen(pathname) + 1);
|
return vfs_create(pathname, mode);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_read(l4id_t sender, int fd, void *buf, int count)
|
int sys_read(l4id_t sender, int fd, void *buf, int count)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
#define L4_IPC_TAG_READDIR 18
|
#define L4_IPC_TAG_READDIR 18
|
||||||
|
|
||||||
/* Tags for ipc between fs0 and mm0 */
|
/* 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
|
#define L4_IPC_TAG_TASKDATA 26
|
||||||
|
|
||||||
#endif /* __IPCDEFS_H__ */
|
#endif /* __IPCDEFS_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user