mirror of
https://github.com/drasko/codezero.git
synced 2026-07-22 07:05:24 +02:00
Added per-task curdir. and chdir, pager_read/write, mmap and munmap calls.
They look like what they should look like, but untested.
This commit is contained in:
@@ -86,7 +86,7 @@ struct dentry {
|
|||||||
struct list_head children; /* List of children dentries */
|
struct list_head children; /* List of children dentries */
|
||||||
struct list_head vref; /* For vnode's dirent reference list */
|
struct list_head vref; /* For vnode's dirent reference list */
|
||||||
struct list_head cache_list; /* Dentry cache reference */
|
struct list_head cache_list; /* Dentry cache reference */
|
||||||
struct vnode *vnode; /* The vnode associated with dirent */
|
struct vnode *vnode; /* The vnode associated with dentry */
|
||||||
struct dentry_ops ops;
|
struct dentry_ops ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,16 @@
|
|||||||
#ifndef __FS0_SYSCALLS_H__
|
#ifndef __FS0_SYSCALLS_H__
|
||||||
#define __FS0_SYSCALLS_H__
|
#define __FS0_SYSCALLS_H__
|
||||||
|
|
||||||
|
/* Posix calls */
|
||||||
int sys_open(l4id_t sender, char *pathname, int flags, u32 mode);
|
int sys_open(l4id_t sender, char *pathname, int flags, u32 mode);
|
||||||
int sys_read(l4id_t sender, int fd, void *buf, int cnt);
|
int sys_readdir(l4id_t sender, int fd, void *buf, int count);
|
||||||
int sys_write(l4id_t sender, int fd, void *buf, int cnt);
|
int sys_mkdir(l4id_t sender, const char *pathname, unsigned int mode);
|
||||||
int sys_lseek(l4id_t sender, int fd, unsigned long offset, int whence);
|
int sys_chdir(l4id_t sender, const char *pathname);
|
||||||
|
|
||||||
|
/* Calls from pager that completes a posix call */
|
||||||
|
int pager_sys_read(l4id_t 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,
|
||||||
|
unsigned long npages, void *pagebuf);
|
||||||
#endif /* __FS0_SYSCALLS_H__ */
|
#endif /* __FS0_SYSCALLS_H__ */
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ struct tcb {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
int fd[TASK_OFILES_MAX];
|
int fd[TASK_OFILES_MAX];
|
||||||
struct id_pool *fdpool;
|
struct id_pool *fdpool;
|
||||||
|
struct vnode *curdir;
|
||||||
|
struct vnode *rootdir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tcb *find_task(int tid);
|
struct tcb *find_task(int tid);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <memfs/memfs.h>
|
#include <memfs/memfs.h>
|
||||||
#include <l4/macros.h>
|
#include <l4/macros.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
extern struct list_head vnode_cache;
|
extern struct list_head vnode_cache;
|
||||||
extern struct list_head dentry_cache;
|
extern struct list_head dentry_cache;
|
||||||
@@ -92,7 +93,7 @@ extern struct vfs_mountpoint vfs_root;
|
|||||||
|
|
||||||
int vfs_mount_root(struct superblock *sb);
|
int vfs_mount_root(struct superblock *sb);
|
||||||
struct vnode *generic_vnode_lookup(struct vnode *thisnode, char *path);
|
struct vnode *generic_vnode_lookup(struct vnode *thisnode, char *path);
|
||||||
struct vnode *vfs_lookup_bypath(struct superblock *sb, char *path);
|
struct vnode *vfs_lookup_bypath(struct tcb *task, char *path);
|
||||||
struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum);
|
struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum);
|
||||||
|
|
||||||
#endif /* __VFS_H__ */
|
#endif /* __VFS_H__ */
|
||||||
|
|||||||
@@ -33,10 +33,8 @@
|
|||||||
* - Add mkdir
|
* - Add mkdir
|
||||||
* - Add create
|
* - Add create
|
||||||
* - Add read/write -> This will need page cache and mm0 involvement.
|
* - Add read/write -> This will need page cache and mm0 involvement.
|
||||||
*/
|
*
|
||||||
|
* Done those, too. but untested.
|
||||||
/* TODO:
|
|
||||||
* Assign memfs dentry fields same as in posix
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Synchronise with pager via a `wait' tagged ipc with destination as pager */
|
/* Synchronise with pager via a `wait' tagged ipc with destination as pager */
|
||||||
@@ -74,16 +72,24 @@ void handle_fs_requests(void)
|
|||||||
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
|
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
|
||||||
break;
|
break;
|
||||||
case L4_IPC_TAG_OPEN:
|
case L4_IPC_TAG_OPEN:
|
||||||
sys_open(sender, (void *)mr[0], (int)mr[1], (u32)mr[2]);
|
sys_open(sender, (void *)mr[0], (int)mr[1], (unsigned int)mr[2]);
|
||||||
break;
|
break;
|
||||||
case L4_IPC_TAG_READ:
|
case L4_IPC_TAG_MKDIR:
|
||||||
sys_read(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
|
sys_mkdir(sender, (const char *)mr[0], (unsigned int)mr[1]);
|
||||||
break;
|
break;
|
||||||
case L4_IPC_TAG_WRITE:
|
case L4_IPC_TAG_CHDIR:
|
||||||
sys_write(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
|
sys_chdir(sender, (const char *)mr[0]);
|
||||||
break;
|
break;
|
||||||
case L4_IPC_TAG_LSEEK:
|
case L4_IPC_TAG_READDIR:
|
||||||
sys_lseek(sender, (int)mr[0], (int)mr[1], (int)mr[2]);
|
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]);
|
||||||
|
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]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("%s: Unrecognised ipc tag (%d)"
|
printf("%s: Unrecognised ipc tag (%d)"
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ int memfs_format_filesystem(void *buffer)
|
|||||||
INIT_LIST_HEAD(&sb->inode_cache_list);
|
INIT_LIST_HEAD(&sb->inode_cache_list);
|
||||||
memfs_init_caches(sb);
|
memfs_init_caches(sb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Make sure root vnode has a vnode number of 0 !!!.
|
||||||
|
* This is used in early root lookup.
|
||||||
|
*/
|
||||||
|
BUG();
|
||||||
|
|
||||||
/* We allocate and fix a root inode so the sb is ready for mount */
|
/* We allocate and fix a root inode so the sb is ready for mount */
|
||||||
sb->root = memfs_create_inode(sb);
|
sb->root = memfs_create_inode(sb);
|
||||||
|
|
||||||
|
|||||||
@@ -25,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_sys_open(l4id_t sender, int fd, unsigned long vnum, unsigned long size)
|
int pager_sys_open(l4id_t sender, int fd, unsigned long vnum, unsigned long size)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ int send_pager_sys_open(l4id_t sender, int fd, unsigned long vnum, unsigned long
|
|||||||
write_mr(L4SYS_ARG2, vnum);
|
write_mr(L4SYS_ARG2, vnum);
|
||||||
write_mr(L4SYS_ARG3, size);
|
write_mr(L4SYS_ARG3, size);
|
||||||
|
|
||||||
if ((err = l4_send(PAGER_TID, L4_IPC_TAG_PAGER_SYSOPEN)) < 0) {
|
if ((err = l4_send(PAGER_TID, L4_IPC_TAG_PAGER_OPEN)) < 0) {
|
||||||
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ int send_pager_sys_open(l4id_t sender, int fd, unsigned long vnum, unsigned long
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Creates a node under a directory, e.g. a file, directory. */
|
/* Creates a node under a directory, e.g. a file, directory. */
|
||||||
int vfs_create(const char *pathname, unsigned int mode)
|
int vfs_create(struct tcb *task, const char *pathname, unsigned int mode)
|
||||||
{
|
{
|
||||||
char *pathbuf = alloca(strlen(pathname) + 1);
|
char *pathbuf = alloca(strlen(pathname) + 1);
|
||||||
char *parentpath = pathbuf;
|
char *parentpath = pathbuf;
|
||||||
@@ -57,7 +57,7 @@ int vfs_create(const char *pathname, unsigned int mode)
|
|||||||
nodename = splitpath_end(&parentpath, '/');
|
nodename = splitpath_end(&parentpath, '/');
|
||||||
|
|
||||||
/* Check that the parent directory exists. */
|
/* Check that the parent directory exists. */
|
||||||
if (IS_ERR(vparent = vfs_lookup_bypath(vfs_root.pivot->sb, parentpath)))
|
if (IS_ERR(vparent = vfs_lookup_bypath(task, parentpath)))
|
||||||
return (int)vparent;
|
return (int)vparent;
|
||||||
|
|
||||||
/* The parent vnode must be a directory. */
|
/* The parent vnode must be a directory. */
|
||||||
@@ -80,58 +80,127 @@ int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
|||||||
{
|
{
|
||||||
char *pathbuf = alloca(strlen(pathname) + 1);
|
char *pathbuf = alloca(strlen(pathname) + 1);
|
||||||
struct vnode *v;
|
struct vnode *v;
|
||||||
struct tcb *t;
|
struct tcb *task;
|
||||||
int fd;
|
int fd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
strcpy(pathbuf, pathname);
|
strcpy(pathbuf, pathname);
|
||||||
|
|
||||||
|
/* Get the task */
|
||||||
|
BUG_ON(!(task = find_task(sender)));
|
||||||
|
|
||||||
/* Get the vnode */
|
/* Get the vnode */
|
||||||
if (IS_ERR(v = vfs_lookup_bypath(vfs_root.pivot->sb, pathbuf))) {
|
if (IS_ERR(v = vfs_lookup_bypath(task, pathbuf))) {
|
||||||
if (!flags & O_CREAT) {
|
if (!flags & O_CREAT) {
|
||||||
return (int)v;
|
return (int)v;
|
||||||
} else {
|
} else {
|
||||||
if ((err = vfs_create(pathname, mode)) < 0)
|
if ((err = vfs_create(task, pathname, mode)) < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Get the task */
|
|
||||||
BUG_ON(!(t = find_task(sender)));
|
|
||||||
|
|
||||||
/* Get a new fd */
|
/* Get a new fd */
|
||||||
BUG_ON(!(fd = id_new(t->fdpool)));
|
BUG_ON(!(fd = id_new(task->fdpool)));
|
||||||
|
|
||||||
/* Assign the new fd with the vnode's number */
|
/* Assign the new fd with the vnode's number */
|
||||||
t->fd[fd] = v->vnum;
|
task->fd[fd] = v->vnum;
|
||||||
|
|
||||||
/* Tell the pager about opened vnode information */
|
/* Tell the pager about opened vnode information */
|
||||||
BUG_ON(send_pager_sys_open(sender, fd, v->vnum, v->size) < 0);
|
BUG_ON(pager_sys_open(sender, fd, v->vnum, v->size) < 0);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
return vfs_create(pathname, mode);
|
struct tcb *task;
|
||||||
|
|
||||||
|
/* Get the task */
|
||||||
|
BUG_ON(!(task = find_task(sender)));
|
||||||
|
|
||||||
|
return vfs_create(task, pathname, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_read(l4id_t sender, int fd, void *buf, int count)
|
int sys_chdir(l4id_t sender, const char *pathname)
|
||||||
{
|
{
|
||||||
return 0;
|
char *pathbuf = alloca(strlen(pathname) + 1);
|
||||||
}
|
struct vnode *v;
|
||||||
|
struct tcb *task;
|
||||||
|
|
||||||
int sys_write(l4id_t sender, int fd, const void *buf, int count)
|
strcpy(pathbuf, pathname);
|
||||||
{
|
|
||||||
return 0;
|
/* Get the task */
|
||||||
}
|
BUG_ON(!(task = find_task(sender)));
|
||||||
|
|
||||||
|
/* Get the vnode */
|
||||||
|
if (IS_ERR(v = vfs_lookup_bypath(task, pathbuf)))
|
||||||
|
return (int)v;
|
||||||
|
|
||||||
|
/* Ensure it's a directory */
|
||||||
|
if (!vfs_isdir(v))
|
||||||
|
return -ENOTDIR;
|
||||||
|
|
||||||
|
/* Assign the current directory pointer */
|
||||||
|
task->curdir = v;
|
||||||
|
|
||||||
int sys_lseek(l4id_t sender, int fd, int offset, int whence)
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads @count bytes of posix struct dirents into @buf
|
* Note this can be solely called by the pager and is not the posix read call.
|
||||||
|
* 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,
|
||||||
|
unsigned long npages, void *pagebuf)
|
||||||
|
{
|
||||||
|
struct vnode *v;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (sender != PAGER_TID)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Lookup vnode */
|
||||||
|
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||||
|
return -EINVAL; /* No such vnode */
|
||||||
|
|
||||||
|
/* Ensure vnode is not a directory */
|
||||||
|
if (vfs_isdir(v))
|
||||||
|
return -EISDIR;
|
||||||
|
|
||||||
|
if ((err = v->fops.read(v, f_offset, npages, pagebuf)) < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset,
|
||||||
|
unsigned long npages, void *pagebuf)
|
||||||
|
{
|
||||||
|
struct vnode *v;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (sender != PAGER_TID)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Lookup vnode */
|
||||||
|
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
||||||
|
return -EINVAL; /* No such vnode */
|
||||||
|
|
||||||
|
/* Ensure vnode is not a directory */
|
||||||
|
if (vfs_isdir(v))
|
||||||
|
return -EISDIR;
|
||||||
|
|
||||||
|
if ((err = v->fops.write(v, f_offset, npages, pagebuf)) < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reads @count bytes of posix struct dirents into @buf. This implements
|
||||||
|
* the raw dirent read syscall upon which readdir() etc. posix calls
|
||||||
|
* can be built in userspace.
|
||||||
*/
|
*/
|
||||||
int sys_readdir(l4id_t sender, int fd, void *buf, int count)
|
int sys_readdir(l4id_t sender, int fd, void *buf, int count)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include <l4lib/ipcdefs.h>
|
#include <l4lib/ipcdefs.h>
|
||||||
#include <lib/malloc.h>
|
#include <lib/malloc.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
|
#include <vfs.h>
|
||||||
|
|
||||||
|
|
||||||
struct tcb_head {
|
struct tcb_head {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@@ -88,10 +90,12 @@ int init_task_structs(l4id_t *tdata)
|
|||||||
struct tcb *t;
|
struct tcb *t;
|
||||||
int total = tdata[0];
|
int total = tdata[0];
|
||||||
|
|
||||||
for (int i = 0; i < total; i++)
|
for (int i = 0; i < total; i++) {
|
||||||
if (IS_ERR(t = create_tcb(tdata[1 + i])))
|
if (IS_ERR(t = create_tcb(tdata[1 + i])))
|
||||||
return (int)t;
|
return (int)t;
|
||||||
|
t->rootdir = vfs_root.pivot;
|
||||||
|
t->curdir = vfs_root.pivot;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
struct list_head vnode_cache;
|
struct list_head vnode_cache;
|
||||||
struct list_head dentry_cache;
|
struct list_head dentry_cache;
|
||||||
@@ -56,22 +57,25 @@ struct vnode *vfs_lookup_byvnum(struct superblock *sb, unsigned long vnum)
|
|||||||
* have, the other is their vnum. This one checks the vnode cache by the path
|
* have, the other is their vnum. This one checks the vnode cache by the path
|
||||||
* first. If nothing is found, it reads the vnode from disk into the cache.
|
* first. If nothing is found, it reads the vnode from disk into the cache.
|
||||||
*/
|
*/
|
||||||
struct vnode *vfs_lookup_bypath(struct superblock *sb, char *path)
|
struct vnode *vfs_lookup_bypath(struct tcb *task, char *path)
|
||||||
{
|
{
|
||||||
/* If it's just / we already got it. */
|
/* If it's the root or current dir, we already got it. */
|
||||||
if (!strcmp(path, "/"))
|
if (!strcmp(path, "/"))
|
||||||
return sb->root;
|
return task->rootdir;
|
||||||
|
if (!strcmp(path, "."))
|
||||||
|
return task->curdir;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This does vfs cache + fs lookup.
|
* This does vfs cache + fs lookup.
|
||||||
*/
|
*/
|
||||||
return generic_vnode_lookup(sb->root, path);
|
return generic_vnode_lookup(task->rootdir, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfs_mount_root(struct superblock *sb)
|
int vfs_mount_root(struct superblock *sb)
|
||||||
{
|
{
|
||||||
/* Lookup the root vnode of this superblock */
|
/* Lookup the root vnode of this superblock.
|
||||||
vfs_root.pivot = vfs_lookup_bypath(sb, "/");
|
* The root superblock has vnode number 0. */
|
||||||
|
vfs_root.pivot = vfs_lookup_byvnum(sb, 0);
|
||||||
vfs_root.sb = sb;
|
vfs_root.sb = sb;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007 Bahadir Balban
|
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||||
*
|
*
|
||||||
* This file contains ipc definitions that are needed for server tasks
|
* This file contains ipc definitions that are needed for server tasks
|
||||||
* to communicate with each other. For example common shared memory ids
|
* to communicate with each other. For example common shared memory ids
|
||||||
@@ -40,9 +40,14 @@
|
|||||||
#define L4_IPC_TAG_CLOSE 16
|
#define L4_IPC_TAG_CLOSE 16
|
||||||
#define L4_IPC_TAG_BRK 17
|
#define L4_IPC_TAG_BRK 17
|
||||||
#define L4_IPC_TAG_READDIR 18
|
#define L4_IPC_TAG_READDIR 18
|
||||||
|
#define L4_IPC_TAG_MKDIR 19
|
||||||
|
#define L4_IPC_TAG_MMAP2 20
|
||||||
|
#define L4_IPC_TAG_CHDIR 21
|
||||||
|
|
||||||
/* Tags for ipc between fs0 and mm0 */
|
/* Tags for ipc between fs0 and mm0 */
|
||||||
#define L4_IPC_TAG_PAGER_SYSOPEN 25
|
#define L4_IPC_TAG_TASKDATA 25
|
||||||
#define L4_IPC_TAG_TASKDATA 26
|
#define L4_IPC_TAG_PAGER_OPEN 26 /* vfs sends the pager open file data. */
|
||||||
|
#define L4_IPC_TAG_PAGER_READ 27 /* Pager reads file contents from vfs */
|
||||||
|
#define L4_IPC_TAG_PAGER_WRITE 28 /* Pager writes file contents to vfs */
|
||||||
|
|
||||||
#endif /* __IPCDEFS_H__ */
|
#endif /* __IPCDEFS_H__ */
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ struct sys_mmap_args {
|
|||||||
int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
|
int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
|
||||||
int flags, int fd, off_t offset);
|
int flags, int fd, off_t offset);
|
||||||
|
|
||||||
|
int sys_munmap(l4id_t sender, void *vaddr, unsigned long size);
|
||||||
|
|
||||||
struct sys_shmat_args {
|
struct sys_shmat_args {
|
||||||
l4id_t shmid;
|
l4id_t shmid;
|
||||||
const void *shmaddr;
|
const void *shmaddr;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ void handle_requests(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case L4_IPC_TAG_TASKDATA:
|
case L4_IPC_TAG_TASKDATA:
|
||||||
|
/* Send runnable task information to fs0 */
|
||||||
send_task_data(sender);
|
send_task_data(sender);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@ void handle_requests(void)
|
|||||||
sys_shmdt(sender, (void *)mr[0]);
|
sys_shmdt(sender, (void *)mr[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L4_IPC_TAG_PAGER_SYSOPEN:
|
case L4_IPC_TAG_PAGER_OPEN:
|
||||||
/* vfs opens a file and tells us about it here. */
|
/* vfs opens a file and tells us about it here. */
|
||||||
vfs_receive_sys_open(sender, (l4id_t)mr[0], (int)mr[1],
|
vfs_receive_sys_open(sender, (l4id_t)mr[0], (int)mr[1],
|
||||||
(unsigned long)mr[2], (unsigned long)mr[3]);
|
(unsigned long)mr[2], (unsigned long)mr[3]);
|
||||||
@@ -98,19 +99,24 @@ void handle_requests(void)
|
|||||||
sys_write(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
|
sys_write(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case L4_IPC_TAG_MMAP2: {
|
||||||
|
struct sys_mmap_args *args = (struct sys_mmap_args *)mr[0];
|
||||||
|
sys_mmap(sender, args->start, args->length, args->prot,
|
||||||
|
args->flags, args->fd, args->offset);
|
||||||
|
}
|
||||||
case L4_IPC_TAG_MMAP: {
|
case L4_IPC_TAG_MMAP: {
|
||||||
struct sys_mmap_args *args = (struct sys_mmap_args *)&mr[0];
|
struct sys_mmap_args *args = (struct sys_mmap_args *)&mr[0];
|
||||||
BUG(); /* FIXME: There are 8 arguments to ipc whereas there are 7 mrs available. Fix this by increasing MRs to 8 ??? */
|
sys_mmap(sender, args->start, args->length, args->prot,
|
||||||
sys_mmap(sender, args->start, args->length, args->prot, args->flags, args->fd, args->offset);
|
args->flags, args->fd, __pfn(args->offset));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case L4_IPC_TAG_BRK: {
|
case L4_IPC_TAG_BRK: {
|
||||||
// sys_brk(sender, (void *)mr[0]);
|
// sys_brk(sender, (void *)mr[0]);
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case L4_IPC_TAG_MUNMAP: {
|
case L4_IPC_TAG_MUNMAP: {
|
||||||
/* TODO: Use arg struct instead */
|
sys_munmap(sender, (void *)mr[0], (unsigned long)mr[1]);
|
||||||
// sys_munmap(sender, (void *)mr[0], (int)mr[1]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case L4_IPC_TAG_MSYNC: {
|
case L4_IPC_TAG_MSYNC: {
|
||||||
|
|||||||
@@ -194,7 +194,6 @@ struct vm_area *vma_split(struct vm_area *vma, struct tcb *task,
|
|||||||
if (!(new = vma_new(0, 0, 0, 0, 0)))
|
if (!(new = vma_new(0, 0, 0, 0, 0)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some sanity checks to show that splitter range does end up
|
* Some sanity checks to show that splitter range does end up
|
||||||
* producing two smaller vmas.
|
* producing two smaller vmas.
|
||||||
@@ -367,6 +366,15 @@ pgtable_unmap:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sys_munmap(l4id_t sender, void *vaddr, unsigned long size)
|
||||||
|
{
|
||||||
|
struct tcb *task;
|
||||||
|
|
||||||
|
BUG_ON(!(task = find_task(sender)));
|
||||||
|
|
||||||
|
return do_munmap(vaddr, size, task);
|
||||||
|
}
|
||||||
|
|
||||||
static struct vm_area *
|
static struct vm_area *
|
||||||
is_vma_mergeable(unsigned long pfn_start, unsigned long pfn_end,
|
is_vma_mergeable(unsigned long pfn_start, unsigned long pfn_end,
|
||||||
unsigned int flags, struct vm_area *vma)
|
unsigned int flags, struct vm_area *vma)
|
||||||
@@ -480,15 +488,35 @@ int do_mmap(struct vm_file *mapfile, unsigned long f_offset, struct tcb *t,
|
|||||||
|
|
||||||
/* mmap system call implementation */
|
/* mmap system call implementation */
|
||||||
int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
|
int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
|
||||||
int flags, int fd, off_t offset)
|
int flags, int fd, unsigned long pfn)
|
||||||
{
|
{
|
||||||
|
unsigned long npages = __pfn(page_align_up(length));
|
||||||
|
struct tcb * task;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
BUG_ON(!(task = find_task(sender)));
|
||||||
|
|
||||||
|
if (fd < 0 || fd > TASK_OFILES_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((unsigned long)start < USER_AREA_START || (unsigned long)start >= USER_AREA_END)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
* Check that @start does not already have a mapping.
|
||||||
|
* Check that pfn + npages range is within the file range.
|
||||||
|
* Check that posix flags passed match those defined in vm_area.h
|
||||||
|
*/
|
||||||
|
if ((err = do_mmap(task->fd[fd].vmfile, __pfn_to_addr(pfn), task,
|
||||||
|
(unsigned long)start, flags, npages)) < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets the end of data segment for sender */
|
/* Sets the end of data segment for sender */
|
||||||
int sys_brk(l4id_t sender, void *ds_end)
|
int sys_brk(l4id_t sender, void *ds_end)
|
||||||
{
|
{
|
||||||
// do_brk(find_task(sender), ds_end);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ error:
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void init_pm(struct initdata *initdata)
|
void init_pm(struct initdata *initdata)
|
||||||
{
|
{
|
||||||
start_boot_tasks(initdata, &tcb_head);
|
start_boot_tasks(initdata, &tcb_head);
|
||||||
|
|||||||
Reference in New Issue
Block a user