diff options
author | Fred Isaman <iisaman@netapp.com> | 2011-02-28 20:34:15 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-11 15:38:42 -0500 |
commit | bae724ef95b0d0a1f4518f5451e7c8aabc41f820 (patch) | |
tree | 07a2c1866698f183235f7133ac7c004121717bf8 /fs/nfs/read.c | |
parent | 94ad1c80e28f9700c84b4d28d1e5302ddf63a6fd (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.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 2a2765975e1f..6dc9eaf00e5c 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 | ||
32 | static int nfs_pagein_multi(struct inode *, struct list_head *, unsigned int, size_t, int); | 32 | static int nfs_pagein_multi(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *); |
33 | static int nfs_pagein_one(struct inode *, struct list_head *, unsigned int, size_t, int); | 33 | static int nfs_pagein_one(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *); |
34 | static const struct rpc_call_ops nfs_read_partial_ops; | 34 | static const struct rpc_call_ops nfs_read_partial_ops; |
35 | static const struct rpc_call_ops nfs_read_full_ops; | 35 | static 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 | ||
70 | static void nfs_readdata_release(struct nfs_read_data *rdata) | 70 | static 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 | */ |
161 | static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | 161 | static 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 | */ |
243 | static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags) | 245 | static 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 | ||
303 | static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags) | 308 | static 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); |
325 | out_bad: | 334 | out: |
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); |