romfs_readpage: don't report errors for pages beyond i_size
[pandora-kernel.git] / fs / romfs / inode.c
index 00b6f0a..60d2f82 100644 (file)
@@ -340,8 +340,9 @@ static struct dentry *
 romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
        unsigned long offset, maxoff;
-       int fslen, res;
-       struct inode *inode;
+       long res;
+       int fslen;
+       struct inode *inode = NULL;
        char fsname[ROMFS_MAXFN];       /* XXX dynamic? */
        struct romfs_inode ri;
        const char *name;               /* got from dentry */
@@ -351,7 +352,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        offset = dir->i_ino & ROMFH_MASK;
        lock_kernel();
        if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
-               goto out;
+               goto error;
 
        maxoff = romfs_maxsize(dir->i_sb);
        offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
@@ -364,9 +365,9 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 
        for(;;) {
                if (!offset || offset >= maxoff)
-                       goto out0;
+                       goto success; /* negative success */
                if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
-                       goto out;
+                       goto error;
 
                /* try to match the first 16 bytes of name */
                fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE);
@@ -397,23 +398,14 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        inode = romfs_iget(dir->i_sb, offset);
        if (IS_ERR(inode)) {
                res = PTR_ERR(inode);
-               goto out;
+               goto error;
        }
 
-       /*
-        * it's a bit funky, _lookup needs to return an error code
-        * (negative) or a NULL, both as a dentry.  ENOENT should not
-        * be returned, instead we need to create a negative dentry by
-        * d_add(dentry, NULL); and return 0 as no error.
-        * (Although as I see, it only matters on writable file
-        * systems).
-        */
-
-out0:  inode = NULL;
+success:
+       d_add(dentry, inode);
        res = 0;
-       d_add (dentry, inode);
-
-out:   unlock_kernel();
+error:
+       unlock_kernel();
        return ERR_PTR(res);
 }
 
@@ -426,7 +418,8 @@ static int
 romfs_readpage(struct file *file, struct page * page)
 {
        struct inode *inode = page->mapping->host;
-       loff_t offset, avail, readlen;
+       loff_t offset, size;
+       unsigned long filled;
        void *buf;
        int result = -EIO;
 
@@ -438,21 +431,29 @@ romfs_readpage(struct file *file, struct page * page)
 
        /* 32 bit warning -- but not for us :) */
        offset = page_offset(page);
-       if (offset < i_size_read(inode)) {
-               avail = inode->i_size-offset;
-               readlen = min_t(unsigned long, avail, PAGE_SIZE);
-               if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) {
-                       if (readlen < PAGE_SIZE) {
-                               memset(buf + readlen,0,PAGE_SIZE-readlen);
-                       }
-                       SetPageUptodate(page);
-                       result = 0;
+       size = i_size_read(inode);
+       filled = 0;
+       result = 0;
+       if (offset < size) {
+               unsigned long readlen;
+
+               size -= offset;
+               readlen = size > PAGE_SIZE ? PAGE_SIZE : size;
+
+               filled = romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen);
+
+               if (filled != readlen) {
+                       SetPageError(page);
+                       filled = 0;
+                       result = -EIO;
                }
        }
-       if (result) {
-               memset(buf, 0, PAGE_SIZE);
-               SetPageError(page);
-       }
+
+       if (filled < PAGE_SIZE)
+               memset(buf + filled, 0, PAGE_SIZE-filled);
+
+       if (!result)
+               SetPageUptodate(page);
        flush_dcache_page(page);
 
        unlock_page(page);
@@ -585,7 +586,7 @@ static void romfs_destroy_inode(struct inode *inode)
        kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));
 }
 
-static void init_once(struct kmem_cache *cachep, void *foo)
+static void init_once(void *foo)
 {
        struct romfs_inode_info *ei = foo;