aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-14 15:40:00 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:05:32 -0500
commitbdc7f021f3a1fade77adf3c2d7f65690566fddfe (patch)
treec076431ac83fc75cde00dc3d3a218fabae449980
parentb3ef8b3bb93300e58a4c4806207de3de4eb76f48 (diff)
NFS: Clean up the (commit|read|write)_setup() callback routines
Move the common code for setting up the nfs_write_data and nfs_read_data structures into fs/nfs/read.c, fs/nfs/write.c and fs/nfs/direct.c. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/direct.c45
-rw-r--r--fs/nfs/nfs3proc.c41
-rw-r--r--fs/nfs/nfs4proc.c49
-rw-r--r--fs/nfs/proc.c26
-rw-r--r--fs/nfs/read.c38
-rw-r--r--fs/nfs/write.c51
-rw-r--r--include/linux/nfs_xdr.h6
7 files changed, 113 insertions, 143 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 5bcc764e501a..244d1bd7002c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -272,8 +272,12 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
272 unsigned long user_addr = (unsigned long)iov->iov_base; 272 unsigned long user_addr = (unsigned long)iov->iov_base;
273 size_t count = iov->iov_len; 273 size_t count = iov->iov_len;
274 size_t rsize = NFS_SERVER(inode)->rsize; 274 size_t rsize = NFS_SERVER(inode)->rsize;
275 struct rpc_message msg = {
276 .rpc_cred = ctx->cred,
277 };
275 struct rpc_task_setup task_setup_data = { 278 struct rpc_task_setup task_setup_data = {
276 .rpc_client = NFS_CLIENT(inode), 279 .rpc_client = NFS_CLIENT(inode),
280 .rpc_message = &msg,
277 .callback_ops = &nfs_read_direct_ops, 281 .callback_ops = &nfs_read_direct_ops,
278 .flags = RPC_TASK_ASYNC, 282 .flags = RPC_TASK_ASYNC,
279 }; 283 };
@@ -316,7 +320,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
316 320
317 data->req = (struct nfs_page *) dreq; 321 data->req = (struct nfs_page *) dreq;
318 data->inode = inode; 322 data->inode = inode;
319 data->cred = ctx->cred; 323 data->cred = msg.rpc_cred;
320 data->args.fh = NFS_FH(inode); 324 data->args.fh = NFS_FH(inode);
321 data->args.context = ctx; 325 data->args.context = ctx;
322 data->args.offset = pos; 326 data->args.offset = pos;
@@ -326,10 +330,12 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
326 data->res.fattr = &data->fattr; 330 data->res.fattr = &data->fattr;
327 data->res.eof = 0; 331 data->res.eof = 0;
328 data->res.count = bytes; 332 data->res.count = bytes;
333 msg.rpc_argp = &data->args;
334 msg.rpc_resp = &data->res;
329 335
330 task_setup_data.callback_data = data; 336 task_setup_data.callback_data = data;
337 NFS_PROTO(inode)->read_setup(data, &msg);
331 rpc_init_task(&data->task, &task_setup_data); 338 rpc_init_task(&data->task, &task_setup_data);
332 NFS_PROTO(inode)->read_setup(data);
333 339
334 rpc_execute(&data->task); 340 rpc_execute(&data->task);
335 341
@@ -434,6 +440,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
434 struct inode *inode = dreq->inode; 440 struct inode *inode = dreq->inode;
435 struct list_head *p; 441 struct list_head *p;
436 struct nfs_write_data *data; 442 struct nfs_write_data *data;
443 struct rpc_message msg = {
444 .rpc_cred = dreq->ctx->cred,
445 };
437 struct rpc_task_setup task_setup_data = { 446 struct rpc_task_setup task_setup_data = {
438 .rpc_client = NFS_CLIENT(inode), 447 .rpc_client = NFS_CLIENT(inode),
439 .callback_ops = &nfs_write_direct_ops, 448 .callback_ops = &nfs_write_direct_ops,
@@ -448,6 +457,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
448 457
449 get_dreq(dreq); 458 get_dreq(dreq);
450 459
460 /* Use stable writes */
461 data->args.stable = NFS_FILE_SYNC;
462
451 /* 463 /*
452 * Reset data->res. 464 * Reset data->res.
453 */ 465 */
@@ -460,8 +472,10 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
460 * since the original request was sent. 472 * since the original request was sent.
461 */ 473 */
462 task_setup_data.callback_data = data; 474 task_setup_data.callback_data = data;
475 msg.rpc_argp = &data->args;
476 msg.rpc_resp = &data->res;
477 NFS_PROTO(inode)->write_setup(data, &msg);
463 rpc_init_task(&data->task, &task_setup_data); 478 rpc_init_task(&data->task, &task_setup_data);
464 NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE);
465 479
466 /* 480 /*
467 * We're called via an RPC callback, so BKL is already held. 481 * We're called via an RPC callback, so BKL is already held.
@@ -509,15 +523,21 @@ static const struct rpc_call_ops nfs_commit_direct_ops = {
509static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) 523static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
510{ 524{
511 struct nfs_write_data *data = dreq->commit_data; 525 struct nfs_write_data *data = dreq->commit_data;
526 struct rpc_message msg = {
527 .rpc_argp = &data->args,
528 .rpc_resp = &data->res,
529 .rpc_cred = dreq->ctx->cred,
530 };
512 struct rpc_task_setup task_setup_data = { 531 struct rpc_task_setup task_setup_data = {
513 .rpc_client = NFS_CLIENT(dreq->inode), 532 .rpc_client = NFS_CLIENT(dreq->inode),
533 .rpc_message = &msg,
514 .callback_ops = &nfs_commit_direct_ops, 534 .callback_ops = &nfs_commit_direct_ops,
515 .callback_data = data, 535 .callback_data = data,
516 .flags = RPC_TASK_ASYNC, 536 .flags = RPC_TASK_ASYNC,
517 }; 537 };
518 538
519 data->inode = dreq->inode; 539 data->inode = dreq->inode;
520 data->cred = dreq->ctx->cred; 540 data->cred = msg.rpc_cred;
521 541
522 data->args.fh = NFS_FH(data->inode); 542 data->args.fh = NFS_FH(data->inode);
523 data->args.offset = 0; 543 data->args.offset = 0;
@@ -526,8 +546,8 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
526 data->res.fattr = &data->fattr; 546 data->res.fattr = &data->fattr;
527 data->res.verf = &data->verf; 547 data->res.verf = &data->verf;
528 548
549 NFS_PROTO(data->inode)->commit_setup(data, &msg);
529 rpc_init_task(&data->task, &task_setup_data); 550 rpc_init_task(&data->task, &task_setup_data);
530 NFS_PROTO(data->inode)->commit_setup(data, 0);
531 551
532 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ 552 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
533 dreq->commit_data = NULL; 553 dreq->commit_data = NULL;
@@ -649,8 +669,12 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
649 struct inode *inode = ctx->path.dentry->d_inode; 669 struct inode *inode = ctx->path.dentry->d_inode;
650 unsigned long user_addr = (unsigned long)iov->iov_base; 670 unsigned long user_addr = (unsigned long)iov->iov_base;
651 size_t count = iov->iov_len; 671 size_t count = iov->iov_len;
672 struct rpc_message msg = {
673 .rpc_cred = ctx->cred,
674 };
652 struct rpc_task_setup task_setup_data = { 675 struct rpc_task_setup task_setup_data = {
653 .rpc_client = NFS_CLIENT(inode), 676 .rpc_client = NFS_CLIENT(inode),
677 .rpc_message = &msg,
654 .callback_ops = &nfs_write_direct_ops, 678 .callback_ops = &nfs_write_direct_ops,
655 .flags = RPC_TASK_ASYNC, 679 .flags = RPC_TASK_ASYNC,
656 }; 680 };
@@ -696,20 +720,23 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
696 720
697 data->req = (struct nfs_page *) dreq; 721 data->req = (struct nfs_page *) dreq;
698 data->inode = inode; 722 data->inode = inode;
699 data->cred = ctx->cred; 723 data->cred = msg.rpc_cred;
700 data->args.fh = NFS_FH(inode); 724 data->args.fh = NFS_FH(inode);
701 data->args.context = ctx; 725 data->args.context = ctx;
702 data->args.offset = pos; 726 data->args.offset = pos;
703 data->args.pgbase = pgbase; 727 data->args.pgbase = pgbase;
704 data->args.pages = data->pagevec; 728 data->args.pages = data->pagevec;
705 data->args.count = bytes; 729 data->args.count = bytes;
730 data->args.stable = sync;
706 data->res.fattr = &data->fattr; 731 data->res.fattr = &data->fattr;
707 data->res.count = bytes; 732 data->res.count = bytes;
708 data->res.verf = &data->verf; 733 data->res.verf = &data->verf;
709 734
710 task_setup_data.callback_data = data; 735 task_setup_data.callback_data = data;
736 msg.rpc_argp = &data->args;
737 msg.rpc_resp = &data->res;
738 NFS_PROTO(inode)->write_setup(data, &msg);
711 rpc_init_task(&data->task, &task_setup_data); 739 rpc_init_task(&data->task, &task_setup_data);
712 NFS_PROTO(inode)->write_setup(data, sync);
713 740
714 rpc_execute(&data->task); 741 rpc_execute(&data->task);
715 742
@@ -782,7 +809,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
782 struct rpc_clnt *clnt = NFS_CLIENT(inode); 809 struct rpc_clnt *clnt = NFS_CLIENT(inode);
783 struct nfs_direct_req *dreq; 810 struct nfs_direct_req *dreq;
784 size_t wsize = NFS_SERVER(inode)->wsize; 811 size_t wsize = NFS_SERVER(inode)->wsize;
785 int sync = 0; 812 int sync = NFS_UNSTABLE;
786 813
787 dreq = nfs_direct_req_alloc(); 814 dreq = nfs_direct_req_alloc();
788 if (!dreq) 815 if (!dreq)
@@ -790,7 +817,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
790 nfs_alloc_commit_data(dreq); 817 nfs_alloc_commit_data(dreq);
791 818
792 if (dreq->commit_data == NULL || count < wsize) 819 if (dreq->commit_data == NULL || count < wsize)
793 sync = FLUSH_STABLE; 820 sync = NFS_FILE_SYNC;
794 821
795 dreq->inode = inode; 822 dreq->inode = inode;
796 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 823 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 4cdc2361a669..e68580ebaa47 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -732,16 +732,9 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
732 return 0; 732 return 0;
733} 733}
734 734
735static void nfs3_proc_read_setup(struct nfs_read_data *data) 735static void nfs3_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
736{ 736{
737 struct rpc_message msg = { 737 msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
738 .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
739 .rpc_argp = &data->args,
740 .rpc_resp = &data->res,
741 .rpc_cred = data->cred,
742 };
743
744 rpc_call_setup(&data->task, &msg, 0);
745} 738}
746 739
747static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data) 740static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -753,24 +746,9 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
753 return 0; 746 return 0;
754} 747}
755 748
756static void nfs3_proc_write_setup(struct nfs_write_data *data, int how) 749static void nfs3_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
757{ 750{
758 struct rpc_message msg = { 751 msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE];
759 .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE],
760 .rpc_argp = &data->args,
761 .rpc_resp = &data->res,
762 .rpc_cred = data->cred,
763 };
764
765 data->args.stable = NFS_UNSTABLE;
766 if (how & FLUSH_STABLE) {
767 data->args.stable = NFS_FILE_SYNC;
768 if (NFS_I(data->inode)->ncommit)
769 data->args.stable = NFS_DATA_SYNC;
770 }
771
772 /* Finalize the task. */
773 rpc_call_setup(&data->task, &msg, 0);
774} 752}
775 753
776static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data) 754static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -781,16 +759,9 @@ static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
781 return 0; 759 return 0;
782} 760}
783 761
784static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how) 762static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
785{ 763{
786 struct rpc_message msg = { 764 msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT];
787 .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT],
788 .rpc_argp = &data->args,
789 .rpc_resp = &data->res,
790 .rpc_cred = data->cred,
791 };
792
793 rpc_call_setup(&data->task, &msg, 0);
794} 765}
795 766
796static int 767static int
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ff2c5f83ce87..7c0baf23abdc 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2432,18 +2432,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2432 return 0; 2432 return 0;
2433} 2433}
2434 2434
2435static void nfs4_proc_read_setup(struct nfs_read_data *data) 2435static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
2436{ 2436{
2437 struct rpc_message msg = {
2438 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
2439 .rpc_argp = &data->args,
2440 .rpc_resp = &data->res,
2441 .rpc_cred = data->cred,
2442 };
2443
2444 data->timestamp = jiffies; 2437 data->timestamp = jiffies;
2445 2438 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
2446 rpc_call_setup(&data->task, &msg, 0);
2447} 2439}
2448 2440
2449static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) 2441static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -2461,33 +2453,15 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2461 return 0; 2453 return 0;
2462} 2454}
2463 2455
2464static void nfs4_proc_write_setup(struct nfs_write_data *data, int how) 2456static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
2465{ 2457{
2466 struct rpc_message msg = { 2458 struct nfs_server *server = NFS_SERVER(data->inode);
2467 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], 2459
2468 .rpc_argp = &data->args,
2469 .rpc_resp = &data->res,
2470 .rpc_cred = data->cred,
2471 };
2472 struct inode *inode = data->inode;
2473 struct nfs_server *server = NFS_SERVER(inode);
2474 int stable;
2475
2476 if (how & FLUSH_STABLE) {
2477 if (!NFS_I(inode)->ncommit)
2478 stable = NFS_FILE_SYNC;
2479 else
2480 stable = NFS_DATA_SYNC;
2481 } else
2482 stable = NFS_UNSTABLE;
2483 data->args.stable = stable;
2484 data->args.bitmask = server->attr_bitmask; 2460 data->args.bitmask = server->attr_bitmask;
2485 data->res.server = server; 2461 data->res.server = server;
2486
2487 data->timestamp = jiffies; 2462 data->timestamp = jiffies;
2488 2463
2489 /* Finalize the task. */ 2464 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
2490 rpc_call_setup(&data->task, &msg, 0);
2491} 2465}
2492 2466
2493static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data) 2467static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -2502,20 +2476,13 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
2502 return 0; 2476 return 0;
2503} 2477}
2504 2478
2505static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how) 2479static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
2506{ 2480{
2507 struct rpc_message msg = {
2508 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
2509 .rpc_argp = &data->args,
2510 .rpc_resp = &data->res,
2511 .rpc_cred = data->cred,
2512 };
2513 struct nfs_server *server = NFS_SERVER(data->inode); 2481 struct nfs_server *server = NFS_SERVER(data->inode);
2514 2482
2515 data->args.bitmask = server->attr_bitmask; 2483 data->args.bitmask = server->attr_bitmask;
2516 data->res.server = server; 2484 data->res.server = server;
2517 2485 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
2518 rpc_call_setup(&data->task, &msg, 0);
2519} 2486}
2520 2487
2521/* 2488/*
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 4f80d88e9fee..c9f46a24e75c 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -565,16 +565,9 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
565 return 0; 565 return 0;
566} 566}
567 567
568static void nfs_proc_read_setup(struct nfs_read_data *data) 568static void nfs_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
569{ 569{
570 struct rpc_message msg = { 570 msg->rpc_proc = &nfs_procedures[NFSPROC_READ];
571 .rpc_proc = &nfs_procedures[NFSPROC_READ],
572 .rpc_argp = &data->args,
573 .rpc_resp = &data->res,
574 .rpc_cred = data->cred,
575 };
576
577 rpc_call_setup(&data->task, &msg, 0);
578} 571}
579 572
580static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) 573static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
@@ -584,24 +577,15 @@ static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
584 return 0; 577 return 0;
585} 578}
586 579
587static void nfs_proc_write_setup(struct nfs_write_data *data, int how) 580static void nfs_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
588{ 581{
589 struct rpc_message msg = {
590 .rpc_proc = &nfs_procedures[NFSPROC_WRITE],
591 .rpc_argp = &data->args,
592 .rpc_resp = &data->res,
593 .rpc_cred = data->cred,
594 };
595
596 /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */ 582 /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
597 data->args.stable = NFS_FILE_SYNC; 583 data->args.stable = NFS_FILE_SYNC;
598 584 msg->rpc_proc = &nfs_procedures[NFSPROC_WRITE];
599 /* Finalize the task. */
600 rpc_call_setup(&data->task, &msg, 0);
601} 585}
602 586
603static void 587static void
604nfs_proc_commit_setup(struct nfs_write_data *data, int how) 588nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
605{ 589{
606 BUG(); 590 BUG();
607} 591}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 8f1eb08ccffa..e9dbdc8eafe6 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -153,6 +153,16 @@ static void nfs_readpage_release(struct nfs_page *req)
153 nfs_release_request(req); 153 nfs_release_request(req);
154} 154}
155 155
156static void nfs_execute_read(struct nfs_read_data *data)
157{
158 struct rpc_clnt *clnt = NFS_CLIENT(data->inode);
159 sigset_t oldset;
160
161 rpc_clnt_sigmask(clnt, &oldset);
162 rpc_execute(&data->task);
163 rpc_clnt_sigunmask(clnt, &oldset);
164}
165
156/* 166/*
157 * Set up the NFS read request struct 167 * Set up the NFS read request struct
158 */ 168 */
@@ -162,8 +172,14 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
162{ 172{
163 struct inode *inode = req->wb_context->path.dentry->d_inode; 173 struct inode *inode = req->wb_context->path.dentry->d_inode;
164 int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0; 174 int swap_flags = IS_SWAPFILE(inode) ? NFS_RPC_SWAPFLAGS : 0;
175 struct rpc_message msg = {
176 .rpc_argp = &data->args,
177 .rpc_resp = &data->res,
178 .rpc_cred = req->wb_context->cred,
179 };
165 struct rpc_task_setup task_setup_data = { 180 struct rpc_task_setup task_setup_data = {
166 .rpc_client = NFS_CLIENT(inode), 181 .rpc_client = NFS_CLIENT(inode),
182 .rpc_message = &msg,
167 .callback_ops = call_ops, 183 .callback_ops = call_ops,
168 .callback_data = data, 184 .callback_data = data,
169 .flags = RPC_TASK_ASYNC | swap_flags, 185 .flags = RPC_TASK_ASYNC | swap_flags,
@@ -171,7 +187,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
171 187
172 data->req = req; 188 data->req = req;
173 data->inode = inode; 189 data->inode = inode;
174 data->cred = req->wb_context->cred; 190 data->cred = msg.rpc_cred;
175 191
176 data->args.fh = NFS_FH(inode); 192 data->args.fh = NFS_FH(inode);
177 data->args.offset = req_offset(req) + offset; 193 data->args.offset = req_offset(req) + offset;
@@ -186,8 +202,8 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
186 nfs_fattr_init(&data->fattr); 202 nfs_fattr_init(&data->fattr);
187 203
188 /* Set up the initial task struct. */ 204 /* Set up the initial task struct. */
205 NFS_PROTO(inode)->read_setup(data, &msg);
189 rpc_init_task(&data->task, &task_setup_data); 206 rpc_init_task(&data->task, &task_setup_data);
190 NFS_PROTO(inode)->read_setup(data);
191 207
192 dprintk("NFS: %5u initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n", 208 dprintk("NFS: %5u initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
193 data->task.tk_pid, 209 data->task.tk_pid,
@@ -195,6 +211,8 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
195 (long long)NFS_FILEID(inode), 211 (long long)NFS_FILEID(inode),
196 count, 212 count,
197 (unsigned long long)data->args.offset); 213 (unsigned long long)data->args.offset);
214
215 nfs_execute_read(data);
198} 216}
199 217
200static void 218static void
@@ -211,19 +229,6 @@ nfs_async_read_error(struct list_head *head)
211} 229}
212 230
213/* 231/*
214 * Start an async read operation
215 */
216static void nfs_execute_read(struct nfs_read_data *data)
217{
218 struct rpc_clnt *clnt = NFS_CLIENT(data->inode);
219 sigset_t oldset;
220
221 rpc_clnt_sigmask(clnt, &oldset);
222 rpc_execute(&data->task);
223 rpc_clnt_sigunmask(clnt, &oldset);
224}
225
226/*
227 * Generate multiple requests to fill a single page. 232 * Generate multiple requests to fill a single page.
228 * 233 *
229 * We optimize to reduce the number of read operations on the wire. If we 234 * We optimize to reduce the number of read operations on the wire. If we
@@ -277,7 +282,6 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
277 rsize, offset); 282 rsize, offset);
278 offset += rsize; 283 offset += rsize;
279 nbytes -= rsize; 284 nbytes -= rsize;
280 nfs_execute_read(data);
281 } while (nbytes != 0); 285 } while (nbytes != 0);
282 286
283 return 0; 287 return 0;
@@ -315,8 +319,6 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
315 req = nfs_list_entry(data->pages.next); 319 req = nfs_list_entry(data->pages.next);
316 320
317 nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0); 321 nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0);
318
319 nfs_execute_read(data);
320 return 0; 322 return 0;
321out_bad: 323out_bad:
322 nfs_async_read_error(head); 324 nfs_async_read_error(head);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8d90e90ccd47..9a69469274ae 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -764,6 +764,16 @@ static int flush_task_priority(int how)
764 return RPC_PRIORITY_NORMAL; 764 return RPC_PRIORITY_NORMAL;
765} 765}
766 766
767static void nfs_execute_write(struct nfs_write_data *data)
768{
769 struct rpc_clnt *clnt = NFS_CLIENT(data->inode);
770 sigset_t oldset;
771
772 rpc_clnt_sigmask(clnt, &oldset);
773 rpc_execute(&data->task);
774 rpc_clnt_sigunmask(clnt, &oldset);
775}
776
767/* 777/*
768 * Set up the argument/result storage required for the RPC call. 778 * Set up the argument/result storage required for the RPC call.
769 */ 779 */
@@ -776,8 +786,14 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
776 struct inode *inode = req->wb_context->path.dentry->d_inode; 786 struct inode *inode = req->wb_context->path.dentry->d_inode;
777 int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; 787 int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
778 int priority = flush_task_priority(how); 788 int priority = flush_task_priority(how);
789 struct rpc_message msg = {
790 .rpc_argp = &data->args,
791 .rpc_resp = &data->res,
792 .rpc_cred = req->wb_context->cred,
793 };
779 struct rpc_task_setup task_setup_data = { 794 struct rpc_task_setup task_setup_data = {
780 .rpc_client = NFS_CLIENT(inode), 795 .rpc_client = NFS_CLIENT(inode),
796 .rpc_message = &msg,
781 .callback_ops = call_ops, 797 .callback_ops = call_ops,
782 .callback_data = data, 798 .callback_data = data,
783 .flags = flags, 799 .flags = flags,
@@ -789,7 +805,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
789 805
790 data->req = req; 806 data->req = req;
791 data->inode = inode = req->wb_context->path.dentry->d_inode; 807 data->inode = inode = req->wb_context->path.dentry->d_inode;
792 data->cred = req->wb_context->cred; 808 data->cred = msg.rpc_cred;
793 809
794 data->args.fh = NFS_FH(inode); 810 data->args.fh = NFS_FH(inode);
795 data->args.offset = req_offset(req) + offset; 811 data->args.offset = req_offset(req) + offset;
@@ -797,6 +813,12 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
797 data->args.pages = data->pagevec; 813 data->args.pages = data->pagevec;
798 data->args.count = count; 814 data->args.count = count;
799 data->args.context = req->wb_context; 815 data->args.context = req->wb_context;
816 data->args.stable = NFS_UNSTABLE;
817 if (how & FLUSH_STABLE) {
818 data->args.stable = NFS_DATA_SYNC;
819 if (!NFS_I(inode)->ncommit)
820 data->args.stable = NFS_FILE_SYNC;
821 }
800 822
801 data->res.fattr = &data->fattr; 823 data->res.fattr = &data->fattr;
802 data->res.count = count; 824 data->res.count = count;
@@ -804,8 +826,8 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
804 nfs_fattr_init(&data->fattr); 826 nfs_fattr_init(&data->fattr);
805 827
806 /* Set up the initial task struct. */ 828 /* Set up the initial task struct. */
829 NFS_PROTO(inode)->write_setup(data, &msg);
807 rpc_init_task(&data->task, &task_setup_data); 830 rpc_init_task(&data->task, &task_setup_data);
808 NFS_PROTO(inode)->write_setup(data, how);
809 831
810 dprintk("NFS: %5u initiated write call " 832 dprintk("NFS: %5u initiated write call "
811 "(req %s/%Ld, %u bytes @ offset %Lu)\n", 833 "(req %s/%Ld, %u bytes @ offset %Lu)\n",
@@ -814,16 +836,8 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
814 (long long)NFS_FILEID(inode), 836 (long long)NFS_FILEID(inode),
815 count, 837 count,
816 (unsigned long long)data->args.offset); 838 (unsigned long long)data->args.offset);
817}
818 839
819static void nfs_execute_write(struct nfs_write_data *data) 840 nfs_execute_write(data);
820{
821 struct rpc_clnt *clnt = NFS_CLIENT(data->inode);
822 sigset_t oldset;
823
824 rpc_clnt_sigmask(clnt, &oldset);
825 rpc_execute(&data->task);
826 rpc_clnt_sigunmask(clnt, &oldset);
827} 841}
828 842
829/* 843/*
@@ -870,7 +884,6 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
870 wsize, offset, how); 884 wsize, offset, how);
871 offset += wsize; 885 offset += wsize;
872 nbytes -= wsize; 886 nbytes -= wsize;
873 nfs_execute_write(data);
874 } while (nbytes != 0); 887 } while (nbytes != 0);
875 888
876 return 0; 889 return 0;
@@ -918,7 +931,6 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
918 /* Set up the argument struct */ 931 /* Set up the argument struct */
919 nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how); 932 nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how);
920 933
921 nfs_execute_write(data);
922 return 0; 934 return 0;
923 out_bad: 935 out_bad:
924 while (!list_empty(head)) { 936 while (!list_empty(head)) {
@@ -1152,8 +1164,14 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1152 struct inode *inode = first->wb_context->path.dentry->d_inode; 1164 struct inode *inode = first->wb_context->path.dentry->d_inode;
1153 int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; 1165 int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
1154 int priority = flush_task_priority(how); 1166 int priority = flush_task_priority(how);
1167 struct rpc_message msg = {
1168 .rpc_argp = &data->args,
1169 .rpc_resp = &data->res,
1170 .rpc_cred = first->wb_context->cred,
1171 };
1155 struct rpc_task_setup task_setup_data = { 1172 struct rpc_task_setup task_setup_data = {
1156 .rpc_client = NFS_CLIENT(inode), 1173 .rpc_client = NFS_CLIENT(inode),
1174 .rpc_message = &msg,
1157 .callback_ops = &nfs_commit_ops, 1175 .callback_ops = &nfs_commit_ops,
1158 .callback_data = data, 1176 .callback_data = data,
1159 .flags = flags, 1177 .flags = flags,
@@ -1166,7 +1184,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1166 list_splice_init(head, &data->pages); 1184 list_splice_init(head, &data->pages);
1167 1185
1168 data->inode = inode; 1186 data->inode = inode;
1169 data->cred = first->wb_context->cred; 1187 data->cred = msg.rpc_cred;
1170 1188
1171 data->args.fh = NFS_FH(data->inode); 1189 data->args.fh = NFS_FH(data->inode);
1172 /* Note: we always request a commit of the entire inode */ 1190 /* Note: we always request a commit of the entire inode */
@@ -1178,10 +1196,12 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1178 nfs_fattr_init(&data->fattr); 1196 nfs_fattr_init(&data->fattr);
1179 1197
1180 /* Set up the initial task struct. */ 1198 /* Set up the initial task struct. */
1199 NFS_PROTO(inode)->commit_setup(data, &msg);
1181 rpc_init_task(&data->task, &task_setup_data); 1200 rpc_init_task(&data->task, &task_setup_data);
1182 NFS_PROTO(inode)->commit_setup(data, how);
1183 1201
1184 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 1202 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
1203
1204 nfs_execute_write(data);
1185} 1205}
1186 1206
1187/* 1207/*
@@ -1201,7 +1221,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1201 /* Set up the argument struct */ 1221 /* Set up the argument struct */
1202 nfs_commit_rpcsetup(head, data, how); 1222 nfs_commit_rpcsetup(head, data, how);
1203 1223
1204 nfs_execute_write(data);
1205 return 0; 1224 return 0;
1206 out_bad: 1225 out_bad:
1207 while (!list_empty(head)) { 1226 while (!list_empty(head)) {
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index daab252f2e5c..6b213a64b15f 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -816,11 +816,11 @@ struct nfs_rpc_ops {
816 struct nfs_pathconf *); 816 struct nfs_pathconf *);
817 int (*set_capabilities)(struct nfs_server *, struct nfs_fh *); 817 int (*set_capabilities)(struct nfs_server *, struct nfs_fh *);
818 __be32 *(*decode_dirent)(__be32 *, struct nfs_entry *, int plus); 818 __be32 *(*decode_dirent)(__be32 *, struct nfs_entry *, int plus);
819 void (*read_setup) (struct nfs_read_data *); 819 void (*read_setup) (struct nfs_read_data *, struct rpc_message *);
820 int (*read_done) (struct rpc_task *, struct nfs_read_data *); 820 int (*read_done) (struct rpc_task *, struct nfs_read_data *);
821 void (*write_setup) (struct nfs_write_data *, int how); 821 void (*write_setup) (struct nfs_write_data *, struct rpc_message *);
822 int (*write_done) (struct rpc_task *, struct nfs_write_data *); 822 int (*write_done) (struct rpc_task *, struct nfs_write_data *);
823 void (*commit_setup) (struct nfs_write_data *, int how); 823 void (*commit_setup) (struct nfs_write_data *, struct rpc_message *);
824 int (*commit_done) (struct rpc_task *, struct nfs_write_data *); 824 int (*commit_done) (struct rpc_task *, struct nfs_write_data *);
825 int (*file_open) (struct inode *, struct file *); 825 int (*file_open) (struct inode *, struct file *);
826 int (*file_release) (struct inode *, struct file *); 826 int (*file_release) (struct inode *, struct file *);