Removed find_task(sender) + l4_ipc_return(ret) from fs0 syscalls.

Both moved to topmost request handler so syscalls need not call them.
This commit is contained in:
Bahadir Balban
2008-09-16 22:19:54 +03:00
parent ab67ee4cda
commit 86e752be59
4 changed files with 137 additions and 214 deletions

View File

@@ -6,26 +6,28 @@
#ifndef __FS0_SYSCALLS_H__
#define __FS0_SYSCALLS_H__
#include <task.h>
/* Posix calls */
int sys_open(l4id_t sender, char *pathname, int flags, u32 mode);
int sys_readdir(l4id_t sender, int fd, void *buf, int count);
int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode);
int sys_chdir(l4id_t sender, const char *pathname);
int sys_open(struct tcb *sender, const char *pathname, int flags, u32 mode);
int sys_readdir(struct tcb *sender, int fd, void *buf, int count);
int sys_mkdir(struct tcb *sender, const char *pathname, unsigned int mode);
int sys_chdir(struct tcb *sender, const char *pathname);
/* Calls from pager that completes a posix call */
int pager_sys_open(l4id_t sender, l4id_t opener, int fd);
int pager_sys_read(l4id_t sender, unsigned long vnum, unsigned long f_offset,
int pager_sys_open(struct tcb *sender, l4id_t opener, int fd);
int pager_sys_read(struct tcb *sender, unsigned long vnum, unsigned long f_offset,
unsigned long npages, void *pagebuf);
int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset,
int pager_sys_write(struct tcb *sender, unsigned long vnum, unsigned long f_offset,
unsigned long npages, void *pagebuf);
int pager_sys_close(l4id_t sender, l4id_t closer, int fd);
int pager_update_stats(l4id_t sender, unsigned long vnum,
int pager_sys_close(struct tcb *sender, l4id_t closer, int fd);
int pager_update_stats(struct tcb *sender, unsigned long vnum,
unsigned long newsize);
int pager_notify_fork(l4id_t sender, l4id_t parid,
int pager_notify_fork(struct tcb *sender, l4id_t parid,
l4id_t chid, unsigned long utcb_address);
#endif /* __FS0_SYSCALLS_H__ */

View File

@@ -16,6 +16,7 @@
#include <syscalls.h>
#include <task.h>
#include <posix/sys/time.h>
#include <l4/api/errno.h>
/*
* TODO:
@@ -48,19 +49,25 @@ void wait_pager(l4id_t partner)
void handle_fs_requests(void)
{
u32 mr[MR_UNUSED_TOTAL];
l4id_t sender;
int err;
l4id_t senderid;
struct tcb *sender;
int ret;
u32 tag;
if ((err = l4_receive(L4_ANYTHREAD)) < 0) {
if ((ret = l4_receive(L4_ANYTHREAD)) < 0) {
printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__,
__FUNCTION__, err);
__FUNCTION__, ret);
BUG();
}
/* Read conventional ipc data */
tag = l4_get_tag();
sender = l4_get_sender();
senderid = l4_get_sender();
if (!(sender = find_task(senderid))) {
l4_ipc_return(-ESRCH);
return;
}
/* Read mrs not used by syslib */
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
@@ -71,40 +78,40 @@ void handle_fs_requests(void)
switch(tag) {
case L4_IPC_TAG_WAIT:
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
break;
return; /* No reply for this tag */
case L4_IPC_TAG_OPEN:
sys_open(sender, (void *)mr[0], (int)mr[1], (unsigned int)mr[2]);
ret = sys_open(sender, (void *)mr[0], (int)mr[1], (unsigned int)mr[2]);
break;
case L4_IPC_TAG_MKDIR:
sys_mkdir(sender, (const char *)mr[0], (unsigned int)mr[1]);
ret = sys_mkdir(sender, (const char *)mr[0], (unsigned int)mr[1]);
break;
case L4_IPC_TAG_CHDIR:
sys_chdir(sender, (const char *)mr[0]);
ret = sys_chdir(sender, (const char *)mr[0]);
break;
case L4_IPC_TAG_READDIR:
sys_readdir(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
ret = sys_readdir(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
break;
case L4_IPC_TAG_PAGER_READ:
pager_sys_read(sender, (unsigned long)mr[0], (unsigned long)mr[1],
(unsigned long)mr[2], (void *)mr[3]);
ret = pager_sys_read(sender, (unsigned long)mr[0], (unsigned long)mr[1],
(unsigned long)mr[2], (void *)mr[3]);
break;
case L4_IPC_TAG_PAGER_OPEN:
pager_sys_open(sender, (l4id_t)mr[0], (int)mr[1]);
ret = pager_sys_open(sender, (l4id_t)mr[0], (int)mr[1]);
break;
case L4_IPC_TAG_PAGER_WRITE:
pager_sys_write(sender, (unsigned long)mr[0], (unsigned long)mr[1],
(unsigned long)mr[2], (void *)mr[3]);
ret = pager_sys_write(sender, (unsigned long)mr[0], (unsigned long)mr[1],
(unsigned long)mr[2], (void *)mr[3]);
break;
case L4_IPC_TAG_PAGER_CLOSE:
pager_sys_close(sender, (l4id_t)mr[0], (int)mr[1]);
ret = pager_sys_close(sender, (l4id_t)mr[0], (int)mr[1]);
break;
case L4_IPC_TAG_PAGER_UPDATE_STATS:
pager_update_stats(sender, (unsigned long)mr[0],
(unsigned long)mr[1]);
ret = pager_update_stats(sender, (unsigned long)mr[0],
(unsigned long)mr[1]);
break;
case L4_IPC_TAG_NOTIFY_FORK:
pager_notify_fork(sender, (l4id_t)mr[0], (l4id_t)mr[1],
(unsigned long)mr[2]);
ret = pager_notify_fork(sender, (l4id_t)mr[0], (l4id_t)mr[1],
(unsigned long)mr[2]);
break;
default:
@@ -112,6 +119,12 @@ void handle_fs_requests(void)
"received from tid: %d. Ignoring.\n", __TASKNAME__,
mr[MR_TAG], sender);
}
/* Reply */
if ((ret = l4_ipc_return(ret)) < 0) {
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, ret);
BUG();
}
}
void main(void)

View File

@@ -17,6 +17,7 @@
#include <vfs.h>
#include <alloca.h>
#include <path.h>
#include <syscalls.h>
#define NILFD -1
@@ -30,39 +31,36 @@
* keeping the request flow in one way.
*/
int pager_sys_open(l4id_t sender, l4id_t opener, int fd)
int pager_sys_open(struct tcb *pager, l4id_t opener, int fd)
{
struct tcb *task;
struct vnode *v;
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
//
if (pager->tid != PAGER_TID)
return -EINVAL;
/* Check if such task exists */
if (!(task = find_task(opener))) {
l4_ipc_return(-ESRCH);
return 0;
}
if (!(task = find_task(opener)))
return -ESRCH;
/* Check if that fd has been opened */
if (task->fd[fd] == NILFD) {
l4_ipc_return(-EBADF);
return 0;
}
if (task->fd[fd] == NILFD)
return -EBADF;
/* Search the vnode by that vnum */
if (IS_ERR(v = vfs_lookup_byvnum(vfs_root.pivot->sb,
task->fd[fd]))) {
l4_ipc_return((int)v);
return 0;
}
task->fd[fd])))
return (int)v;
/* Write file information */
/*
* Write file information, they will
* be sent via the return reply.
*/
write_mr(L4SYS_ARG0, v->vnum);
write_mr(L4SYS_ARG1, v->size);
/* Return ipc with success code */
l4_ipc_return(0);
return 0;
}
@@ -112,7 +110,7 @@ struct vnode *vfs_create(struct tcb *task, struct pathdata *pdata,
* FIXME: fsync + close could be done under a single "close" ipc
* from pager. Currently there are 2 ipcs: 1 fsync + 1 fd close.
*/
int pager_sys_close(l4id_t sender, l4id_t closer, int fd)
int pager_sys_close(struct tcb *sender, l4id_t closer, int fd)
{
struct tcb *task;
int err;
@@ -124,12 +122,10 @@ int pager_sys_close(l4id_t sender, l4id_t closer, int fd)
if ((err = id_del(task->fdpool, fd)) < 0) {
printf("%s: Error releasing fd identifier.\n",
__FUNCTION__);
l4_ipc_return(err);
return 0;
return err;
}
task->fd[fd] = NILFD;
l4_ipc_return(0);
return 0;
}
@@ -138,26 +134,20 @@ int pager_sys_close(l4id_t sender, l4id_t closer, int fd)
* - Allocate a copy of path string since lookup destroys it
* - Check flags and mode.
*/
int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
int sys_open(struct tcb *task, const char *pathname, int flags, unsigned int mode)
{
struct pathdata *pdata;
struct vnode *v;
struct tcb *task;
int fd;
int retval;
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
/* Get the task */
BUG_ON(!(task = find_task(sender)));
/* Parse path data */
if (IS_ERR(pdata = pathdata_parse(pathname,
alloca(strlen(pathname) + 1),
task))) {
l4_ipc_return((int)pdata);
return 0;
}
task)))
return (int)pdata;
/* Creating new file */
if (flags & O_CREAT) {
@@ -184,77 +174,64 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
out:
pathdata_destroy(pdata);
l4_ipc_return(retval);
return 0;
return retval;
}
int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode)
int sys_mkdir(struct tcb *task, const char *pathname, unsigned int mode)
{
struct tcb *task;
struct pathdata *pdata;
struct vnode *v;
/* Get the task */
BUG_ON(!(task = find_task(sender)));
int ret = 0;
/* Parse path data */
if (IS_ERR(pdata = pathdata_parse(pathname,
alloca(strlen(pathname) + 1),
task))) {
l4_ipc_return((int)pdata);
return 0;
}
task)))
return (int)pdata;
/* Make sure we create a directory */
mode |= S_IFDIR;
/* Create the directory or fail */
if (IS_ERR(v = vfs_create(task, pdata, mode)))
l4_ipc_return((int)v);
else
l4_ipc_return(0);
ret = (int)v;
/* Destroy extracted path data */
pathdata_destroy(pdata);
return 0;
return ret;
}
int sys_chdir(l4id_t sender, const char *pathname)
int sys_chdir(struct tcb *task, const char *pathname)
{
struct vnode *v;
struct tcb *task;
struct pathdata *pdata;
/* Get the task */
BUG_ON(!(task = find_task(sender)));
int ret = 0;
/* Parse path data */
if (IS_ERR(pdata = pathdata_parse(pathname,
alloca(strlen(pathname) + 1),
task))) {
l4_ipc_return((int)pdata);
return 0;
}
task)))
return (int)pdata;
/* Get the vnode */
if (IS_ERR(v = vfs_lookup_bypath(pdata))) {
l4_ipc_return((int)v);
return 0;
ret = (int)v;
goto out;
}
/* Ensure it's a directory */
if (!vfs_isdir(v)) {
l4_ipc_return(-ENOTDIR);
return 0;
ret = -ENOTDIR;
goto out;
}
/* Assign the current directory pointer */
task->curdir = v;
out:
/* Destroy extracted path data */
pathdata_destroy(pdata);
l4_ipc_return(0);
return 0;
return ret;
}
void fill_kstat(struct vnode *v, struct kstat *ks)
@@ -271,33 +248,24 @@ void fill_kstat(struct vnode *v, struct kstat *ks)
ks->ctime = v->ctime;
}
int sys_fstat(l4id_t sender, int fd, void *statbuf)
int sys_fstat(struct tcb *task, int fd, void *statbuf)
{
struct vnode *v;
struct tcb *task;
unsigned long vnum;
int retval;
/* Get the task */
BUG_ON(!(task = find_task(sender)));
/* Get the vnum */
if (fd < 0 || fd > TASK_FILES_MAX) {
l4_ipc_return(-EINVAL);
return 0;
}
if (fd < 0 || fd > TASK_FILES_MAX || task->fd[fd] == NILFD)
return -EBADF;
vnum = task->fd[fd];
/* Lookup vnode */
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) {
retval = -EINVAL; /* No such vnode */
return 0;
}
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
return -EINVAL;
/* Fill in the c0-style stat structure */
fill_kstat(v, statbuf);
l4_ipc_return(0);
return 0;
}
@@ -306,34 +274,31 @@ int sys_fstat(l4id_t sender, int fd, void *statbuf)
* converted to posix style stat structure via the libposix
* library in userspace.
*/
int sys_stat(l4id_t sender, const char *pathname, void *statbuf)
int sys_stat(struct tcb *task, const char *pathname, void *statbuf)
{
struct vnode *v;
struct tcb *task;
struct pathdata *pdata;
/* Get the task */
BUG_ON(!(task = find_task(sender)));
int ret = 0;
/* Parse path data */
if (IS_ERR(pdata = pathdata_parse(pathname,
alloca(strlen(pathname) + 1),
task))) {
l4_ipc_return((int)pdata);
return 0;
}
task)))
return (int)pdata;
/* Get the vnode */
if (IS_ERR(v = vfs_lookup_bypath(pdata))) {
l4_ipc_return((int)v);
return 0;
ret = (int)v;
goto out;
}
/* Fill in the c0-style stat structure */
fill_kstat(v, statbuf);
l4_ipc_return(0);
return 0;
out:
/* Destroy extracted path data */
pathdata_destroy(pdata);
return ret;
}
/*
@@ -341,65 +306,44 @@ int sys_stat(l4id_t sender, const char *pathname, void *statbuf)
* That call is in the pager. This merely supplies the pages the pager needs
* if they're not in the page cache.
*/
int pager_sys_read(l4id_t sender, unsigned long vnum, unsigned long f_offset,
int pager_sys_read(struct tcb *pager, unsigned long vnum, unsigned long f_offset,
unsigned long npages, void *pagebuf)
{
struct vnode *v;
int err, retval = 0;
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
if (sender != PAGER_TID) {
retval = -EINVAL;
goto out;
}
if (pager->tid != PAGER_TID)
return -EINVAL;
/* Lookup vnode */
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) {
retval = -EINVAL; /* No such vnode */
goto out;
}
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
return -EINVAL;
/* Ensure vnode is not a directory */
if (vfs_isdir(v)) {
retval = -EISDIR;
goto out;
}
if (vfs_isdir(v))
return -EISDIR;
if ((err = v->fops.read(v, f_offset, npages, pagebuf)) < 0) {
retval = err;
goto out;
}
out:
l4_ipc_return(retval);
return 0;
return v->fops.read(v, f_offset, npages, pagebuf);
}
int pager_update_stats(l4id_t sender, unsigned long vnum,
int pager_update_stats(struct tcb *pager, unsigned long vnum,
unsigned long newsize)
{
struct vnode *v;
int retval = 0;
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
if (sender != PAGER_TID) {
retval = -EINVAL;
goto out;
}
if (pager->tid != PAGER_TID)
return -EINVAL;
/* Lookup vnode */
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) {
retval = -EINVAL; /* No such vnode */
goto out;
}
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
return -EINVAL;
v->size = newsize;
v->sb->ops->write_vnode(v->sb, v);
out:
l4_ipc_return(retval);
return 0;
}
@@ -410,30 +354,23 @@ out:
*
* The buffer must be contiguous by page, if npages > 1.
*/
int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset,
int pager_sys_write(struct tcb *pager, unsigned long vnum, unsigned long f_offset,
unsigned long npages, void *pagebuf)
{
struct vnode *v;
int err, retval = 0;
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
if (sender != PAGER_TID) {
retval = -EINVAL;
goto out;
}
if (pager->tid != PAGER_TID)
return -EINVAL;
/* Lookup vnode */
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) {
retval = -EINVAL; /* No such vnode */
goto out;
}
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
return -EINVAL;
/* Ensure vnode is not a directory */
if (vfs_isdir(v)) {
retval = -EISDIR;
goto out;
}
if (vfs_isdir(v))
return -EISDIR;
printf("%s/%s: Writing to vnode %lu, at pgoff 0x%x, %d pages, buf at 0x%x\n",
__TASKNAME__, __FUNCTION__, vnum, f_offset, npages, pagebuf);
@@ -443,16 +380,7 @@ int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset,
* But we expect an explicit pager_update_stats from the
* pager to update the new file size on the vnode.
*/
if ((err = v->fops.write(v, f_offset, npages, pagebuf)) < 0) {
retval = err;
goto out;
}
out:
// printf("%s/%s: Returning ipc result.\n", __TASKNAME__, __FUNCTION__);
l4_ipc_return(retval);
// printf("%s/%s: Done.\n", __TASKNAME__, __FUNCTION__);
return 0;
return v->fops.write(v, f_offset, npages, pagebuf);
}
/*
@@ -494,47 +422,35 @@ int fill_dirent(void *buf, unsigned long vnum, int offset, char *name)
*
* FIXME: Ensure buf is in shared utcb, and count does not exceed it.
*/
int sys_readdir(l4id_t sender, int fd, void *buf, int count)
int sys_readdir(struct tcb *t, int fd, void *buf, int count)
{
int dirent_size = sizeof(struct dirent);
int total = 0, nbytes = 0;
unsigned long vnum;
struct vnode *v;
struct dentry *d;
struct tcb *t;
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
/* Get the task */
BUG_ON(!(t = find_task(sender)));
/* Check address is in task's utcb */
if ((unsigned long)buf < t->utcb_address ||
(unsigned long)buf > t->utcb_address + PAGE_SIZE) {
l4_ipc_return(-EINVAL);
return 0;
}
(unsigned long)buf > t->utcb_address + PAGE_SIZE)
return -EINVAL;
if (fd < 0 || fd > TASK_FILES_MAX) {
l4_ipc_return(-EBADF);
return 0;
}
if (fd < 0 || fd > TASK_FILES_MAX || t->fd[fd] == NILFD)
return -EBADF;
/* Convert fd to vnum. */
BUG_ON((vnum = t->fd[fd]) < 0);
vnum = t->fd[fd];
/* Lookup vnode */
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) {
l4_ipc_return(-EINVAL);
return 0; /* No such vnode */
}
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
return -EINVAL;
d = list_entry(v->dentries.next, struct dentry, vref);
/* Ensure vnode is a directory */
if (!vfs_isdir(v)) {
l4_ipc_return(-ENOTDIR);
return 0;
}
if (!vfs_isdir(v))
return -ENOTDIR;
/* Write pseudo-entries . and .. to user buffer */
if (count < dirent_size)
@@ -554,13 +470,9 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count)
count -= dirent_size;
/* Copy fs-specific dir to buf in struct dirent format */
if ((total = v->ops.filldir(buf, v, count)) < 0) {
l4_ipc_return(total);
return 0;
}
nbytes += total;
l4_ipc_return(nbytes);
if ((total = v->ops.filldir(buf, v, count)) < 0)
return total;
return 0;
return nbytes + total;
}

