aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:04 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:39 -0500
commit963d8fe53339128ee46a7701f2e36305f0ccff8c (patch)
tree426736c70a8e05cb1d945d5c7f44ea6475edd113 /fs/nfs/nfs4proc.c
parentabbcf28f23d53e8ec56a91f3528743913fa2694a (diff)
RPC: Clean up RPC task structure
Shrink the RPC task structure. Instead of storing separate pointers for task->tk_exit and task->tk_release, put them in a structure. Also pass the user data pointer as a parameter instead of passing it via task->tk_calldata. This enables us to nest callbacks. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c107
1 files changed, 62 insertions, 45 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f988a9417b13..3d5d3c07d621 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -196,14 +196,12 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
196 196
197/* Helper for asynchronous RPC calls */ 197/* Helper for asynchronous RPC calls */
198static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin, 198static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin,
199 rpc_action tk_exit, void *calldata) 199 const struct rpc_call_ops *tk_ops, void *calldata)
200{ 200{
201 struct rpc_task *task; 201 struct rpc_task *task;
202 202
203 if (!(task = rpc_new_task(clnt, tk_exit, RPC_TASK_ASYNC))) 203 if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata)))
204 return -ENOMEM; 204 return -ENOMEM;
205
206 task->tk_calldata = calldata;
207 task->tk_action = tk_begin; 205 task->tk_action = tk_begin;
208 rpc_execute(task); 206 rpc_execute(task);
209 return 0; 207 return 0;
@@ -867,10 +865,10 @@ struct nfs4_closedata {
867 struct nfs_fattr fattr; 865 struct nfs_fattr fattr;
868}; 866};
869 867
870static void nfs4_free_closedata(struct nfs4_closedata *calldata) 868static void nfs4_free_closedata(void *data)
871{ 869{
872 struct nfs4_state *state = calldata->state; 870 struct nfs4_closedata *calldata = data;
873 struct nfs4_state_owner *sp = state->owner; 871 struct nfs4_state_owner *sp = calldata->state->owner;
874 872
875 nfs4_put_open_state(calldata->state); 873 nfs4_put_open_state(calldata->state);
876 nfs_free_seqid(calldata->arg.seqid); 874 nfs_free_seqid(calldata->arg.seqid);
@@ -878,9 +876,9 @@ static void nfs4_free_closedata(struct nfs4_closedata *calldata)
878 kfree(calldata); 876 kfree(calldata);
879} 877}
880 878
881static void nfs4_close_done(struct rpc_task *task) 879static void nfs4_close_done(struct rpc_task *task, void *data)
882{ 880{
883 struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata; 881 struct nfs4_closedata *calldata = data;
884 struct nfs4_state *state = calldata->state; 882 struct nfs4_state *state = calldata->state;
885 struct nfs_server *server = NFS_SERVER(calldata->inode); 883 struct nfs_server *server = NFS_SERVER(calldata->inode);
886 884
@@ -904,7 +902,6 @@ static void nfs4_close_done(struct rpc_task *task)
904 } 902 }
905 } 903 }
906 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 904 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
907 nfs4_free_closedata(calldata);
908} 905}
909 906
910static void nfs4_close_begin(struct rpc_task *task) 907static void nfs4_close_begin(struct rpc_task *task)
@@ -918,10 +915,8 @@ static void nfs4_close_begin(struct rpc_task *task)
918 .rpc_cred = state->owner->so_cred, 915 .rpc_cred = state->owner->so_cred,
919 }; 916 };
920 int mode = 0, old_mode; 917 int mode = 0, old_mode;
921 int status;
922 918
923 status = nfs_wait_on_sequence(calldata->arg.seqid, task); 919 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
924 if (status != 0)
925 return; 920 return;
926 /* Recalculate the new open mode in case someone reopened the file 921 /* Recalculate the new open mode in case someone reopened the file
927 * while we were waiting in line to be scheduled. 922 * while we were waiting in line to be scheduled.
@@ -937,9 +932,8 @@ static void nfs4_close_begin(struct rpc_task *task)
937 spin_unlock(&calldata->inode->i_lock); 932 spin_unlock(&calldata->inode->i_lock);
938 spin_unlock(&state->owner->so_lock); 933 spin_unlock(&state->owner->so_lock);
939 if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) { 934 if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) {
940 nfs4_free_closedata(calldata); 935 /* Note: exit _without_ calling nfs4_close_done */
941 task->tk_exit = NULL; 936 task->tk_action = NULL;
942 rpc_exit(task, 0);
943 return; 937 return;
944 } 938 }
945 nfs_fattr_init(calldata->res.fattr); 939 nfs_fattr_init(calldata->res.fattr);
@@ -949,6 +943,11 @@ static void nfs4_close_begin(struct rpc_task *task)
949 rpc_call_setup(task, &msg, 0); 943 rpc_call_setup(task, &msg, 0);
950} 944}
951 945
946static const struct rpc_call_ops nfs4_close_ops = {
947 .rpc_call_done = nfs4_close_done,
948 .rpc_release = nfs4_free_closedata,
949};
950
952/* 951/*
953 * It is possible for data to be read/written from a mem-mapped file 952 * It is possible for data to be read/written from a mem-mapped file
954 * after the sys_close call (which hits the vfs layer as a flush). 953 * after the sys_close call (which hits the vfs layer as a flush).
@@ -982,7 +981,7 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
982 calldata->res.server = server; 981 calldata->res.server = server;
983 982
984 status = nfs4_call_async(server->client, nfs4_close_begin, 983 status = nfs4_call_async(server->client, nfs4_close_begin,
985 nfs4_close_done, calldata); 984 &nfs4_close_ops, calldata);
986 if (status == 0) 985 if (status == 0)
987 goto out; 986 goto out;
988 987
@@ -2125,10 +2124,9 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
2125 return err; 2124 return err;
2126} 2125}
2127 2126
2128static void 2127static void nfs4_read_done(struct rpc_task *task, void *calldata)
2129nfs4_read_done(struct rpc_task *task)
2130{ 2128{
2131 struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; 2129 struct nfs_read_data *data = calldata;
2132 struct inode *inode = data->inode; 2130 struct inode *inode = data->inode;
2133 2131
2134 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2132 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
@@ -2138,9 +2136,14 @@ nfs4_read_done(struct rpc_task *task)
2138 if (task->tk_status > 0) 2136 if (task->tk_status > 0)
2139 renew_lease(NFS_SERVER(inode), data->timestamp); 2137 renew_lease(NFS_SERVER(inode), data->timestamp);
2140 /* Call back common NFS readpage processing */ 2138 /* Call back common NFS readpage processing */
2141 nfs_readpage_result(task); 2139 nfs_readpage_result(task, calldata);
2142} 2140}
2143 2141
2142static const struct rpc_call_ops nfs4_read_ops = {
2143 .rpc_call_done = nfs4_read_done,
2144 .rpc_release = nfs_readdata_release,
2145};
2146
2144static void 2147static void
2145nfs4_proc_read_setup(struct nfs_read_data *data) 2148nfs4_proc_read_setup(struct nfs_read_data *data)
2146{ 2149{
@@ -2160,14 +2163,13 @@ nfs4_proc_read_setup(struct nfs_read_data *data)
2160 flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); 2163 flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
2161 2164
2162 /* Finalize the task. */ 2165 /* Finalize the task. */
2163 rpc_init_task(task, NFS_CLIENT(inode), nfs4_read_done, flags); 2166 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_read_ops, data);
2164 rpc_call_setup(task, &msg, 0); 2167 rpc_call_setup(task, &msg, 0);
2165} 2168}
2166 2169
2167static void 2170static void nfs4_write_done(struct rpc_task *task, void *calldata)
2168nfs4_write_done(struct rpc_task *task)
2169{ 2171{
2170 struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; 2172 struct nfs_write_data *data = calldata;
2171 struct inode *inode = data->inode; 2173 struct inode *inode = data->inode;
2172 2174
2173 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2175 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
@@ -2179,9 +2181,14 @@ nfs4_write_done(struct rpc_task *task)
2179 nfs_post_op_update_inode(inode, data->res.fattr); 2181 nfs_post_op_update_inode(inode, data->res.fattr);
2180 } 2182 }
2181 /* Call back common NFS writeback processing */ 2183 /* Call back common NFS writeback processing */
2182 nfs_writeback_done(task); 2184 nfs_writeback_done(task, calldata);
2183} 2185}
2184 2186
2187static const struct rpc_call_ops nfs4_write_ops = {
2188 .rpc_call_done = nfs4_write_done,
2189 .rpc_release = nfs_writedata_release,
2190};
2191
2185static void 2192static void
2186nfs4_proc_write_setup(struct nfs_write_data *data, int how) 2193nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2187{ 2194{
@@ -2214,14 +2221,13 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how)
2214 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; 2221 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
2215 2222
2216 /* Finalize the task. */ 2223 /* Finalize the task. */
2217 rpc_init_task(task, NFS_CLIENT(inode), nfs4_write_done, flags); 2224 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_write_ops, data);
2218 rpc_call_setup(task, &msg, 0); 2225 rpc_call_setup(task, &msg, 0);
2219} 2226}
2220 2227
2221static void 2228static void nfs4_commit_done(struct rpc_task *task, void *calldata)
2222nfs4_commit_done(struct rpc_task *task)
2223{ 2229{
2224 struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; 2230 struct nfs_write_data *data = calldata;
2225 struct inode *inode = data->inode; 2231 struct inode *inode = data->inode;
2226 2232
2227 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2233 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
@@ -2231,9 +2237,14 @@ nfs4_commit_done(struct rpc_task *task)
2231 if (task->tk_status >= 0) 2237 if (task->tk_status >= 0)
2232 nfs_post_op_update_inode(inode, data->res.fattr); 2238 nfs_post_op_update_inode(inode, data->res.fattr);
2233 /* Call back common NFS writeback processing */ 2239 /* Call back common NFS writeback processing */
2234 nfs_commit_done(task); 2240 nfs_commit_done(task, calldata);
2235} 2241}
2236 2242
2243static const struct rpc_call_ops nfs4_commit_ops = {
2244 .rpc_call_done = nfs4_commit_done,
2245 .rpc_release = nfs_commit_release,
2246};
2247
2237static void 2248static void
2238nfs4_proc_commit_setup(struct nfs_write_data *data, int how) 2249nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2239{ 2250{
@@ -2255,7 +2266,7 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2255 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; 2266 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
2256 2267
2257 /* Finalize the task. */ 2268 /* Finalize the task. */
2258 rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags); 2269 rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_commit_ops, data);
2259 rpc_call_setup(task, &msg, 0); 2270 rpc_call_setup(task, &msg, 0);
2260} 2271}
2261 2272
@@ -2263,11 +2274,10 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2263 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special 2274 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
2264 * standalone procedure for queueing an asynchronous RENEW. 2275 * standalone procedure for queueing an asynchronous RENEW.
2265 */ 2276 */
2266static void 2277static void nfs4_renew_done(struct rpc_task *task, void *data)
2267renew_done(struct rpc_task *task)
2268{ 2278{
2269 struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; 2279 struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
2270 unsigned long timestamp = (unsigned long)task->tk_calldata; 2280 unsigned long timestamp = (unsigned long)data;
2271 2281
2272 if (task->tk_status < 0) { 2282 if (task->tk_status < 0) {
2273 switch (task->tk_status) { 2283 switch (task->tk_status) {
@@ -2284,6 +2294,10 @@ renew_done(struct rpc_task *task)
2284 spin_unlock(&clp->cl_lock); 2294 spin_unlock(&clp->cl_lock);
2285} 2295}
2286 2296
2297static const struct rpc_call_ops nfs4_renew_ops = {
2298 .rpc_call_done = nfs4_renew_done,
2299};
2300
2287int 2301int
2288nfs4_proc_async_renew(struct nfs4_client *clp) 2302nfs4_proc_async_renew(struct nfs4_client *clp)
2289{ 2303{
@@ -2294,7 +2308,7 @@ nfs4_proc_async_renew(struct nfs4_client *clp)
2294 }; 2308 };
2295 2309
2296 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, 2310 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
2297 renew_done, (void *)jiffies); 2311 &nfs4_renew_ops, (void *)jiffies);
2298} 2312}
2299 2313
2300int 2314int
@@ -2866,15 +2880,16 @@ static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata)
2866 } 2880 }
2867} 2881}
2868 2882
2869static void nfs4_locku_complete(struct nfs4_unlockdata *calldata) 2883static void nfs4_locku_complete(void *data)
2870{ 2884{
2885 struct nfs4_unlockdata *calldata = data;
2871 complete(&calldata->completion); 2886 complete(&calldata->completion);
2872 nfs4_locku_release_calldata(calldata); 2887 nfs4_locku_release_calldata(calldata);
2873} 2888}
2874 2889
2875static void nfs4_locku_done(struct rpc_task *task) 2890static void nfs4_locku_done(struct rpc_task *task, void *data)
2876{ 2891{
2877 struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata; 2892 struct nfs4_unlockdata *calldata = data;
2878 2893
2879 nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid); 2894 nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid);
2880 switch (task->tk_status) { 2895 switch (task->tk_status) {
@@ -2890,10 +2905,8 @@ static void nfs4_locku_done(struct rpc_task *task)
2890 default: 2905 default:
2891 if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) { 2906 if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) {
2892 rpc_restart_call(task); 2907 rpc_restart_call(task);
2893 return;
2894 } 2908 }
2895 } 2909 }
2896 nfs4_locku_complete(calldata);
2897} 2910}
2898 2911
2899static void nfs4_locku_begin(struct rpc_task *task) 2912static void nfs4_locku_begin(struct rpc_task *task)
@@ -2911,14 +2924,18 @@ static void nfs4_locku_begin(struct rpc_task *task)
2911 if (status != 0) 2924 if (status != 0)
2912 return; 2925 return;
2913 if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) { 2926 if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
2914 nfs4_locku_complete(calldata); 2927 /* Note: exit _without_ running nfs4_locku_done */
2915 task->tk_exit = NULL; 2928 task->tk_action = NULL;
2916 rpc_exit(task, 0);
2917 return; 2929 return;
2918 } 2930 }
2919 rpc_call_setup(task, &msg, 0); 2931 rpc_call_setup(task, &msg, 0);
2920} 2932}
2921 2933
2934static const struct rpc_call_ops nfs4_locku_ops = {
2935 .rpc_call_done = nfs4_locku_done,
2936 .rpc_release = nfs4_locku_complete,
2937};
2938
2922static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) 2939static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
2923{ 2940{
2924 struct nfs4_unlockdata *calldata; 2941 struct nfs4_unlockdata *calldata;
@@ -2963,7 +2980,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
2963 init_completion(&calldata->completion); 2980 init_completion(&calldata->completion);
2964 2981
2965 status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin, 2982 status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin,
2966 nfs4_locku_done, calldata); 2983 &nfs4_locku_ops, calldata);
2967 if (status == 0) 2984 if (status == 0)
2968 wait_for_completion_interruptible(&calldata->completion); 2985 wait_for_completion_interruptible(&calldata->completion);
2969 do_vfs_lock(request->fl_file, request); 2986 do_vfs_lock(request->fl_file, request);