aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r--fs/nfs/read.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index ae3ddd24cf8f..2da255f0247f 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -36,8 +36,8 @@
36#define NFSDBG_FACILITY NFSDBG_PAGECACHE 36#define NFSDBG_FACILITY NFSDBG_PAGECACHE
37 37
38static int nfs_pagein_one(struct list_head *, struct inode *); 38static int nfs_pagein_one(struct list_head *, struct inode *);
39static void nfs_readpage_result_partial(struct nfs_read_data *, int); 39static const struct rpc_call_ops nfs_read_partial_ops;
40static void nfs_readpage_result_full(struct nfs_read_data *, int); 40static const struct rpc_call_ops nfs_read_full_ops;
41 41
42static kmem_cache_t *nfs_rdata_cachep; 42static kmem_cache_t *nfs_rdata_cachep;
43mempool_t *nfs_rdata_mempool; 43mempool_t *nfs_rdata_mempool;
@@ -200,9 +200,11 @@ static void nfs_readpage_release(struct nfs_page *req)
200 * Set up the NFS read request struct 200 * Set up the NFS read request struct
201 */ 201 */
202static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, 202static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
203 const struct rpc_call_ops *call_ops,
203 unsigned int count, unsigned int offset) 204 unsigned int count, unsigned int offset)
204{ 205{
205 struct inode *inode; 206 struct inode *inode;
207 int flags;
206 208
207 data->req = req; 209 data->req = req;
208 data->inode = inode = req->wb_context->dentry->d_inode; 210 data->inode = inode = req->wb_context->dentry->d_inode;
@@ -220,6 +222,9 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
220 data->res.eof = 0; 222 data->res.eof = 0;
221 nfs_fattr_init(&data->fattr); 223 nfs_fattr_init(&data->fattr);
222 224
225 /* Set up the initial task struct. */
226 flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
227 rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data);
223 NFS_PROTO(inode)->read_setup(data); 228 NFS_PROTO(inode)->read_setup(data);
224 229
225 data->task.tk_cookie = (unsigned long)inode; 230 data->task.tk_cookie = (unsigned long)inode;
@@ -307,14 +312,15 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode)
307 list_del_init(&data->pages); 312 list_del_init(&data->pages);
308 313
309 data->pagevec[0] = page; 314 data->pagevec[0] = page;
310 data->complete = nfs_readpage_result_partial;
311 315
312 if (nbytes > rsize) { 316 if (nbytes > rsize) {
313 nfs_read_rpcsetup(req, data, rsize, offset); 317 nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
318 rsize, offset);
314 offset += rsize; 319 offset += rsize;
315 nbytes -= rsize; 320 nbytes -= rsize;
316 } else { 321 } else {
317 nfs_read_rpcsetup(req, data, nbytes, offset); 322 nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
323 nbytes, offset);
318 nbytes = 0; 324 nbytes = 0;
319 } 325 }
320 nfs_execute_read(data); 326 nfs_execute_read(data);
@@ -360,8 +366,7 @@ static int nfs_pagein_one(struct list_head *head, struct inode *inode)
360 } 366 }
361 req = nfs_list_entry(data->pages.next); 367 req = nfs_list_entry(data->pages.next);
362 368
363 data->complete = nfs_readpage_result_full; 369 nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0);
364 nfs_read_rpcsetup(req, data, count, 0);
365 370
366 nfs_execute_read(data); 371 nfs_execute_read(data);
367 return 0; 372 return 0;
@@ -395,12 +400,15 @@ nfs_pagein_list(struct list_head *head, int rpages)
395/* 400/*
396 * Handle a read reply that fills part of a page. 401 * Handle a read reply that fills part of a page.
397 */ 402 */
398static void nfs_readpage_result_partial(struct nfs_read_data *data, int status) 403static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata)
399{ 404{
405 struct nfs_read_data *data = calldata;
400 struct nfs_page *req = data->req; 406 struct nfs_page *req = data->req;
401 struct page *page = req->wb_page; 407 struct page *page = req->wb_page;
402 408
403 if (status >= 0) { 409 if (nfs_readpage_result(task, data) != 0)
410 return;
411 if (task->tk_status >= 0) {
404 unsigned int request = data->args.count; 412 unsigned int request = data->args.count;
405 unsigned int result = data->res.count; 413 unsigned int result = data->res.count;
406 414
@@ -419,20 +427,28 @@ static void nfs_readpage_result_partial(struct nfs_read_data *data, int status)
419 } 427 }
420} 428}
421 429
430static const struct rpc_call_ops nfs_read_partial_ops = {
431 .rpc_call_done = nfs_readpage_result_partial,
432 .rpc_release = nfs_readdata_release,
433};
434
422/* 435/*
423 * This is the callback from RPC telling us whether a reply was 436 * This is the callback from RPC telling us whether a reply was
424 * received or some error occurred (timeout or socket shutdown). 437 * received or some error occurred (timeout or socket shutdown).
425 */ 438 */
426static void nfs_readpage_result_full(struct nfs_read_data *data, int status) 439static void nfs_readpage_result_full(struct rpc_task *task, void *calldata)
427{ 440{
441 struct nfs_read_data *data = calldata;
428 unsigned int count = data->res.count; 442 unsigned int count = data->res.count;
429 443
444 if (nfs_readpage_result(task, data) != 0)
445 return;
430 while (!list_empty(&data->pages)) { 446 while (!list_empty(&data->pages)) {
431 struct nfs_page *req = nfs_list_entry(data->pages.next); 447 struct nfs_page *req = nfs_list_entry(data->pages.next);
432 struct page *page = req->wb_page; 448 struct page *page = req->wb_page;
433 nfs_list_remove_request(req); 449 nfs_list_remove_request(req);
434 450
435 if (status >= 0) { 451 if (task->tk_status >= 0) {
436 if (count < PAGE_CACHE_SIZE) { 452 if (count < PAGE_CACHE_SIZE) {
437 if (count < req->wb_bytes) 453 if (count < req->wb_bytes)
438 memclear_highpage_flush(page, 454 memclear_highpage_flush(page,
@@ -448,19 +464,27 @@ static void nfs_readpage_result_full(struct nfs_read_data *data, int status)
448 } 464 }
449} 465}
450 466
467static const struct rpc_call_ops nfs_read_full_ops = {
468 .rpc_call_done = nfs_readpage_result_full,
469 .rpc_release = nfs_readdata_release,
470};
471
451/* 472/*
452 * This is the callback from RPC telling us whether a reply was 473 * This is the callback from RPC telling us whether a reply was
453 * received or some error occurred (timeout or socket shutdown). 474 * received or some error occurred (timeout or socket shutdown).
454 */ 475 */
455void nfs_readpage_result(struct rpc_task *task, void *calldata) 476int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data)
456{ 477{
457 struct nfs_read_data *data = calldata;
458 struct nfs_readargs *argp = &data->args; 478 struct nfs_readargs *argp = &data->args;
459 struct nfs_readres *resp = &data->res; 479 struct nfs_readres *resp = &data->res;
460 int status = task->tk_status; 480 int status;
461 481
462 dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", 482 dprintk("NFS: %4d nfs_readpage_result, (status %d)\n",
463 task->tk_pid, status); 483 task->tk_pid, task->tk_status);
484
485 status = NFS_PROTO(data->inode)->read_done(task, data);
486 if (status != 0)
487 return status;
464 488
465 nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); 489 nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count);
466 490
@@ -474,14 +498,14 @@ void nfs_readpage_result(struct rpc_task *task, void *calldata)
474 argp->pgbase += resp->count; 498 argp->pgbase += resp->count;
475 argp->count -= resp->count; 499 argp->count -= resp->count;
476 rpc_restart_call(task); 500 rpc_restart_call(task);
477 return; 501 return -EAGAIN;
478 } 502 }
479 task->tk_status = -EIO; 503 task->tk_status = -EIO;
480 } 504 }
481 spin_lock(&data->inode->i_lock); 505 spin_lock(&data->inode->i_lock);
482 NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME; 506 NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME;
483 spin_unlock(&data->inode->i_lock); 507 spin_unlock(&data->inode->i_lock);
484 data->complete(data, status); 508 return 0;
485} 509}
486 510
487/* 511/*