mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Added syscall to update filestats (size) from pager.
After flushing written/truncated pages, stats are updated so that vfs is synced with new file info such as its size.
This commit is contained in:
@@ -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__ */
|
||||
|
||||
@@ -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__,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user