aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs3proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:27 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:27 -0500
commit788e7a89a03e364855583c0ab4649b94925efbb9 (patch)
tree4434c93af133a92f550ba0ecc8d3254cb222e72d /fs/nfs/nfs3proc.c
parent7117bf3dfb10b534a017260d9fc643bc1d0afd2a (diff)
NFS: Cleanup of NFS write code in preparation for asynchronous o_direct
This patch inverts the callback hierarchy for NFS write calls. Instead of having the NFSv2/v3/v4-specific code set up the RPC callback ops, we allow the original caller to do so. This allows for more flexibility w.r.t. how to set up and tear down the nfs_write_data structure while still allowing the NFSv3/v4 code to perform error handling. The greater flexibility is needed by the asynchronous O_DIRECT code, which wants to be able to hold on to the original nfs_write_data structures after the WRITE RPC call has completed in order to be able to replay them if the COMMIT call determines that the server has rebooted. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs3proc.c')
-rw-r--r--fs/nfs/nfs3proc.c66
1 files changed, 17 insertions, 49 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,