diff options
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r-- | fs/nfs/read.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index f856004bb7fa..4ace3c50a8eb 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "internal.h" | 25 | #include "internal.h" |
26 | #include "iostat.h" | 26 | #include "iostat.h" |
27 | #include "fscache.h" | ||
27 | 28 | ||
28 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 29 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
29 | 30 | ||
@@ -111,8 +112,8 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data) | |||
111 | } | 112 | } |
112 | } | 113 | } |
113 | 114 | ||
114 | static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | 115 | int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, |
115 | struct page *page) | 116 | struct page *page) |
116 | { | 117 | { |
117 | LIST_HEAD(one_request); | 118 | LIST_HEAD(one_request); |
118 | struct nfs_page *new; | 119 | struct nfs_page *new; |
@@ -139,6 +140,11 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | |||
139 | 140 | ||
140 | static void nfs_readpage_release(struct nfs_page *req) | 141 | static void nfs_readpage_release(struct nfs_page *req) |
141 | { | 142 | { |
143 | struct inode *d_inode = req->wb_context->path.dentry->d_inode; | ||
144 | |||
145 | if (PageUptodate(req->wb_page)) | ||
146 | nfs_readpage_to_fscache(d_inode, req->wb_page, 0); | ||
147 | |||
142 | unlock_page(req->wb_page); | 148 | unlock_page(req->wb_page); |
143 | 149 | ||
144 | dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", | 150 | dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", |
@@ -510,8 +516,15 @@ int nfs_readpage(struct file *file, struct page *page) | |||
510 | } else | 516 | } else |
511 | ctx = get_nfs_open_context(nfs_file_open_context(file)); | 517 | ctx = get_nfs_open_context(nfs_file_open_context(file)); |
512 | 518 | ||
519 | if (!IS_SYNC(inode)) { | ||
520 | error = nfs_readpage_from_fscache(ctx, inode, page); | ||
521 | if (error == 0) | ||
522 | goto out; | ||
523 | } | ||
524 | |||
513 | error = nfs_readpage_async(ctx, inode, page); | 525 | error = nfs_readpage_async(ctx, inode, page); |
514 | 526 | ||
527 | out: | ||
515 | put_nfs_open_context(ctx); | 528 | put_nfs_open_context(ctx); |
516 | return error; | 529 | return error; |
517 | out_unlock: | 530 | out_unlock: |
@@ -584,6 +597,15 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
584 | return -EBADF; | 597 | return -EBADF; |
585 | } else | 598 | } else |
586 | desc.ctx = get_nfs_open_context(nfs_file_open_context(filp)); | 599 | desc.ctx = get_nfs_open_context(nfs_file_open_context(filp)); |
600 | |||
601 | /* attempt to read as many of the pages as possible from the cache | ||
602 | * - this returns -ENOBUFS immediately if the cookie is negative | ||
603 | */ | ||
604 | ret = nfs_readpages_from_fscache(desc.ctx, inode, mapping, | ||
605 | pages, &nr_pages); | ||
606 | if (ret == 0) | ||
607 | goto read_complete; /* all pages were read */ | ||
608 | |||
587 | if (rsize < PAGE_CACHE_SIZE) | 609 | if (rsize < PAGE_CACHE_SIZE) |
588 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); | 610 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); |
589 | else | 611 | else |
@@ -594,6 +616,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
594 | nfs_pageio_complete(&pgio); | 616 | nfs_pageio_complete(&pgio); |
595 | npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 617 | npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
596 | nfs_add_stats(inode, NFSIOS_READPAGES, npages); | 618 | nfs_add_stats(inode, NFSIOS_READPAGES, npages); |
619 | read_complete: | ||
597 | put_nfs_open_context(desc.ctx); | 620 | put_nfs_open_context(desc.ctx); |
598 | out: | 621 | out: |
599 | return ret; | 622 | return ret; |