diff --git a/tasks/fs0/include/syscalls.h b/tasks/fs0/include/syscalls.h index 3b6a078..a375957 100644 --- a/tasks/fs0/include/syscalls.h +++ b/tasks/fs0/include/syscalls.h @@ -18,4 +18,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_update_stats(l4id_t sender, unsigned long vnum, + unsigned long newsize); #endif /* __FS0_SYSCALLS_H__ */ diff --git a/tasks/fs0/main.c b/tasks/fs0/main.c index f8e5bb8..d76ee2b 100644 --- a/tasks/fs0/main.c +++ b/tasks/fs0/main.c @@ -92,6 +92,11 @@ 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_UPDATE_STATS: + pager_update_stats(sender, (unsigned long)mr[0], + (unsigned long)mr[1]); + break; + default: printf("%s: Unrecognised ipc tag (%d) " "received from tid: %d. Ignoring.\n", __TASKNAME__, diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index f63d595..447c8b8 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -259,6 +259,31 @@ out: return 0; } +int pager_update_stats(l4id_t sender, unsigned long vnum, + unsigned long newsize) +{ + struct vnode *v; + int retval = 0; + + if (sender != PAGER_TID) { + retval = -EINVAL; + goto out; + } + + /* Lookup vnode */ + if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum))) { + retval = -EINVAL; /* No such vnode */ + goto out; + } + + v->size = newsize; + v->sb->ops->write_vnode(v->sb, v); + +out: + l4_ipc_return(retval); + return 0; +} + /* * This can be solely called by the pager and is not the posix write call. * That call is in the pager. This writes the dirty pages of a file @@ -271,7 +296,6 @@ int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset, { struct vnode *v; int err, retval = 0; - int bytes = 0; if (sender != PAGER_TID) { retval = -EINVAL; @@ -290,17 +314,16 @@ int pager_sys_write(l4id_t sender, unsigned long vnum, unsigned long f_offset, goto out; } - /* If the file is extended, write automatically extends it */ + /* + * If the file is extended, write silently extends it. + * 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; } - /* FIXME: Find a way to properly update new bytes */ - BUG(); - v->size += bytes; - v->sb->ops->write_vnode(v->sb, v); - out: l4_ipc_return(retval); return 0; diff --git a/tasks/libl4/include/l4lib/ipcdefs.h b/tasks/libl4/include/l4lib/ipcdefs.h index c8e94b9..d0573de 100644 --- a/tasks/libl4/include/l4lib/ipcdefs.h +++ b/tasks/libl4/include/l4lib/ipcdefs.h @@ -49,5 +49,6 @@ #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 */ #endif /* __IPCDEFS_H__ */ diff --git a/tasks/mm0/src/file.c b/tasks/mm0/src/file.c index 23d8aa8..3946815 100644 --- a/tasks/mm0/src/file.c +++ b/tasks/mm0/src/file.c @@ -237,6 +237,34 @@ int vfs_write(unsigned long vnum, unsigned long file_offset, return err; } +/* Writes updated file stats back to vfs. (e.g. new file size) */ +int vfs_update_file_stats(struct vm_file *f) +{ + int err; + + l4_save_ipcregs(); + + write_mr(L4SYS_ARG0, vm_file_to_vnum(f)); + write_mr(L4SYS_ARG1, f->length); + + if ((err = l4_sendrecv(VFS_TID, VFS_TID, + L4_IPC_TAG_PAGER_UPDATE_STATS)) < 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 pages in cache back to their file */ int write_file_pages(struct vm_file *f, unsigned long pfn_start, unsigned long pfn_end) @@ -261,6 +289,8 @@ int flush_file_pages(struct vm_file *f) { write_file_pages(f, 0, __pfn(page_align_up(f->length))); + vfs_update_file_stats(f); + return 0; } diff --git a/tools/tagsgen/tagsgen_all b/tools/tagsgen/tagsgen_all index d07201c..ec62242 100755 --- a/tools/tagsgen/tagsgen_all +++ b/tools/tagsgen/tagsgen_all @@ -11,6 +11,7 @@ find ./ -name '*.lds' >> tagfilelist # Use file list to include in tags. ctags --languages=C,C++,Asm --recurse -Ltagfilelist +exuberant-ctags --languages=C,C++,Asm --recurse -Ltagfilelist cscope -q -k -R -i tagfilelist # Remove file list.