aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/direct.c17
-rw-r--r--fs/nfs/nfs3proc.c27
-rw-r--r--fs/nfs/nfs4proc.c33
-rw-r--r--fs/nfs/proc.c25
-rw-r--r--fs/nfs/read.c58
5 files changed, 74 insertions, 86 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index fc07ce4885da..3f87a72bd137 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -218,14 +218,17 @@ static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int
218 * until the RPCs complete. This could be long *after* we are woken up in 218 * until the RPCs complete. This could be long *after* we are woken up in
219 * nfs_direct_read_wait (for instance, if someone hits ^C on a slow server). 219 * nfs_direct_read_wait (for instance, if someone hits ^C on a slow server).
220 */ 220 */
221static void nfs_direct_read_result(struct nfs_read_data *data, int status) 221static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
222{ 222{
223 struct nfs_read_data *data = calldata;
223 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req; 224 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
224 225
225 if (likely(status >= 0)) 226 if (nfs_readpage_result(task, data) != 0)
227 return;
228 if (likely(task->tk_status >= 0))
226 atomic_add(data->res.count, &dreq->count); 229 atomic_add(data->res.count, &dreq->count);
227 else 230 else
228 atomic_set(&dreq->error, status); 231 atomic_set(&dreq->error, task->tk_status);
229 232
230 if (unlikely(atomic_dec_and_test(&dreq->complete))) { 233 if (unlikely(atomic_dec_and_test(&dreq->complete))) {
231 nfs_free_user_pages(dreq->pages, dreq->npages, 1); 234 nfs_free_user_pages(dreq->pages, dreq->npages, 1);
@@ -234,6 +237,11 @@ static void nfs_direct_read_result(struct nfs_read_data *data, int status)
234 } 237 }
235} 238}
236 239
240static const struct rpc_call_ops nfs_read_direct_ops = {
241 .rpc_call_done = nfs_direct_read_result,
242 .rpc_release = nfs_readdata_release,
243};
244
237/** 245/**
238 * nfs_direct_read_schedule - dispatch NFS READ operations for a direct read 246 * nfs_direct_read_schedule - dispatch NFS READ operations for a direct read
239 * @dreq: address of nfs_direct_req struct for this request 247 * @dreq: address of nfs_direct_req struct for this request
@@ -280,10 +288,11 @@ static void nfs_direct_read_schedule(struct nfs_direct_req *dreq,
280 data->res.eof = 0; 288 data->res.eof = 0;
281 data->res.count = bytes; 289 data->res.count = bytes;
282 290
291 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC,
292 &nfs_read_direct_ops, data);
283 NFS_PROTO(inode)->read_setup(data); 293 NFS_PROTO(inode)->read_setup(data);
284 294
285 data->task.tk_cookie = (unsigned long) inode; 295 data->task.tk_cookie = (unsigned long) inode;
286 data->complete = nfs_direct_read_result;
287 296
288 lock_kernel(); 297 lock_kernel();
289 rpc_execute(&data->task); 298 rpc_execute(&data->task);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index c4f7de8830e9..cf186f0d2b3b 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -811,29 +811,18 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
811 811
812extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); 812extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
813 813
814static void nfs3_read_done(struct rpc_task *task, void *calldata) 814static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
815{ 815{
816 struct nfs_read_data *data = calldata;
817
818 if (nfs3_async_handle_jukebox(task, data->inode)) 816 if (nfs3_async_handle_jukebox(task, data->inode))
819 return; 817 return -EAGAIN;
820 /* Call back common NFS readpage processing */ 818 /* Call back common NFS readpage processing */
821 if (task->tk_status >= 0) 819 if (task->tk_status >= 0)
822 nfs_refresh_inode(data->inode, &data->fattr); 820 nfs_refresh_inode(data->inode, &data->fattr);
823 nfs_readpage_result(task, calldata); 821 return 0;
824} 822}
825 823
826static const struct rpc_call_ops nfs3_read_ops = { 824static void nfs3_proc_read_setup(struct nfs_read_data *data)
827 .rpc_call_done = nfs3_read_done,
828 .rpc_release = nfs_readdata_release,
829};
830
831static void
832nfs3_proc_read_setup(struct nfs_read_data *data)
833{ 825{
834 struct rpc_task *task = &data->task;
835 struct inode *inode = data->inode;
836 int flags;
837 struct rpc_message msg = { 826 struct rpc_message msg = {
838 .rpc_proc = &nfs3_procedures[NFS3PROC_READ], 827 .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
839 .rpc_argp = &data->args, 828 .rpc_argp = &data->args,
@@ -841,12 +830,7 @@ nfs3_proc_read_setup(struct nfs_read_data *data)
841 .rpc_cred = data->cred, 830 .rpc_cred = data->cred,
842 }; 831 };
843 832
844 /* N.B. Do we need to test? Never called for swapfile inode */ 833 rpc_call_setup(&data->task, &msg, 0);
845 flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
846
847 /* Finalize the task. */
848 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_read_ops, data);
849 rpc_call_setup(task, &msg, 0);
850} 834}
851 835
852static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data) 836static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -935,6 +919,7 @@ struct nfs_rpc_ops nfs_v3_clientops = {
935 .pathconf = nfs3_proc_pathconf, 919 .pathconf = nfs3_proc_pathconf,
936 .decode_dirent = nfs3_decode_dirent, 920 .decode_dirent = nfs3_decode_dirent,
937 .read_setup = nfs3_proc_read_setup, 921 .read_setup = nfs3_proc_read_setup,
922 .read_done = nfs3_read_done,
938 .write_setup = nfs3_proc_write_setup, 923 .write_setup = nfs3_proc_write_setup,
939 .write_done = nfs3_write_done, 924 .write_done = nfs3_write_done,
940 .commit_setup = nfs3_proc_commit_setup, 925 .commit_setup = nfs3_proc_commit_setup,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ef4dc315ecc2..bad1eae5608a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2345,47 +2345,31 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
2345 return err; 2345 return err;
2346} 2346}
2347 2347
2348static void nfs4_read_done(struct rpc_task *task, void *calldata) 2348static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2349{ 2349{
2350 struct nfs_read_data *data = calldata; 2350 struct nfs_server *server = NFS_SERVER(data->inode);
2351 struct inode *inode = data->inode;
2352 2351
2353 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2352 if (nfs4_async_handle_error(task, server) == -EAGAIN) {
2354 rpc_restart_call(task); 2353 rpc_restart_call(task);
2355 return; 2354 return -EAGAIN;
2356 } 2355 }
2357 if (task->tk_status > 0) 2356 if (task->tk_status > 0)
2358 renew_lease(NFS_SERVER(inode), data->timestamp); 2357 renew_lease(server, data->timestamp);
2359 /* Call back common NFS readpage processing */ 2358 return 0;
2360 nfs_readpage_result(task, calldata);
2361} 2359}
2362 2360
2363static const struct rpc_call_ops nfs4_read_ops = { 2361static void nfs4_proc_read_setup(struct nfs_read_data *data)
2364 .rpc_call_done = nfs4_read_done,
2365 .rpc_release = nfs_readdata_release,
2366};
2367
2368static void
2369nfs4_proc_read_setup(struct nfs_read_data *data)
2370{ 2362{
2371 struct rpc_task *task = &data->task;
2372 struct rpc_message msg = { 2363 struct rpc_message msg = {
2373 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ], 2364 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
2374 .rpc_argp = &data->args, 2365 .rpc_argp = &data->args,
2375 .rpc_resp = &data->res, 2366 .rpc_resp = &data->res,
2376 .rpc_cred = data->cred, 2367 .rpc_cred = data->cred,
2377 }; 2368 };
2378 struct inode *inode = data->inode;
2379 int flags;
2380 2369
2381 data->timestamp = jiffies; 2370 data->timestamp = jiffies;
2382 2371
2383 /* N.B. Do we need to test? Never called for swapfile inode */ 2372 rpc_call_setup(&data->task, &msg, 0);
2384 flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
2385
2386 /* Finalize the task. */
2387 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_read_ops, data);
2388 rpc_call_setup(task, &msg, 0);
2389} 2373}
2390 2374
2391static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) 2375static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -3617,6 +3601,7 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3617 .pathconf = nfs4_proc_pathconf, 3601 .pathconf = nfs4_proc_pathconf,
3618 .decode_dirent = nfs4_decode_dirent, 3602 .decode_dirent = nfs4_decode_dirent,
3619 .read_setup = nfs4_proc_read_setup, 3603 .read_setup = nfs4_proc_read_setup,
3604 .read_done = nfs4_read_done,
3620 .write_setup = nfs4_proc_write_setup, 3605 .write_setup = nfs4_proc_write_setup,
3621 .write_done = nfs4_write_done, 3606 .write_done = nfs4_write_done,
3622 .commit_setup = nfs4_proc_commit_setup, 3607 .commit_setup = nfs4_proc_commit_setup,
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 608aa5932a1d..9dd85cac2df0 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -613,10 +613,8 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
613 613
614extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); 614extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
615 615
616static void nfs_read_done(struct rpc_task *task, void *calldata) 616static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
617{ 617{
618 struct nfs_read_data *data = calldata;
619
620 if (task->tk_status >= 0) { 618 if (task->tk_status >= 0) {
621 nfs_refresh_inode(data->inode, data->res.fattr); 619 nfs_refresh_inode(data->inode, data->res.fattr);
622 /* Emulate the eof flag, which isn't normally needed in NFSv2 620 /* Emulate the eof flag, which isn't normally needed in NFSv2
@@ -625,20 +623,11 @@ static void nfs_read_done(struct rpc_task *task, void *calldata)
625 if (data->args.offset + data->args.count >= data->res.fattr->size) 623 if (data->args.offset + data->args.count >= data->res.fattr->size)
626 data->res.eof = 1; 624 data->res.eof = 1;
627 } 625 }
628 nfs_readpage_result(task, calldata); 626 return 0;
629} 627}
630 628
631static const struct rpc_call_ops nfs_read_ops = { 629static void nfs_proc_read_setup(struct nfs_read_data *data)
632 .rpc_call_done = nfs_read_done,
633 .rpc_release = nfs_readdata_release,
634};
635
636static void
637nfs_proc_read_setup(struct nfs_read_data *data)
638{ 630{
639 struct rpc_task *task = &data->task;
640 struct inode *inode = data->inode;
641 int flags;
642 struct rpc_message msg = { 631 struct rpc_message msg = {
643 .rpc_proc = &nfs_procedures[NFSPROC_READ], 632 .rpc_proc = &nfs_procedures[NFSPROC_READ],
644 .rpc_argp = &data->args, 633 .rpc_argp = &data->args,
@@ -646,12 +635,7 @@ nfs_proc_read_setup(struct nfs_read_data *data)
646 .rpc_cred = data->cred, 635 .rpc_cred = data->cred,
647 }; 636 };
648 637
649 /* N.B. Do we need to test? Never called for swapfile inode */ 638 rpc_call_setup(&data->task, &msg, 0);
650 flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
651
652 /* Finalize the task. */
653 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs_read_ops, data);
654 rpc_call_setup(task, &msg, 0);
655} 639}
656 640
657static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) 641static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -720,6 +704,7 @@ struct nfs_rpc_ops nfs_v2_clientops = {
720 .pathconf = nfs_proc_pathconf, 704 .pathconf = nfs_proc_pathconf,
721 .decode_dirent = nfs_decode_dirent, 705 .decode_dirent = nfs_decode_dirent,
722 .read_setup = nfs_proc_read_setup, 706 .read_setup = nfs_proc_read_setup,
707 .read_done = nfs_read_done,
723 .write_setup = nfs_proc_write_setup, 708 .write_setup = nfs_proc_write_setup,
724 .write_done = nfs_write_done, 709 .write_done = nfs_write_done,
725 .commit_setup = nfs_proc_commit_setup, 710 .commit_setup = nfs_proc_commit_setup,
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/*