NFS: Cleanup: add common helper nfs_page_length()
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 5 Dec 2006 05:35:38 +0000 (00:35 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 6 Dec 2006 15:46:36 +0000 (10:46 -0500)
Clean up a lot of ad-hoc page length calculations in fs/nfs/write.c

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/internal.h
fs/nfs/read.c
fs/nfs/write.c

index d205466..a28f6ce 100644 (file)
@@ -217,3 +217,21 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
        if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
                sb->s_maxbytes = MAX_LFS_FILESIZE;
 }
+
+/*
+ * Determine the number of bytes of data the page contains
+ */
+static inline
+unsigned int nfs_page_length(struct page *page)
+{
+       loff_t i_size = i_size_read(page->mapping->host);
+
+       if (i_size > 0) {
+               pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;
+               if (page->index < end_index)
+                       return PAGE_CACHE_SIZE;
+               if (page->index == end_index)
+                       return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1;
+       }
+       return 0;
+}
index cca9fa2..05cca66 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <asm/system.h>
 
+#include "internal.h"
 #include "iostat.h"
 
 #define NFSDBG_FACILITY                NFSDBG_PAGECACHE
@@ -83,22 +84,6 @@ void nfs_readdata_release(void *data)
         nfs_readdata_free(data);
 }
 
-static
-unsigned int nfs_page_length(struct inode *inode, struct page *page)
-{
-       loff_t i_size = i_size_read(inode);
-       unsigned long idx;
-
-       if (i_size <= 0)
-               return 0;
-       idx = (i_size - 1) >> PAGE_CACHE_SHIFT;
-       if (page->index > idx)
-               return 0;
-       if (page->index != idx)
-               return PAGE_CACHE_SIZE;
-       return 1 + ((i_size - 1) & (PAGE_CACHE_SIZE - 1));
-}
-
 static
 int nfs_return_empty_page(struct page *page)
 {
@@ -231,7 +216,7 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
        struct nfs_page *new;
        unsigned int len;
 
-       len = nfs_page_length(inode, page);
+       len = nfs_page_length(page);
        if (len == 0)
                return nfs_return_empty_page(page);
        new = nfs_create_request(ctx, inode, page, 0, len);
@@ -667,7 +652,7 @@ readpage_async_filler(void *data, struct page *page)
        unsigned int len;
 
        nfs_wb_page(inode, page);
-       len = nfs_page_length(inode, page);
+       len = nfs_page_length(page);
        if (len == 0)
                return nfs_return_empty_page(page);
        new = nfs_create_request(desc->ctx, inode, page, 0, len);
index 6df8319..3f6ca52 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/smp_lock.h>
 
 #include "delegation.h"
+#include "internal.h"
 #include "iostat.h"
 
 #define NFSDBG_FACILITY                NFSDBG_PAGECACHE
@@ -199,30 +200,15 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
  */
 static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count)
 {
-       loff_t end_offs;
-
        if (PageUptodate(page))
                return;
        if (base != 0)
                return;
-       if (count == PAGE_CACHE_SIZE) {
-               SetPageUptodate(page);
-               return;
-       }
-
-       end_offs = i_size_read(page->mapping->host) - 1;
-       if (end_offs < 0)
-               return;
-       /* Is this the last page? */
-       if (page->index != (unsigned long)(end_offs >> PAGE_CACHE_SHIFT))
+       if (count != nfs_page_length(page))
                return;
-       /* This is the last page: set PG_uptodate if we cover the entire
-        * extent of the data, then zero the rest of the page.
-        */
-       if (count == (unsigned int)(end_offs & (PAGE_CACHE_SIZE - 1)) + 1) {
+       if (count != PAGE_CACHE_SIZE)
                memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count);
-               SetPageUptodate(page);
-       }
+       SetPageUptodate(page);
 }
 
 /*
@@ -330,9 +316,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct nfs_open_context *ctx;
        struct inode *inode = page->mapping->host;
-       unsigned long end_index;
-       unsigned offset = PAGE_CACHE_SIZE;
-       loff_t i_size = i_size_read(inode);
+       unsigned offset;
        int inode_referenced = 0;
        int priority = wb_priority(wbc);
        int err;
@@ -350,22 +334,15 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
         */
        if (igrab(inode) != 0)
                inode_referenced = 1;
-       end_index = i_size >> PAGE_CACHE_SHIFT;
 
        /* Ensure we've flushed out any previous writes */
        nfs_wb_page_priority(inode, page, priority);
 
-       /* easy case */
-       if (page->index < end_index)
-               goto do_it;
-       /* things got complicated... */
-       offset = i_size & (PAGE_CACHE_SIZE-1);
-
-       /* OK, are we completely out? */
-       err = 0; /* potential race with truncate - ignore */
-       if (page->index >= end_index+1 || !offset)
+       err = 0;
+       offset = nfs_page_length(page);
+       if (!offset)
                goto out;
-do_it:
+
        ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
        if (ctx == NULL) {
                err = -EBADF;
@@ -826,20 +803,8 @@ int nfs_updatepage(struct file *file, struct page *page,
         * fragmenting write requests.
         */
        if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
-               loff_t end_offs = i_size_read(inode) - 1;
-               unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT;
-
-               count += offset;
+               count = max(count + offset, nfs_page_length(page));
                offset = 0;
-               if (unlikely(end_offs < 0)) {
-                       /* Do nothing */
-               } else if (page->index == end_index) {
-                       unsigned int pglen;
-                       pglen = (unsigned int)(end_offs & (PAGE_CACHE_SIZE-1)) + 1;
-                       if (count < pglen)
-                               count = pglen;
-               } else if (page->index < end_index)
-                       count = PAGE_CACHE_SIZE;
        }
 
        /*