View File

@@ -16,6 +16,7 @@
#include <sys/shm.h>
#include <sys/types.h>
#include <errno.h>
#include <syscalls.h>
struct tcb_head {
struct list_head list;
@@ -124,7 +125,7 @@ out_err:
* Receives ipc from pager about a new fork event and
* the information on the resulting child task.
*/
int pager_notify_fork(l4id_t sender, l4id_t parid,
int pager_notify_fork(struct tcb *sender, l4id_t parid,
l4id_t chid, unsigned long utcb_address)
{
struct tcb *child, *parent;
@@ -132,10 +133,8 @@ int pager_notify_fork(l4id_t sender, l4id_t parid,
// printf("%s/%s\n", __TASKNAME__, __FUNCTION__);
BUG_ON(!(parent = find_task(parid)));
if (IS_ERR(child = create_tcb())) {
l4_ipc_return((int)child);
return 0;
}
if (IS_ERR(child = create_tcb()))
return (int)child;
/* Initialise fields sent by pager */
child->tid = chid;
@@ -152,10 +151,7 @@ int pager_notify_fork(l4id_t sender, l4id_t parid,
id_pool_copy(child->fdpool, parent->fdpool, TASK_FILES_MAX);
memcpy(child->fd, parent->fd, TASK_FILES_MAX * sizeof(int));
l4_ipc_return(0);
printf("%s/%s: Exiting...\n", __TASKNAME__, __FUNCTION__);
return 0;
}