diff --git a/tasks/fs0/include/memfs/memfs.h b/tasks/fs0/include/memfs/memfs.h index 79c3ed3..6b1eb47 100644 --- a/tasks/fs0/include/memfs/memfs.h +++ b/tasks/fs0/include/memfs/memfs.h @@ -86,8 +86,6 @@ extern struct vnode_ops memfs_vnode_operations; extern struct superblock_ops memfs_superblock_operations; extern struct file_ops memfs_file_operations; -extern struct memfs_superblock *memfs_superblock; - int memfs_format_filesystem(void *buffer); struct memfs_inode *memfs_create_inode(struct memfs_superblock *sb); void memfs_register_fstype(struct list_head *); diff --git a/tasks/fs0/include/vfs.h b/tasks/fs0/include/vfs.h index 3d55d14..6b9122a 100644 --- a/tasks/fs0/include/vfs.h +++ b/tasks/fs0/include/vfs.h @@ -27,19 +27,18 @@ extern struct list_head dentry_cache; * Normally mm0 tracks all vnode pages, but this is used to track pages in * directory vnodes, which are normally never mapped by tasks. */ -extern struct memfs_superblock *memfs_superblock; -static inline void *vfs_alloc_dirpage(void) +static inline void *vfs_alloc_dirpage(struct vnode *v) { /* * Urgh, we allocate from the block cache of memfs to store generic vfs directory * pages. This is currently the quickest we can allocate page-aligned memory. */ - return memfs_alloc_block(memfs_superblock); + return memfs_alloc_block(v->sb->fs_super); } -static inline void vfs_free_dirpage(void *block) +static inline void vfs_free_dirpage(struct vnode *v, void *block) { - memfs_free_block(memfs_superblock, block); + memfs_free_block(v->sb->fs_super, block); } static inline struct dentry *vfs_alloc_dentry(void) diff --git a/tasks/fs0/src/memfs/file.c b/tasks/fs0/src/memfs/file.c index 2315f53..d9560fa 100644 --- a/tasks/fs0/src/memfs/file.c +++ b/tasks/fs0/src/memfs/file.c @@ -52,11 +52,12 @@ int memfs_write_block(struct vnode *v, int blknum, void *buf) * this use, its meant for retrieving an unknown inode under the vnode with valid vnum. * here we already have the inode. */ -int memfs_file_read_write(struct vnode *v, unsigned long pfn, - unsigned long npages, void *buf, int wr) +int memfs_file_read_write(struct vnode *v, unsigned int pfn, + unsigned int npages, void *buf, int wr) { struct memfs_inode *i; struct memfs_superblock *memfs_sb; + unsigned int start, end, count; u32 blocksize; /* Don't support different block and page sizes for now */ @@ -79,17 +80,16 @@ int memfs_file_read_write(struct vnode *v, unsigned long pfn, /* Read-specific operations */ if (!wr) { - /* Check if read is beyond EOF */ - if ((pfn + npages) > __pfn(v->size)) { - printf("%s: Trying to read beyond end of file: %x-%x\n", - __FUNCTION__, pfn, pfn + npages); - return -EINVAL; /* Same error that posix llseek returns */ - } + /* Find read boundaries from expected range and file's current range */ + start = pfn < __pfn(v->size) ? pfn : __pfn(v->size); + end = pfn + npages < __pfn(v->size) ? pfn + npages : __pfn(v->size); + count = end - start; /* Copy the data from inode blocks into page buffer */ - for (int x = pfn, bufpage = 0; x < pfn + npages; x++, bufpage++) + for (int x = start, bufpage = 0; x < end; x++, bufpage++) memcpy(((void *)buf) + (bufpage * blocksize), &i->block[x], blocksize); + return (int)(count * blocksize); } else { /* Write-specific operations */ /* Is the write beyond current file size? */ if (v->size < ((pfn + npages) * (blocksize))) { @@ -121,8 +121,7 @@ int memfs_file_read_write(struct vnode *v, unsigned long pfn, for (int x = pfn, bufpage = 0; x < pfn + npages; x++, bufpage++) memcpy(i->block[x], ((void *)buf) + (bufpage * blocksize), blocksize); } - - return npages * blocksize; + return (int)(npages * blocksize); } int memfs_file_write(struct vnode *v, unsigned long pfn, unsigned long npages, void *buf) diff --git a/tasks/fs0/src/memfs/vnode.c b/tasks/fs0/src/memfs/vnode.c index 12ddf1e..e26c5c7 100644 --- a/tasks/fs0/src/memfs/vnode.c +++ b/tasks/fs0/src/memfs/vnode.c @@ -127,6 +127,7 @@ struct vnode *memfs_alloc_vnode(struct superblock *sb) /* Associate memfs-specific fields with vnode */ v->ops = memfs_vnode_operations; v->fops = memfs_file_operations; + v->sb = sb; /* Return the vnode */ return v; @@ -315,7 +316,10 @@ int memfs_vnode_readdir(struct vnode *v) return 0; /* This is as big as a page */ - v->dirbuf.buffer = vfs_alloc_dirpage(); + if (IS_ERR(v->dirbuf.buffer = vfs_alloc_dirpage(v))) { + printf("%s: Could not allocate dirbuf.\n", __FUNCTION__); + return (int)v->dirbuf.buffer; + } v->dirbuf.npages = 1; /* diff --git a/tasks/fs0/src/syscalls.c b/tasks/fs0/src/syscalls.c index 2d7b617..f3e8069 100644 --- a/tasks/fs0/src/syscalls.c +++ b/tasks/fs0/src/syscalls.c @@ -277,6 +277,7 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count) if (count < dirent_size) return 0; + printf("%s: Filling in . (curdir)\n", __TASKNAME__); fill_dirent(buf, v->vnum, nbytes, "."); nbytes += dirent_size; buf += dirent_size; @@ -285,11 +286,13 @@ int sys_readdir(l4id_t sender, int fd, void *buf, int count) if (count < dirent_size) return 0; + printf("%s: Filling in .. (pardir)\n", __TASKNAME__); fill_dirent(buf, d->parent->vnode->vnum, nbytes, ".."); nbytes += dirent_size; buf += dirent_size; count -= dirent_size; + printf("%s: Filling in other dir contents\n", __TASKNAME__); /* Copy fs-specific dir to buf in struct dirent format */ if ((total = v->ops.filldir(buf, v, count)) < 0) { l4_ipc_return(total);