aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-04-02 18:48:28 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-05-01 01:17:05 -0400
commit8b09bee3083897e375bd0bf9d60f48daedfab3e0 (patch)
tree5122ee611fc46799660db63442107e5677234266
parentbcb71bba7e64f0442d0ca339d7d3117a7060589f (diff)
NFS: Cleanup for nfs_readpages()
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>
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/read.c47
-rw-r--r--include/linux/nfs_page.h2
3 files changed, 19 insertions, 34 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 528128545d66..094537ddd344 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -342,8 +342,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
342 * Returns true if the request 'req' was successfully coalesced into the 342 * Returns true if the request 'req' was successfully coalesced into the
343 * existing list of pages 'desc'. 343 * existing list of pages 'desc'.
344 */ 344 */
345static int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, 345int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
346 struct nfs_page *req) 346 struct nfs_page *req)
347{ 347{
348 while (!nfs_pageio_do_add_request(desc, req)) { 348 while (!nfs_pageio_do_add_request(desc, req)) {
349 nfs_pageio_doio(desc); 349 nfs_pageio_doio(desc);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 0effa74992df..f0016062340d 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -321,28 +321,6 @@ out_bad:
321 return -ENOMEM; 321 return -ENOMEM;
322} 322}
323 323
324static int
325nfs_pagein_list(struct inode *inode, struct list_head *head, unsigned int rsize)
326{
327 struct nfs_pageio_descriptor desc;
328 unsigned int pages = 0;
329 int error = 0;
330
331 if (rsize < PAGE_CACHE_SIZE)
332 nfs_pageio_init(&desc, inode, nfs_pagein_multi, rsize, 0);
333 else
334 nfs_pageio_init(&desc, inode, nfs_pagein_one, rsize, 0);
335
336 nfs_pageio_add_list(&desc, head);
337 nfs_pageio_complete(&desc);
338 pages += (desc.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
339
340 nfs_async_read_error(head);
341 if (error >= 0)
342 return pages;
343 return error;
344}
345
346/* 324/*
347 * This is the callback from RPC telling us whether a reply was 325 * This is the callback from RPC telling us whether a reply was
348 * received or some error occurred (timeout or socket shutdown). 326 * received or some error occurred (timeout or socket shutdown).
@@ -532,7 +510,7 @@ out_error:
532} 510}
533 511
534struct nfs_readdesc { 512struct nfs_readdesc {
535 struct list_head *head; 513 struct nfs_pageio_descriptor *pgio;
536 struct nfs_open_context *ctx; 514 struct nfs_open_context *ctx;
537}; 515};
538 516
@@ -556,19 +534,21 @@ readpage_async_filler(void *data, struct page *page)
556 } 534 }
557 if (len < PAGE_CACHE_SIZE) 535 if (len < PAGE_CACHE_SIZE)
558 memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); 536 memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
559 nfs_list_add_request(new, desc->head); 537 nfs_pageio_add_request(desc->pgio, new);
560 return 0; 538 return 0;
561} 539}
562 540
563int nfs_readpages(struct file *filp, struct address_space *mapping, 541int nfs_readpages(struct file *filp, struct address_space *mapping,
564 struct list_head *pages, unsigned nr_pages) 542 struct list_head *pages, unsigned nr_pages)
565{ 543{
566 LIST_HEAD(head); 544 struct nfs_pageio_descriptor pgio;
567 struct nfs_readdesc desc = { 545 struct nfs_readdesc desc = {
568 .head = &head, 546 .pgio = &pgio,
569 }; 547 };
570 struct inode *inode = mapping->host; 548 struct inode *inode = mapping->host;
571 struct nfs_server *server = NFS_SERVER(inode); 549 struct nfs_server *server = NFS_SERVER(inode);
550 size_t rsize = server->rsize;
551 unsigned long npages;
572 int ret = -ESTALE; 552 int ret = -ESTALE;
573 553
574 dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", 554 dprintk("NFS: nfs_readpages (%s/%Ld %d)\n",
@@ -587,13 +567,16 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
587 } else 567 } else
588 desc.ctx = get_nfs_open_context((struct nfs_open_context *) 568 desc.ctx = get_nfs_open_context((struct nfs_open_context *)
589 filp->private_data); 569 filp->private_data);
570 if (rsize < PAGE_CACHE_SIZE)
571 nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
572 else
573 nfs_pageio_init(&pgio, inode, nfs_pagein_one, rsize, 0);
574
590 ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); 575 ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
591 if (!list_empty(&head)) { 576
592 int err = nfs_pagein_list(inode, &head, server->rsize); 577 nfs_pageio_complete(&pgio);
593 if (!ret) 578 npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
594 nfs_add_stats(inode, NFSIOS_READPAGES, err); 579 nfs_add_stats(inode, NFSIOS_READPAGES, npages);
595 ret = err;
596 }
597 put_nfs_open_context(desc.ctx); 580 put_nfs_open_context(desc.ctx);
598out: 581out:
599 return ret; 582 return ret;
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 91c7b18c47d8..b8b7bca3bac8 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -82,6 +82,8 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
82 int (*doio)(struct inode *, struct list_head *, size_t, int), 82 int (*doio)(struct inode *, struct list_head *, size_t, int),
83 size_t bsize, 83 size_t bsize,
84 int how); 84 int how);
85extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
86 struct nfs_page *);
85extern void nfs_pageio_add_list(struct nfs_pageio_descriptor *, 87extern void nfs_pageio_add_list(struct nfs_pageio_descriptor *,
86 struct list_head *); 88 struct list_head *);
87extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc); 89extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);