Fixes elf panic
[akaros.git] / kern / src / kfs.c
index 14fea7b..4584312 100644 (file)
@@ -137,27 +137,30 @@ int kfs_readpage(struct page_map *pm, struct page *page)
                memset(page2kva(page) + copy_amt, 0, PGSIZE - copy_amt);
        }
        struct buffer_head *bh = kmem_cache_alloc(bh_kcache, 0);
-       if (!bh) {
-               unlock_page(page);
+       if (!bh)
                return -1;                      /* untested, un-thought-through */
-       }
+       atomic_or(&page->pg_flags, PG_BUFFER);
        /* KFS does a 1:1 BH to page mapping */
        bh->bh_page = page;                                                             /* weak ref */
        bh->bh_buffer = page2kva(page);
        bh->bh_flags = 0;                                                               /* whatever... */
        bh->bh_next = 0;                                                                /* only one BH needed */
        bh->bh_bdev = pm->pm_host->i_sb->s_bdev;                /* uncounted */
-       bh->bh_blocknum = page->pg_index;
-       bh->bh_numblock = 1;                                                    /* sector size = PGSIZE */
+       bh->bh_sector = page->pg_index;
+       bh->bh_nr_sector = 1;                                                   /* sector size = PGSIZE */
        page->pg_private = bh;
        /* This is supposed to be done in the IO system when the operation is
         * complete.  Since we aren't doing a real IO request, and it is already
         * done, we can do it here. */
-       page->pg_flags |= PG_UPTODATE;
-       unlock_page(page);
+       atomic_or(&page->pg_flags, PG_UPTODATE);
        return 0;
 }
 
+int kfs_writepage(struct page_map *pm, struct page *page)
+{
+       return -1;
+}
+
 /* Super Operations */
 
 /* Creates and initializes a new inode.  FS specific, yet inode-generic fields
@@ -176,6 +179,7 @@ struct inode *kfs_alloc_inode(struct super_block *sb)
        inode->i_fs_info = kmem_cache_alloc(kfs_i_kcache, 0);
        TAILQ_INIT(&((struct kfs_i_info*)inode->i_fs_info)->children);
        ((struct kfs_i_info*)inode->i_fs_info)->filestart = 0;
+       ((struct kfs_i_info*)inode->i_fs_info)->init_size = 0;
        return inode;
 }
 
@@ -337,6 +341,8 @@ struct dentry *kfs_lookup(struct inode *dir, struct dentry *dentry,
        struct dentry *d_i;
 
        assert(dir_dent && dir_dent == TAILQ_LAST(&dir->i_dentry, dentry_tailq));
+       /* had this fail when kern/kfs has a symlink go -> ../../../go, though
+        * a symlink like lib2 -> lib work okay. */
        assert(S_ISDIR(dir->i_mode));
        assert(kref_refcnt(&dentry->d_kref) == 1);
        TAILQ_FOREACH(d_i, &dir_dent->d_subdirs, d_subdirs_link) {
@@ -438,7 +444,7 @@ int kfs_rmdir(struct inode *dir, struct dentry *dentry)
        if (!empty)
                return -ENOTEMPTY;
        kref_put(&dentry->d_kref);                              /* unpin the dentry, KFS-style */
-       printk("DENTRY %s REFCNT %d\n", dentry->d_name.name, kref_refcnt(&dentry->d_kref));
+       printd("DENTRY %s REFCNT %d\n", dentry->d_name.name, kref_refcnt(&dentry->d_kref));
        return 0;
 }
 
@@ -526,9 +532,9 @@ void kfs_d_iput(struct dentry *dentry, struct inode *inode)
 
 /* Updates the file pointer.  KFS doesn't let you go past the end of a file
  * yet, so it won't let you seek past either.  TODO: think about locking. */
-off_t kfs_llseek(struct file *file, off_t offset, int whence)
+int kfs_llseek(struct file *file, off64_t offset, off64_t *ret, int whence)
 {
-       off_t temp_off = 0;
+       off64_t temp_off = 0;
        switch (whence) {
                case SEEK_SET:
                        temp_off = offset;
@@ -548,7 +554,8 @@ off_t kfs_llseek(struct file *file, off_t offset, int whence)
         * techincally, if they go too far, we should return EINVAL */
        temp_off = MAX(MIN(temp_off, file->f_dentry->d_inode->i_size), 0);
        file->f_pos = temp_off;
-       return temp_off;
+       *ret = temp_off;
+       return 0;
 }
 
 /* Fills in the next directory entry (dirent), starting with d_off.  KFS treats
@@ -658,7 +665,7 @@ unsigned int kfs_poll(struct file *file, struct poll_table_struct *poll_table)
 /* Reads count bytes from a file, starting from (and modifiying) offset, and
  * putting the bytes into buffers described by vector */
 ssize_t kfs_readv(struct file *file, const struct iovec *vector,
-                  unsigned long count, off_t *offset)
+                  unsigned long count, off64_t *offset)
 {
        return -1;
 }
@@ -666,14 +673,14 @@ ssize_t kfs_readv(struct file *file, const struct iovec *vector,
 /* Writes count bytes to a file, starting from (and modifiying) offset, and
  * taking the bytes from buffers described by vector */
 ssize_t kfs_writev(struct file *file, const struct iovec *vector,
-                  unsigned long count, off_t *offset)
+                  unsigned long count, off64_t *offset)
 {
        return -1;
 }
 
 /* Write the contents of file to the page.  Will sort the params later */
 ssize_t kfs_sendpage(struct file *file, struct page *page, int offset,
-                     size_t size, off_t pos, int more)
+                     size_t size, off64_t pos, int more)
 {
        return -1;
 }
@@ -687,6 +694,7 @@ int kfs_check_flags(int flags)
 /* Redeclaration and initialization of the FS ops structures */
 struct page_map_operations kfs_pm_op = {
        kfs_readpage,
+       kfs_writepage,
 };
 
 struct super_operations kfs_s_op = {
@@ -916,7 +924,7 @@ void parse_cpio_entries(struct super_block *sb, void *cpio_b)
                }
                c_bhdr->c_filename = (char*)c_hdr + sizeof(*c_hdr);
                namesize = cpio_strntol(buf, c_hdr->c_namesize, 8);
-               printd("Namesize: %d\n", size);
+               printd("Namesize: %d\n", namesize);
                if (!strcmp(c_bhdr->c_filename, "TRAILER!!!"))
                        break;
                c_bhdr->c_ino = cpio_strntol(buf, c_hdr->c_ino, 8);