NFS: Cleanup for nfs_readpages()
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 2 Apr 2007 22:48:28 +0000 (18:48 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 1 May 2007 05:17:05 +0000 (22:17 -0700)
Do the coalescing of read requests into block sized requests at start of
I/O as we scan through the pages instead of going through a second pass.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/pagelist.c
fs/nfs/read.c
include/linux/nfs_page.h

index 528128545d66b105268e95503211d4d0360356b9..094537ddd344cf296368fb5b689d16a18c96b1f4 100644 (file)
@@ -342,8 +342,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
  * Returns true if the request 'req' was successfully coalesced into the
  * existing list of pages 'desc'.
  */
-static int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
-                                 struct nfs_page *req)
+int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
+                          struct nfs_page *req)
 {
        while (!nfs_pageio_do_add_request(desc, req)) {
                nfs_pageio_doio(desc);
index 0effa74992df503ce0d7bf9b6e3789a4f1a5d0fa..f0016062340dac58357d4ea15a9ca6fdbd402002 100644 (file)
@@ -321,28 +321,6 @@ out_bad:
        return -ENOMEM;
 }
 
-static int
-nfs_pagein_list(struct inode *inode, struct list_head *head, unsigned int rsize)
-{
-       struct nfs_pageio_descriptor desc;
-       unsigned int pages = 0;
-       int error = 0;
-
-       if (rsize < PAGE_CACHE_SIZE)
-               nfs_pageio_init(&desc, inode, nfs_pagein_multi, rsize, 0);
-       else
-               nfs_pageio_init(&desc, inode, nfs_pagein_one, rsize, 0);
-
-       nfs_pageio_add_list(&desc, head);
-       nfs_pageio_complete(&desc);
-       pages += (desc.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-
-       nfs_async_read_error(head);
-       if (error >= 0)
-               return pages;
-       return error;
-}
-
 /*
  * This is the callback from RPC telling us whether a reply was
  * received or some error occurred (timeout or socket shutdown).
@@ -532,7 +510,7 @@ out_error:
 }
 
 struct nfs_readdesc {
-       struct list_head *head;
+       struct nfs_pageio_descriptor *pgio;
        struct nfs_open_context *ctx;
 };
 
@@ -556,19 +534,21 @@ readpage_async_filler(void *data, struct page *page)
        }
        if (len < PAGE_CACHE_SIZE)
                memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
-       nfs_list_add_request(new, desc->head);
+       nfs_pageio_add_request(desc->pgio, new);
        return 0;
 }
 
 int nfs_readpages(struct file *filp, struct address_space *mapping,
                struct list_head *pages, unsigned nr_pages)
 {
-       LIST_HEAD(head);
+       struct nfs_pageio_descriptor pgio;
        struct nfs_readdesc desc = {
-               .head           = &head,
+               .pgio = &pgio,
        };
        struct inode *inode = mapping->host;
        struct nfs_server *server = NFS_SERVER(inode);
+       size_t rsize = server->rsize;
+       unsigned long npages;
        int ret = -ESTALE;
 
        dprintk("NFS: nfs_readpages (%s/%Ld %d)\n",
@@ -587,13 +567,16 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
        } else
                desc.ctx = get_nfs_open_context((struct nfs_open_context *)
                                filp->private_data);
+       if (rsize < PAGE_CACHE_SIZE)
+               nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
+       else
+               nfs_pageio_init(&pgio, inode, nfs_pagein_one, rsize, 0);
+
        ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
-       if (!list_empty(&head)) {
-               int err = nfs_pagein_list(inode, &head, server->rsize);
-               if (!ret)
-                       nfs_add_stats(inode, NFSIOS_READPAGES, err);
-                       ret = err;
-       }
+
+       nfs_pageio_complete(&pgio);
+       npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+       nfs_add_stats(inode, NFSIOS_READPAGES, npages);
        put_nfs_open_context(desc.ctx);
 out:
        return ret;
index 91c7b18c47d8daad732b62e999f09b0fe65b82f4..b8b7bca3bac89209635ce32d501fc4e428d91b08 100644 (file)
@@ -82,6 +82,8 @@ extern        void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
                             int (*doio)(struct inode *, struct list_head *, size_t, int),
                             size_t bsize,
                             int how);
+extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
+                                  struct nfs_page *);
 extern void nfs_pageio_add_list(struct nfs_pageio_descriptor *,
                                 struct list_head *);
 extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);