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

View File

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

View File

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

View File

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