aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs3proc.c66
-rw-r--r--fs/nfs/nfs4proc.c54
-rw-r--r--fs/nfs/proc.c24
-rw-r--r--fs/nfs/write.c92
-rw-r--r--include/linux/nfs_fs.h7
-rw-r--r--include/linux/nfs_xdr.h3
6 files changed, 103 insertions, 143 deletions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 740f8b1ab04d..c4f7de8830e9 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -849,29 +849,17 @@ nfs3_proc_read_setup(struct nfs_read_data *data)
849 rpc_call_setup(task, &msg, 0); 849 rpc_call_setup(task, &msg, 0);
850} 850}
851 851
852static void nfs3_write_done(struct rpc_task *task, void *calldata) 852static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
853{ 853{
854 struct nfs_write_data *data = calldata;
855
856 if (nfs3_async_handle_jukebox(task, data->inode)) 854 if (nfs3_async_handle_jukebox(task, data->inode))
857 return; 855 return -EAGAIN;
858 if (task->tk_status >= 0) 856 if (task->tk_status >= 0)
859 nfs_post_op_update_inode(data->inode, data->res.fattr); 857 nfs_post_op_update_inode(data->inode, data->res.fattr);
860 nfs_writeback_done(task, calldata); 858 return 0;
861} 859}
862 860
863static const struct rpc_call_ops nfs3_write_ops = { 861static void nfs3_proc_write_setup(struct nfs_write_data *data, int how)
864 .rpc_call_done = nfs3_write_done,
865 .rpc_release = nfs_writedata_release,
866};
867
868static void
869nfs3_proc_write_setup(struct nfs_write_data *data, int how)
870{ 862{
871 struct rpc_task *task = &data->task;
872 struct inode *inode = data->inode;
873 int stable;
874 int flags;
875 struct rpc_message msg = { 863 struct rpc_message msg = {
876 .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE], 864 .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE],
877 .rpc_argp = &data->args, 865 .rpc_argp = &data->args,
@@ -879,45 +867,28 @@ nfs3_proc_write_setup(struct nfs_write_data *data, int how)
879 .rpc_cred = data->cred, 867 .rpc_cred = data->cred,
880 }; 868 };
881 869
870 data->args.stable = NFS_UNSTABLE;
882 if (how & FLUSH_STABLE) { 871 if (how & FLUSH_STABLE) {
883 if (!NFS_I(inode)->ncommit) 872 data->args.stable = NFS_FILE_SYNC;
884 stable = NFS_FILE_SYNC; 873 if (NFS_I(data->inode)->ncommit)
885 else 874 data->args.stable = NFS_DATA_SYNC;
886 stable = NFS_DATA_SYNC; 875 }
887 } else
888 stable = NFS_UNSTABLE;
889 data->args.stable = stable;
890
891 /* Set the initial flags for the task. */
892 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
893 876
894 /* Finalize the task. */ 877 /* Finalize the task. */
895 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_write_ops, data); 878 rpc_call_setup(&data->task, &msg, 0);
896 rpc_call_setup(task, &msg, 0);
897} 879}
898 880
899static void nfs3_commit_done(struct rpc_task *task, void *calldata) 881static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
900{ 882{
901 struct nfs_write_data *data = calldata;
902
903 if (nfs3_async_handle_jukebox(task, data->inode)) 883 if (nfs3_async_handle_jukebox(task, data->inode))
904 return; 884 return -EAGAIN;
905 if (task->tk_status >= 0) 885 if (task->tk_status >= 0)
906 nfs_post_op_update_inode(data->inode, data->res.fattr); 886 nfs_post_op_update_inode(data->inode, data->res.fattr);
907 nfs_commit_done(task, calldata); 887 return 0;
908} 888}
909 889
910static const struct rpc_call_ops nfs3_commit_ops = { 890static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
911 .rpc_call_done = nfs3_commit_done,
912 .rpc_release = nfs_commit_release,
913};
914
915static void
916nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
917{ 891{
918 struct rpc_task *task = &data->task;
919 struct inode *inode = data->inode;
920 int flags;
921 struct rpc_message msg = { 892 struct rpc_message msg = {
922 .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT], 893 .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT],
923 .rpc_argp = &data->args, 894 .rpc_argp = &data->args,
@@ -925,12 +896,7 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
925 .rpc_cred = data->cred, 896 .rpc_cred = data->cred,
926 }; 897 };
927 898
928 /* Set the initial flags for the task. */ 899 rpc_call_setup(&data->task, &msg, 0);
929 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
930
931 /* Finalize the task. */
932 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_commit_ops, data);
933 rpc_call_setup(task, &msg, 0);
934} 900}
935 901
936static int 902static int
@@ -970,7 +936,9 @@ struct nfs_rpc_ops nfs_v3_clientops = {
970 .decode_dirent = nfs3_decode_dirent, 936 .decode_dirent = nfs3_decode_dirent,
971 .read_setup = nfs3_proc_read_setup, 937 .read_setup = nfs3_proc_read_setup,
972 .write_setup = nfs3_proc_write_setup, 938 .write_setup = nfs3_proc_write_setup,
939 .write_done = nfs3_write_done,
973 .commit_setup = nfs3_proc_commit_setup, 940 .commit_setup = nfs3_proc_commit_setup,
941 .commit_done = nfs3_commit_done,
974 .file_open = nfs_open, 942 .file_open = nfs_open,
975 .file_release = nfs_release, 943 .file_release = nfs_release,
976 .lock = nfs3_proc_lock, 944 .lock = nfs3_proc_lock,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f1ff4fa6cce5..ef4dc315ecc2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2388,32 +2388,23 @@ nfs4_proc_read_setup(struct nfs_read_data *data)
2388 rpc_call_setup(task, &msg, 0); 2388 rpc_call_setup(task, &msg, 0);
2389} 2389}
2390 2390
2391static void nfs4_write_done(struct rpc_task *task, void *calldata) 2391static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2392{ 2392{
2393 struct nfs_write_data *data = calldata;
2394 struct inode *inode = data->inode; 2393 struct inode *inode = data->inode;
2395 2394
2396 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2395 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
2397 rpc_restart_call(task); 2396 rpc_restart_call(task);
2398 return; 2397 return -EAGAIN;
2399 } 2398 }
2400 if (task->tk_status >= 0) { 2399 if (task->tk_status >= 0) {
2401 renew_lease(NFS_SERVER(inode), data->timestamp); 2400 renew_lease(NFS_SERVER(inode), data->timestamp);
2402 nfs_post_op_update_inode(inode, data->res.fattr); 2401 nfs_post_op_update_inode(inode, data->res.fattr);
2403 } 2402 }
2404 /* Call back common NFS writeback processing */ 2403 return 0;
2405 nfs_writeback_done(task, calldata);
2406} 2404}
2407 2405
2408static const struct rpc_call_ops nfs4_write_ops = { 2406static void nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2409 .rpc_call_done = nfs4_write_done,
2410 .rpc_release = nfs_writedata_release,
2411};
2412
2413static void
2414nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2415{ 2407{
2416 struct rpc_task *task = &data->task;
2417 struct rpc_message msg = { 2408 struct rpc_message msg = {
2418 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], 2409 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
2419 .rpc_argp = &data->args, 2410 .rpc_argp = &data->args,
@@ -2423,7 +2414,6 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2423 struct inode *inode = data->inode; 2414 struct inode *inode = data->inode;
2424 struct nfs_server *server = NFS_SERVER(inode); 2415 struct nfs_server *server = NFS_SERVER(inode);
2425 int stable; 2416 int stable;
2426 int flags;
2427 2417
2428 if (how & FLUSH_STABLE) { 2418 if (how & FLUSH_STABLE) {
2429 if (!NFS_I(inode)->ncommit) 2419 if (!NFS_I(inode)->ncommit)
@@ -2438,57 +2428,37 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2438 2428
2439 data->timestamp = jiffies; 2429 data->timestamp = jiffies;
2440 2430
2441 /* Set the initial flags for the task. */
2442 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
2443
2444 /* Finalize the task. */ 2431 /* Finalize the task. */
2445 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_write_ops, data); 2432 rpc_call_setup(&data->task, &msg, 0);
2446 rpc_call_setup(task, &msg, 0);
2447} 2433}
2448 2434
2449static void nfs4_commit_done(struct rpc_task *task, void *calldata) 2435static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
2450{ 2436{
2451 struct nfs_write_data *data = calldata;
2452 struct inode *inode = data->inode; 2437 struct inode *inode = data->inode;
2453 2438
2454 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2439 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
2455 rpc_restart_call(task); 2440 rpc_restart_call(task);
2456 return; 2441 return -EAGAIN;
2457 } 2442 }
2458 if (task->tk_status >= 0) 2443 if (task->tk_status >= 0)
2459 nfs_post_op_update_inode(inode, data->res.fattr); 2444 nfs_post_op_update_inode(inode, data->res.fattr);
2460 /* Call back common NFS writeback processing */ 2445 return 0;
2461 nfs_commit_done(task, calldata);
2462} 2446}
2463 2447
2464static const struct rpc_call_ops nfs4_commit_ops = { 2448static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2465 .rpc_call_done = nfs4_commit_done,
2466 .rpc_release = nfs_commit_release,
2467};
2468
2469static void
2470nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2471{ 2449{
2472 struct rpc_task *task = &data->task;
2473 struct rpc_message msg = { 2450 struct rpc_message msg = {
2474 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT], 2451 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
2475 .rpc_argp = &data->args, 2452 .rpc_argp = &data->args,
2476 .rpc_resp = &data->res, 2453 .rpc_resp = &data->res,
2477 .rpc_cred = data->cred, 2454 .rpc_cred = data->cred,
2478 }; 2455 };
2479 struct inode *inode = data->inode; 2456 struct nfs_server *server = NFS_SERVER(data->inode);
2480 struct nfs_server *server = NFS_SERVER(inode);
2481 int flags;
2482 2457
2483 data->args.bitmask = server->attr_bitmask; 2458 data->args.bitmask = server->attr_bitmask;
2484 data->res.server = server; 2459 data->res.server = server;
2485 2460
2486 /* Set the initial flags for the task. */ 2461 rpc_call_setup(&data->task, &msg, 0);
2487 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
2488
2489 /* Finalize the task. */
2490 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_commit_ops, data);
2491 rpc_call_setup(task, &msg, 0);
2492} 2462}
2493 2463
2494/* 2464/*
@@ -3648,7 +3618,9 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3648 .decode_dirent = nfs4_decode_dirent, 3618 .decode_dirent = nfs4_decode_dirent,
3649 .read_setup = nfs4_proc_read_setup, 3619 .read_setup = nfs4_proc_read_setup,
3650 .write_setup = nfs4_proc_write_setup, 3620 .write_setup = nfs4_proc_write_setup,
3621 .write_done = nfs4_write_done,
3651 .commit_setup = nfs4_proc_commit_setup, 3622 .commit_setup = nfs4_proc_commit_setup,
3623 .commit_done = nfs4_commit_done,
3652 .file_open = nfs_open, 3624 .file_open = nfs_open,
3653 .file_release = nfs_release, 3625 .file_release = nfs_release,
3654 .lock = nfs4_proc_lock, 3626 .lock = nfs4_proc_lock,
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 2b051ab8bea8..608aa5932a1d 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -654,26 +654,15 @@ nfs_proc_read_setup(struct nfs_read_data *data)
654 rpc_call_setup(task, &msg, 0); 654 rpc_call_setup(task, &msg, 0);
655} 655}
656 656
657static void nfs_write_done(struct rpc_task *task, void *calldata) 657static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
658{ 658{
659 struct nfs_write_data *data = calldata;
660
661 if (task->tk_status >= 0) 659 if (task->tk_status >= 0)
662 nfs_post_op_update_inode(data->inode, data->res.fattr); 660 nfs_post_op_update_inode(data->inode, data->res.fattr);
663 nfs_writeback_done(task, calldata); 661 return 0;
664} 662}
665 663
666static const struct rpc_call_ops nfs_write_ops = { 664static void nfs_proc_write_setup(struct nfs_write_data *data, int how)
667 .rpc_call_done = nfs_write_done,
668 .rpc_release = nfs_writedata_release,
669};
670
671static void
672nfs_proc_write_setup(struct nfs_write_data *data, int how)
673{ 665{
674 struct rpc_task *task = &data->task;
675 struct inode *inode = data->inode;
676 int flags;
677 struct rpc_message msg = { 666 struct rpc_message msg = {
678 .rpc_proc = &nfs_procedures[NFSPROC_WRITE], 667 .rpc_proc = &nfs_procedures[NFSPROC_WRITE],
679 .rpc_argp = &data->args, 668 .rpc_argp = &data->args,
@@ -684,12 +673,8 @@ nfs_proc_write_setup(struct nfs_write_data *data, int how)
684 /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */ 673 /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
685 data->args.stable = NFS_FILE_SYNC; 674 data->args.stable = NFS_FILE_SYNC;
686 675
687 /* Set the initial flags for the task. */
688 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
689
690 /* Finalize the task. */ 676 /* Finalize the task. */
691 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs_write_ops, data); 677 rpc_call_setup(&data->task, &msg, 0);
692 rpc_call_setup(task, &msg, 0);
693} 678}
694 679
695static void 680static void
@@ -736,6 +721,7 @@ struct nfs_rpc_ops nfs_v2_clientops = {
736 .decode_dirent = nfs_decode_dirent, 721 .decode_dirent = nfs_decode_dirent,
737 .read_setup = nfs_proc_read_setup, 722 .read_setup = nfs_proc_read_setup,
738 .write_setup = nfs_proc_write_setup, 723 .write_setup = nfs_proc_write_setup,
724 .write_done = nfs_write_done,
739 .commit_setup = nfs_proc_commit_setup, 725 .commit_setup = nfs_proc_commit_setup,
740 .file_open = nfs_open, 726 .file_open = nfs_open,
741 .file_release = nfs_release, 727 .file_release = nfs_release,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e7c8361cf201..5912274ff1a1 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -77,12 +77,14 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context*,
77 struct inode *, 77 struct inode *,
78 struct page *, 78 struct page *,
79 unsigned int, unsigned int); 79 unsigned int, unsigned int);
80static void nfs_writeback_done_partial(struct nfs_write_data *, int); 80static int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
81static void nfs_writeback_done_full(struct nfs_write_data *, int);
82static int nfs_wait_on_write_congestion(struct address_space *, int); 81static int nfs_wait_on_write_congestion(struct address_space *, int);
83static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); 82static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int);
84static int nfs_flush_inode(struct inode *inode, unsigned long idx_start, 83static int nfs_flush_inode(struct inode *inode, unsigned long idx_start,
85 unsigned int npages, int how); 84 unsigned int npages, int how);
85static const struct rpc_call_ops nfs_write_partial_ops;
86static const struct rpc_call_ops nfs_write_full_ops;
87static const struct rpc_call_ops nfs_commit_ops;
86 88
87static kmem_cache_t *nfs_wdata_cachep; 89static kmem_cache_t *nfs_wdata_cachep;
88mempool_t *nfs_wdata_mempool; 90mempool_t *nfs_wdata_mempool;
@@ -872,10 +874,12 @@ static inline int flush_task_priority(int how)
872 */ 874 */
873static void nfs_write_rpcsetup(struct nfs_page *req, 875static void nfs_write_rpcsetup(struct nfs_page *req,
874 struct nfs_write_data *data, 876 struct nfs_write_data *data,
877 const struct rpc_call_ops *call_ops,
875 unsigned int count, unsigned int offset, 878 unsigned int count, unsigned int offset,
876 int how) 879 int how)
877{ 880{
878 struct inode *inode; 881 struct inode *inode;
882 int flags;
879 883
880 /* Set up the RPC argument and reply structs 884 /* Set up the RPC argument and reply structs
881 * NB: take care not to mess about with data->commit et al. */ 885 * NB: take care not to mess about with data->commit et al. */
@@ -896,6 +900,9 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
896 data->res.verf = &data->verf; 900 data->res.verf = &data->verf;
897 nfs_fattr_init(&data->fattr); 901 nfs_fattr_init(&data->fattr);
898 902
903 /* Set up the initial task struct. */
904 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
905 rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data);
899 NFS_PROTO(inode)->write_setup(data, how); 906 NFS_PROTO(inode)->write_setup(data, how);
900 907
901 data->task.tk_priority = flush_task_priority(how); 908 data->task.tk_priority = flush_task_priority(how);
@@ -959,14 +966,15 @@ static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how)
959 list_del_init(&data->pages); 966 list_del_init(&data->pages);
960 967
961 data->pagevec[0] = page; 968 data->pagevec[0] = page;
962 data->complete = nfs_writeback_done_partial;
963 969
964 if (nbytes > wsize) { 970 if (nbytes > wsize) {
965 nfs_write_rpcsetup(req, data, wsize, offset, how); 971 nfs_write_rpcsetup(req, data, &nfs_write_partial_ops,
972 wsize, offset, how);
966 offset += wsize; 973 offset += wsize;
967 nbytes -= wsize; 974 nbytes -= wsize;
968 } else { 975 } else {
969 nfs_write_rpcsetup(req, data, nbytes, offset, how); 976 nfs_write_rpcsetup(req, data, &nfs_write_partial_ops,
977 nbytes, offset, how);
970 nbytes = 0; 978 nbytes = 0;
971 } 979 }
972 nfs_execute_write(data); 980 nfs_execute_write(data);
@@ -1020,9 +1028,8 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how)
1020 } 1028 }
1021 req = nfs_list_entry(data->pages.next); 1029 req = nfs_list_entry(data->pages.next);
1022 1030
1023 data->complete = nfs_writeback_done_full;
1024 /* Set up the argument struct */ 1031 /* Set up the argument struct */
1025 nfs_write_rpcsetup(req, data, count, 0, how); 1032 nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how);
1026 1033
1027 nfs_execute_write(data); 1034 nfs_execute_write(data);
1028 return 0; 1035 return 0;
@@ -1066,8 +1073,9 @@ nfs_flush_list(struct list_head *head, int wpages, int how)
1066/* 1073/*
1067 * Handle a write reply that flushed part of a page. 1074 * Handle a write reply that flushed part of a page.
1068 */ 1075 */
1069static void nfs_writeback_done_partial(struct nfs_write_data *data, int status) 1076static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
1070{ 1077{
1078 struct nfs_write_data *data = calldata;
1071 struct nfs_page *req = data->req; 1079 struct nfs_page *req = data->req;
1072 struct page *page = req->wb_page; 1080 struct page *page = req->wb_page;
1073 1081
@@ -1077,11 +1085,14 @@ static void nfs_writeback_done_partial(struct nfs_write_data *data, int status)
1077 req->wb_bytes, 1085 req->wb_bytes,
1078 (long long)req_offset(req)); 1086 (long long)req_offset(req));
1079 1087
1080 if (status < 0) { 1088 if (nfs_writeback_done(task, data) != 0)
1089 return;
1090
1091 if (task->tk_status < 0) {
1081 ClearPageUptodate(page); 1092 ClearPageUptodate(page);
1082 SetPageError(page); 1093 SetPageError(page);
1083 req->wb_context->error = status; 1094 req->wb_context->error = task->tk_status;
1084 dprintk(", error = %d\n", status); 1095 dprintk(", error = %d\n", task->tk_status);
1085 } else { 1096 } else {
1086#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1097#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
1087 if (data->verf.committed < NFS_FILE_SYNC) { 1098 if (data->verf.committed < NFS_FILE_SYNC) {
@@ -1102,6 +1113,11 @@ static void nfs_writeback_done_partial(struct nfs_write_data *data, int status)
1102 nfs_writepage_release(req); 1113 nfs_writepage_release(req);
1103} 1114}
1104 1115
1116static const struct rpc_call_ops nfs_write_partial_ops = {
1117 .rpc_call_done = nfs_writeback_done_partial,
1118 .rpc_release = nfs_writedata_release,
1119};
1120
1105/* 1121/*
1106 * Handle a write reply that flushes a whole page. 1122 * Handle a write reply that flushes a whole page.
1107 * 1123 *
@@ -1109,11 +1125,15 @@ static void nfs_writeback_done_partial(struct nfs_write_data *data, int status)
1109 * writebacks since the page->count is kept > 1 for as long 1125 * writebacks since the page->count is kept > 1 for as long
1110 * as the page has a write request pending. 1126 * as the page has a write request pending.
1111 */ 1127 */
1112static void nfs_writeback_done_full(struct nfs_write_data *data, int status) 1128static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1113{ 1129{
1130 struct nfs_write_data *data = calldata;
1114 struct nfs_page *req; 1131 struct nfs_page *req;
1115 struct page *page; 1132 struct page *page;
1116 1133
1134 if (nfs_writeback_done(task, data) != 0)
1135 return;
1136
1117 /* Update attributes as result of writeback. */ 1137 /* Update attributes as result of writeback. */
1118 while (!list_empty(&data->pages)) { 1138 while (!list_empty(&data->pages)) {
1119 req = nfs_list_entry(data->pages.next); 1139 req = nfs_list_entry(data->pages.next);
@@ -1126,13 +1146,13 @@ static void nfs_writeback_done_full(struct nfs_write_data *data, int status)
1126 req->wb_bytes, 1146 req->wb_bytes,
1127 (long long)req_offset(req)); 1147 (long long)req_offset(req));
1128 1148
1129 if (status < 0) { 1149 if (task->tk_status < 0) {
1130 ClearPageUptodate(page); 1150 ClearPageUptodate(page);
1131 SetPageError(page); 1151 SetPageError(page);
1132 req->wb_context->error = status; 1152 req->wb_context->error = task->tk_status;
1133 end_page_writeback(page); 1153 end_page_writeback(page);
1134 nfs_inode_remove_request(req); 1154 nfs_inode_remove_request(req);
1135 dprintk(", error = %d\n", status); 1155 dprintk(", error = %d\n", task->tk_status);
1136 goto next; 1156 goto next;
1137 } 1157 }
1138 end_page_writeback(page); 1158 end_page_writeback(page);
@@ -1154,18 +1174,28 @@ static void nfs_writeback_done_full(struct nfs_write_data *data, int status)
1154 } 1174 }
1155} 1175}
1156 1176
1177static const struct rpc_call_ops nfs_write_full_ops = {
1178 .rpc_call_done = nfs_writeback_done_full,
1179 .rpc_release = nfs_writedata_release,
1180};
1181
1182
1157/* 1183/*
1158 * This function is called when the WRITE call is complete. 1184 * This function is called when the WRITE call is complete.
1159 */ 1185 */
1160void nfs_writeback_done(struct rpc_task *task, void *calldata) 1186static int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1161{ 1187{
1162 struct nfs_write_data *data = calldata;
1163 struct nfs_writeargs *argp = &data->args; 1188 struct nfs_writeargs *argp = &data->args;
1164 struct nfs_writeres *resp = &data->res; 1189 struct nfs_writeres *resp = &data->res;
1190 int status;
1165 1191
1166 dprintk("NFS: %4d nfs_writeback_done (status %d)\n", 1192 dprintk("NFS: %4d nfs_writeback_done (status %d)\n",
1167 task->tk_pid, task->tk_status); 1193 task->tk_pid, task->tk_status);
1168 1194
1195 /* Call the NFS version-specific code */
1196 status = NFS_PROTO(data->inode)->write_done(task, data);
1197 if (status != 0)
1198 return status;
1169 nfs_add_stats(data->inode, NFSIOS_SERVERWRITTENBYTES, resp->count); 1199 nfs_add_stats(data->inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
1170 1200
1171#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1201#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -1210,7 +1240,7 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata)
1210 argp->stable = NFS_FILE_SYNC; 1240 argp->stable = NFS_FILE_SYNC;
1211 } 1241 }
1212 rpc_restart_call(task); 1242 rpc_restart_call(task);
1213 return; 1243 return -EAGAIN;
1214 } 1244 }
1215 if (time_before(complain, jiffies)) { 1245 if (time_before(complain, jiffies)) {
1216 printk(KERN_WARNING 1246 printk(KERN_WARNING
@@ -1221,11 +1251,7 @@ void nfs_writeback_done(struct rpc_task *task, void *calldata)
1221 /* Can't do anything about it except throw an error. */ 1251 /* Can't do anything about it except throw an error. */
1222 task->tk_status = -EIO; 1252 task->tk_status = -EIO;
1223 } 1253 }
1224 1254 return 0;
1225 /*
1226 * Process the nfs_page list
1227 */
1228 data->complete(data, task->tk_status);
1229} 1255}
1230 1256
1231 1257
@@ -1239,10 +1265,12 @@ void nfs_commit_release(void *wdata)
1239 * Set up the argument/result storage required for the RPC call. 1265 * Set up the argument/result storage required for the RPC call.
1240 */ 1266 */
1241static void nfs_commit_rpcsetup(struct list_head *head, 1267static void nfs_commit_rpcsetup(struct list_head *head,
1242 struct nfs_write_data *data, int how) 1268 struct nfs_write_data *data,
1269 int how)
1243{ 1270{
1244 struct nfs_page *first; 1271 struct nfs_page *first;
1245 struct inode *inode; 1272 struct inode *inode;
1273 int flags;
1246 1274
1247 /* Set up the RPC argument and reply structs 1275 /* Set up the RPC argument and reply structs
1248 * NB: take care not to mess about with data->commit et al. */ 1276 * NB: take care not to mess about with data->commit et al. */
@@ -1262,7 +1290,10 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1262 data->res.fattr = &data->fattr; 1290 data->res.fattr = &data->fattr;
1263 data->res.verf = &data->verf; 1291 data->res.verf = &data->verf;
1264 nfs_fattr_init(&data->fattr); 1292 nfs_fattr_init(&data->fattr);
1265 1293
1294 /* Set up the initial task struct. */
1295 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
1296 rpc_init_task(&data->task, NFS_CLIENT(inode), flags, &nfs_commit_ops, data);
1266 NFS_PROTO(inode)->commit_setup(data, how); 1297 NFS_PROTO(inode)->commit_setup(data, how);
1267 1298
1268 data->task.tk_priority = flush_task_priority(how); 1299 data->task.tk_priority = flush_task_priority(how);
@@ -1303,7 +1334,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1303/* 1334/*
1304 * COMMIT call returned 1335 * COMMIT call returned
1305 */ 1336 */
1306void nfs_commit_done(struct rpc_task *task, void *calldata) 1337static void nfs_commit_done(struct rpc_task *task, void *calldata)
1307{ 1338{
1308 struct nfs_write_data *data = calldata; 1339 struct nfs_write_data *data = calldata;
1309 struct nfs_page *req; 1340 struct nfs_page *req;
@@ -1312,6 +1343,10 @@ void nfs_commit_done(struct rpc_task *task, void *calldata)
1312 dprintk("NFS: %4d nfs_commit_done (status %d)\n", 1343 dprintk("NFS: %4d nfs_commit_done (status %d)\n",
1313 task->tk_pid, task->tk_status); 1344 task->tk_pid, task->tk_status);
1314 1345
1346 /* Call the NFS version-specific code */
1347 if (NFS_PROTO(data->inode)->commit_done(task, data) != 0)
1348 return;
1349
1315 while (!list_empty(&data->pages)) { 1350 while (!list_empty(&data->pages)) {
1316 req = nfs_list_entry(data->pages.next); 1351 req = nfs_list_entry(data->pages.next);
1317 nfs_list_remove_request(req); 1352 nfs_list_remove_request(req);
@@ -1345,6 +1380,11 @@ void nfs_commit_done(struct rpc_task *task, void *calldata)
1345 } 1380 }
1346 sub_page_state(nr_unstable,res); 1381 sub_page_state(nr_unstable,res);
1347} 1382}
1383
1384static const struct rpc_call_ops nfs_commit_ops = {
1385 .rpc_call_done = nfs_commit_done,
1386 .rpc_release = nfs_commit_release,
1387};
1348#endif 1388#endif
1349 1389
1350static int nfs_flush_inode(struct inode *inode, unsigned long idx_start, 1390static int nfs_flush_inode(struct inode *inode, unsigned long idx_start,
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index b71da4d4b137..782e59765696 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -407,13 +407,6 @@ extern int nfs_writepage(struct page *page, struct writeback_control *wbc);
407extern int nfs_writepages(struct address_space *, struct writeback_control *); 407extern int nfs_writepages(struct address_space *, struct writeback_control *);
408extern int nfs_flush_incompatible(struct file *file, struct page *page); 408extern int nfs_flush_incompatible(struct file *file, struct page *page);
409extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); 409extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
410extern void nfs_writeback_done(struct rpc_task *task, void *data);
411extern void nfs_writedata_release(void *data);
412
413#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
414extern void nfs_commit_done(struct rpc_task *, void *data);
415extern void nfs_commit_release(void *data);
416#endif
417 410
418/* 411/*
419 * Try to write back everything synchronously (but check the 412 * Try to write back everything synchronously (but check the
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 6d6f69ec5675..277750cc70c0 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -714,7 +714,6 @@ struct nfs_write_data {
714#ifdef CONFIG_NFS_V4 714#ifdef CONFIG_NFS_V4
715 unsigned long timestamp; /* For lease renewal */ 715 unsigned long timestamp; /* For lease renewal */
716#endif 716#endif
717 void (*complete) (struct nfs_write_data *, int);
718 struct page *page_array[NFS_PAGEVEC_SIZE + 1]; 717 struct page *page_array[NFS_PAGEVEC_SIZE + 1];
719}; 718};
720 719
@@ -770,7 +769,9 @@ struct nfs_rpc_ops {
770 u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus); 769 u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus);
771 void (*read_setup) (struct nfs_read_data *); 770 void (*read_setup) (struct nfs_read_data *);
772 void (*write_setup) (struct nfs_write_data *, int how); 771 void (*write_setup) (struct nfs_write_data *, int how);
772 int (*write_done) (struct rpc_task *, struct nfs_write_data *);
773 void (*commit_setup) (struct nfs_write_data *, int how); 773 void (*commit_setup) (struct nfs_write_data *, int how);
774 int (*commit_done) (struct rpc_task *, struct nfs_write_data *);
774 int (*file_open) (struct inode *, struct file *); 775 int (*file_open) (struct inode *, struct file *);
775 int (*file_release) (struct inode *, struct file *); 776 int (*file_release) (struct inode *, struct file *);
776 int (*lock)(struct file *, int, struct file_lock *); 777 int (*lock)(struct file *, int, struct file_lock *);