aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/read.c
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2011-02-28 20:34:15 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-03-11 15:38:42 -0500
commitbae724ef95b0d0a1f4518f5451e7c8aabc41f820 (patch)
tree07a2c1866698f183235f7133ac7c004121717bf8 /fs/nfs/read.c
parent94ad1c80e28f9700c84b4d28d1e5302ddf63a6fd (diff)
NFSv4.1: shift pnfs_update_layout locations
Move the pnfs_update_layout call location to nfs_pageio_do_add_request(). Grab the lseg sent in the doio function to nfs_read_rpcsetup and attach it to each nfs_read_data so it can be sent to the layout driver. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Andy Adamson <andros@citi.umich.edu> Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com> Signed-off-by: Fred Isaman <iisaman@citi.umich.edu> Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Tao Guo <guotao@nrchpc.ac.cn> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r--fs/nfs/read.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 2a2765975e1..6dc9eaf00e5 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -20,17 +20,17 @@
20#include <linux/nfs_page.h> 20#include <linux/nfs_page.h>
21 21
22#include <asm/system.h> 22#include <asm/system.h>
23#include "pnfs.h"
23 24
24#include "nfs4_fs.h" 25#include "nfs4_fs.h"
25#include "internal.h" 26#include "internal.h"
26#include "iostat.h" 27#include "iostat.h"
27#include "fscache.h" 28#include "fscache.h"
28#include "pnfs.h"
29 29
30#define NFSDBG_FACILITY NFSDBG_PAGECACHE 30#define NFSDBG_FACILITY NFSDBG_PAGECACHE
31 31
32static int nfs_pagein_multi(struct inode *, struct list_head *, unsigned int, size_t, int); 32static int nfs_pagein_multi(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *);
33static int nfs_pagein_one(struct inode *, struct list_head *, unsigned int, size_t, int); 33static int nfs_pagein_one(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *);
34static const struct rpc_call_ops nfs_read_partial_ops; 34static const struct rpc_call_ops nfs_read_partial_ops;
35static const struct rpc_call_ops nfs_read_full_ops; 35static const struct rpc_call_ops nfs_read_full_ops;
36 36
@@ -69,6 +69,7 @@ void nfs_readdata_free(struct nfs_read_data *p)
69 69
70static void nfs_readdata_release(struct nfs_read_data *rdata) 70static void nfs_readdata_release(struct nfs_read_data *rdata)
71{ 71{
72 put_lseg(rdata->lseg);
72 put_nfs_open_context(rdata->args.context); 73 put_nfs_open_context(rdata->args.context);
73 nfs_readdata_free(rdata); 74 nfs_readdata_free(rdata);
74} 75}
@@ -121,7 +122,6 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
121 len = nfs_page_length(page); 122 len = nfs_page_length(page);
122 if (len == 0) 123 if (len == 0)
123 return nfs_return_empty_page(page); 124 return nfs_return_empty_page(page);
124 pnfs_update_layout(inode, ctx, IOMODE_READ);
125 new = nfs_create_request(ctx, inode, page, 0, len); 125 new = nfs_create_request(ctx, inode, page, 0, len);
126 if (IS_ERR(new)) { 126 if (IS_ERR(new)) {
127 unlock_page(page); 127 unlock_page(page);
@@ -132,9 +132,9 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
132 132
133 nfs_list_add_request(new, &one_request); 133 nfs_list_add_request(new, &one_request);
134 if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) 134 if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE)
135 nfs_pagein_multi(inode, &one_request, 1, len, 0); 135 nfs_pagein_multi(inode, &one_request, 1, len, 0, NULL);
136 else 136 else
137 nfs_pagein_one(inode, &one_request, 1, len, 0); 137 nfs_pagein_one(inode, &one_request, 1, len, 0, NULL);
138 return 0; 138 return 0;
139} 139}
140 140
@@ -160,7 +160,8 @@ static void nfs_readpage_release(struct nfs_page *req)
160 */ 160 */
161static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, 161static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
162 const struct rpc_call_ops *call_ops, 162 const struct rpc_call_ops *call_ops,
163 unsigned int count, unsigned int offset) 163 unsigned int count, unsigned int offset,
164 struct pnfs_layout_segment *lseg)
164{ 165{
165 struct inode *inode = req->wb_context->path.dentry->d_inode; 166 struct inode *inode = req->wb_context->path.dentry->d_inode;
166 int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0; 167 int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0;
@@ -183,6 +184,7 @@ static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
183 data->req = req; 184 data->req = req;
184 data->inode = inode; 185 data->inode = inode;
185 data->cred = msg.rpc_cred; 186 data->cred = msg.rpc_cred;
187 data->lseg = get_lseg(lseg);
186 188
187 data->args.fh = NFS_FH(inode); 189 data->args.fh = NFS_FH(inode);
188 data->args.offset = req_offset(req) + offset; 190 data->args.offset = req_offset(req) + offset;
@@ -240,7 +242,7 @@ nfs_async_read_error(struct list_head *head)
240 * won't see the new data until our attribute cache is updated. This is more 242 * won't see the new data until our attribute cache is updated. This is more
241 * or less conventional NFS client behavior. 243 * or less conventional NFS client behavior.
242 */ 244 */
243static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags) 245static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags, struct pnfs_layout_segment *lseg)
244{ 246{
245 struct nfs_page *req = nfs_list_entry(head->next); 247 struct nfs_page *req = nfs_list_entry(head->next);
246 struct page *page = req->wb_page; 248 struct page *page = req->wb_page;
@@ -266,6 +268,8 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
266 } while(nbytes != 0); 268 } while(nbytes != 0);
267 atomic_set(&req->wb_complete, requests); 269 atomic_set(&req->wb_complete, requests);
268 270
271 /* We know lseg==NULL */
272 lseg = pnfs_update_layout(inode, req->wb_context, IOMODE_READ);
269 ClearPageError(page); 273 ClearPageError(page);
270 offset = 0; 274 offset = 0;
271 nbytes = count; 275 nbytes = count;
@@ -280,12 +284,13 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
280 if (nbytes < rsize) 284 if (nbytes < rsize)
281 rsize = nbytes; 285 rsize = nbytes;
282 ret2 = nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, 286 ret2 = nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
283 rsize, offset); 287 rsize, offset, lseg);
284 if (ret == 0) 288 if (ret == 0)
285 ret = ret2; 289 ret = ret2;
286 offset += rsize; 290 offset += rsize;
287 nbytes -= rsize; 291 nbytes -= rsize;
288 } while (nbytes != 0); 292 } while (nbytes != 0);
293 put_lseg(lseg);
289 294
290 return ret; 295 return ret;
291 296
@@ -300,7 +305,7 @@ out_bad:
300 return -ENOMEM; 305 return -ENOMEM;
301} 306}
302 307
303static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags) 308static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags, struct pnfs_layout_segment *lseg)
304{ 309{
305 struct nfs_page *req; 310 struct nfs_page *req;
306 struct page **pages; 311 struct page **pages;
@@ -308,8 +313,10 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
308 int ret = -ENOMEM; 313 int ret = -ENOMEM;
309 314
310 data = nfs_readdata_alloc(npages); 315 data = nfs_readdata_alloc(npages);
311 if (!data) 316 if (!data) {
312 goto out_bad; 317 nfs_async_read_error(head);
318 goto out;
319 }
313 320
314 pages = data->pagevec; 321 pages = data->pagevec;
315 while (!list_empty(head)) { 322 while (!list_empty(head)) {
@@ -320,10 +327,12 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
320 *pages++ = req->wb_page; 327 *pages++ = req->wb_page;
321 } 328 }
322 req = nfs_list_entry(data->pages.next); 329 req = nfs_list_entry(data->pages.next);
330 if ((!lseg) && list_is_singular(&data->pages))
331 lseg = pnfs_update_layout(inode, req->wb_context, IOMODE_READ);
323 332
324 return nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0); 333 ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0, lseg);
325out_bad: 334out:
326 nfs_async_read_error(head); 335 put_lseg(lseg);
327 return ret; 336 return ret;
328} 337}
329 338
@@ -625,7 +634,6 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
625 if (ret == 0) 634 if (ret == 0)
626 goto read_complete; /* all pages were read */ 635 goto read_complete; /* all pages were read */
627 636
628 pnfs_update_layout(inode, desc.ctx, IOMODE_READ);
629 pnfs_pageio_init_read(&pgio, inode); 637 pnfs_pageio_init_read(&pgio, inode);
630 if (rsize < PAGE_CACHE_SIZE) 638 if (rsize < PAGE_CACHE_SIZE)
631 nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); 639 nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);