mirror of
https://github.com/drasko/codezero.git
synced 2026-01-14 11:53:15 +01:00
Added sys_close and sys_fsync
Untested.
This commit is contained in:
@@ -19,6 +19,7 @@ int pager_sys_read(l4id_t sender, unsigned long vnum, unsigned long f_offset,
|
||||
int pager_sys_write(l4id_t 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,
|
||||
unsigned long newsize);
|
||||
#endif /* __FS0_SYSCALLS_H__ */
|
||||
|
||||
@@ -92,6 +92,9 @@ void handle_fs_requests(void)
|
||||
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]);
|
||||
break;
|
||||
case L4_IPC_TAG_PAGER_UPDATE_STATS:
|
||||
pager_update_stats(sender, (unsigned long)mr[0],
|
||||
(unsigned long)mr[1]);
|
||||
|
||||
@@ -93,6 +93,30 @@ struct vnode *vfs_create(struct tcb *task, struct pathdata *pdata,
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* Pager notifies vfs about a closed file descriptor.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct tcb *task;
|
||||
int err;
|
||||
|
||||
BUG_ON(!(task = find_task(sender)));
|
||||
|
||||
if ((err = id_del(task->fdpool, task->fd[fd])) < 0) {
|
||||
printf("%s: Error releasing fd identifier.\n",
|
||||
__FUNCTION__);
|
||||
l4_ipc_return(err);
|
||||
return 0;
|
||||
}
|
||||
task->fd[fd] = -1;
|
||||
|
||||
l4_ipc_return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME:
|
||||
* - Is it already open?
|
||||
* - Allocate a copy of path string since lookup destroys it
|
||||
|
||||
@@ -45,13 +45,15 @@
|
||||
#define L4_IPC_TAG_FORK 22
|
||||
#define L4_IPC_TAG_STAT 23
|
||||
#define L4_IPC_TAG_FSTAT 24
|
||||
#define L4_IPC_TAG_FSYNC 25 /* Pager notifies vfs of file close */
|
||||
|
||||
|
||||
/* Tags for ipc between fs0 and mm0 */
|
||||
#define L4_IPC_TAG_TASKDATA 25
|
||||
#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 */
|
||||
#define L4_IPC_TAG_PAGER_UPDATE_STATS 29 /* Pager updates file stats in vfs */
|
||||
#define L4_IPC_TAG_TASKDATA 40
|
||||
#define L4_IPC_TAG_PAGER_OPEN 41 /* vfs sends the pager open file data. */
|
||||
#define L4_IPC_TAG_PAGER_READ 42 /* Pager reads file contents from vfs */
|
||||
#define L4_IPC_TAG_PAGER_WRITE 43 /* Pager writes file contents to vfs */
|
||||
#define L4_IPC_TAG_PAGER_CLOSE 44 /* Pager notifies vfs of file close */
|
||||
#define L4_IPC_TAG_PAGER_UPDATE_STATS 45 /* Pager updates file stats in vfs */
|
||||
|
||||
#endif /* __IPCDEFS_H__ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* l4/posix glue for close()
|
||||
* l4/posix glue for close() and fsync()
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
@@ -44,3 +44,34 @@ int close(int fd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int l4_fsync(int fd)
|
||||
{
|
||||
write_mr(L4SYS_ARG0, fd);
|
||||
|
||||
/* Call pager with close() request. Check ipc error. */
|
||||
if ((fd = l4_sendrecv(PAGER_TID, PAGER_TID, L4_IPC_TAG_FSYNC)) < 0) {
|
||||
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
/* Check if syscall itself was successful */
|
||||
if ((fd = l4_get_retval()) < 0) {
|
||||
printf("%s: CLOSE Error: %d.\n", __FUNCTION__, fd);
|
||||
return fd;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int fsync(int fd)
|
||||
{
|
||||
int ret = l4_fsync(fd);
|
||||
|
||||
/* If error, return positive error code */
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* else return value */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ int vfs_write(unsigned long vnum, unsigned long f_offset, unsigned long npages,
|
||||
int sys_read(l4id_t sender, int fd, void *buf, int count);
|
||||
int sys_write(l4id_t sender, int fd, void *buf, int count);
|
||||
int sys_lseek(l4id_t sender, int fd, off_t offset, int whence);
|
||||
int sys_close(l4id_t sender, int fd);
|
||||
int sys_fsync(l4id_t sender, int fd);
|
||||
|
||||
struct vfs_file_data {
|
||||
unsigned long vnum;
|
||||
|
||||
@@ -97,6 +97,14 @@ void handle_requests(void)
|
||||
sys_write(sender, (int)mr[0], (void *)mr[1], (int)mr[2]);
|
||||
break;
|
||||
|
||||
case L4_IPC_TAG_CLOSE:
|
||||
sys_close(sender, (int)mr[0]);
|
||||
break;
|
||||
|
||||
case L4_IPC_TAG_FSYNC:
|
||||
sys_fsync(sender, (int)mr[0]);
|
||||
break;
|
||||
|
||||
case L4_IPC_TAG_LSEEK:
|
||||
sys_lseek(sender, (int)mr[0], (off_t)mr[1], (int)mr[2]);
|
||||
break;
|
||||
|
||||
@@ -237,6 +237,31 @@ int vfs_write(unsigned long vnum, unsigned long file_offset,
|
||||
return err;
|
||||
}
|
||||
|
||||
int vfs_close(l4id_t sender, int fd)
|
||||
{
|
||||
int err;
|
||||
|
||||
l4_save_ipcregs();
|
||||
|
||||
write_mr(L4SYS_ARG0, sender);
|
||||
write_mr(L4SYS_ARG1, fd);
|
||||
|
||||
if ((err = l4_sendrecv(VFS_TID, VFS_TID, L4_IPC_TAG_PAGER_CLOSE)) < 0) {
|
||||
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Check if syscall was successful */
|
||||
if ((err = l4_get_retval()) < 0) {
|
||||
printf("%s: Pager to VFS write error: %d.\n", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
l4_restore_ipcregs();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Writes updated file stats back to vfs. (e.g. new file size) */
|
||||
int vfs_update_file_stats(struct vm_file *f)
|
||||
{
|
||||
@@ -255,7 +280,8 @@ int vfs_update_file_stats(struct vm_file *f)
|
||||
|
||||
/* Check if syscall was successful */
|
||||
if ((err = l4_get_retval()) < 0) {
|
||||
printf("%s: Pager to VFS write error: %d.\n", __FUNCTION__, err);
|
||||
printf("%s: Pager to VFS write error: %d.\n",
|
||||
__FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -285,6 +311,7 @@ int write_file_pages(struct vm_file *f, unsigned long pfn_start,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Flush all dirty file pages and update file stats */
|
||||
int flush_file_pages(struct vm_file *f)
|
||||
{
|
||||
write_file_pages(f, 0, __pfn(page_align_up(f->length)));
|
||||
@@ -294,38 +321,67 @@ int flush_file_pages(struct vm_file *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_close(l4id_t sender, int fd)
|
||||
/* Given a task and fd syncs all IO on it */
|
||||
int fsync_common(l4id_t sender, int fd)
|
||||
{
|
||||
struct tcb *task;
|
||||
struct vm_file *f;
|
||||
int retval, err;
|
||||
struct tcb *task;
|
||||
int err;
|
||||
|
||||
/* Get the task */
|
||||
BUG_ON(!(task = find_task(sender)));
|
||||
|
||||
/* Check fd validity */
|
||||
if (fd < 0 || fd > TASK_FILES_MAX || !task->fd[fd].vmfile) {
|
||||
retval = -EBADF;
|
||||
goto out;
|
||||
}
|
||||
if (fd < 0 || fd > TASK_FILES_MAX || !task->fd[fd].vmfile)
|
||||
return -EBADF;
|
||||
|
||||
/* Finish I/O on file */
|
||||
f = task->fd[fd].vmfile;
|
||||
if ((err = flush_file_pages(f)) < 0) {
|
||||
retval = err;
|
||||
goto out;
|
||||
}
|
||||
if ((err = flush_file_pages(f)) < 0)
|
||||
return err;
|
||||
|
||||
out:
|
||||
l4_ipc_return(retval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_fsync(int fd)
|
||||
/* Closes the file descriptor and notifies vfs */
|
||||
int fd_close(l4id_t sender, int fd)
|
||||
{
|
||||
struct tcb *task;
|
||||
int err;
|
||||
|
||||
/* Get the task */
|
||||
BUG_ON(!(task = find_task(sender)));
|
||||
|
||||
if ((err = vfs_close(task->tid, fd)) < 0)
|
||||
return err;
|
||||
|
||||
task->fd[fd].vnum = 0;
|
||||
task->fd[fd].cursor = 0;
|
||||
task->fd[fd].vmfile = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_close(l4id_t sender, int fd)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Sync the file and update stats */
|
||||
if ((err = fsync_common(sender, fd)) < 0) {
|
||||
l4_ipc_return(err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close the file descriptor. */
|
||||
return fd_close(sender, fd);
|
||||
}
|
||||
|
||||
int sys_fsync(l4id_t sender, int fd)
|
||||
{
|
||||
/* Sync the file and update stats */
|
||||
return fsync_common(sender, fd);
|
||||
}
|
||||
|
||||
/* FIXME: Add error handling to this */
|
||||
/* Extends a file's size by adding it new pages */
|
||||
int new_file_pages(struct vm_file *f, unsigned long start, unsigned long end)
|
||||
|
||||
Reference in New Issue
Block a user