aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c21
-rw-r--r--fs/nfs/unlink.c13
-rw-r--r--include/linux/sunrpc/sched.h1
-rw-r--r--net/sunrpc/sched.c10
4 files changed, 27 insertions, 18 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3d5d3c07d621..368b75b3bcba 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -195,14 +195,13 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
195} 195}
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,
199 const struct rpc_call_ops *tk_ops, 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, RPC_TASK_ASYNC, tk_ops, calldata))) 203 if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata)))
204 return -ENOMEM; 204 return -ENOMEM;
205 task->tk_action = tk_begin;
206 rpc_execute(task); 205 rpc_execute(task);
207 return 0; 206 return 0;
208} 207}
@@ -882,6 +881,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
882 struct nfs4_state *state = calldata->state; 881 struct nfs4_state *state = calldata->state;
883 struct nfs_server *server = NFS_SERVER(calldata->inode); 882 struct nfs_server *server = NFS_SERVER(calldata->inode);
884 883
884 if (RPC_ASSASSINATED(task))
885 return;
885 /* hmm. we are done with the inode, and in the process of freeing 886 /* hmm. we are done with the inode, and in the process of freeing
886 * the state_owner. we keep this around to process errors 887 * the state_owner. we keep this around to process errors
887 */ 888 */
@@ -904,9 +905,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
904 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 905 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
905} 906}
906 907
907static void nfs4_close_begin(struct rpc_task *task) 908static void nfs4_close_prepare(struct rpc_task *task, void *data)
908{ 909{
909 struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata; 910 struct nfs4_closedata *calldata = data;
910 struct nfs4_state *state = calldata->state; 911 struct nfs4_state *state = calldata->state;
911 struct rpc_message msg = { 912 struct rpc_message msg = {
912 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE], 913 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
@@ -944,6 +945,7 @@ static void nfs4_close_begin(struct rpc_task *task)
944} 945}
945 946
946static const struct rpc_call_ops nfs4_close_ops = { 947static const struct rpc_call_ops nfs4_close_ops = {
948 .rpc_call_prepare = nfs4_close_prepare,
947 .rpc_call_done = nfs4_close_done, 949 .rpc_call_done = nfs4_close_done,
948 .rpc_release = nfs4_free_closedata, 950 .rpc_release = nfs4_free_closedata,
949}; 951};
@@ -980,8 +982,7 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
980 calldata->res.fattr = &calldata->fattr; 982 calldata->res.fattr = &calldata->fattr;
981 calldata->res.server = server; 983 calldata->res.server = server;
982 984
983 status = nfs4_call_async(server->client, nfs4_close_begin, 985 status = nfs4_call_async(server->client, &nfs4_close_ops, calldata);
984 &nfs4_close_ops, calldata);
985 if (status == 0) 986 if (status == 0)
986 goto out; 987 goto out;
987 988
@@ -2909,9 +2910,9 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
2909 } 2910 }
2910} 2911}
2911 2912
2912static void nfs4_locku_begin(struct rpc_task *task) 2913static void nfs4_locku_prepare(struct rpc_task *task, void *data)
2913{ 2914{
2914 struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata; 2915 struct nfs4_unlockdata *calldata = data;
2915 struct rpc_message msg = { 2916 struct rpc_message msg = {
2916 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU], 2917 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
2917 .rpc_argp = &calldata->arg, 2918 .rpc_argp = &calldata->arg,
@@ -2932,6 +2933,7 @@ static void nfs4_locku_begin(struct rpc_task *task)
2932} 2933}
2933 2934
2934static const struct rpc_call_ops nfs4_locku_ops = { 2935static const struct rpc_call_ops nfs4_locku_ops = {
2936 .rpc_call_prepare = nfs4_locku_prepare,
2935 .rpc_call_done = nfs4_locku_done, 2937 .rpc_call_done = nfs4_locku_done,
2936 .rpc_release = nfs4_locku_complete, 2938 .rpc_release = nfs4_locku_complete,
2937}; 2939};
@@ -2979,8 +2981,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
2979 atomic_set(&calldata->refcount, 2); 2981 atomic_set(&calldata->refcount, 2);
2980 init_completion(&calldata->completion); 2982 init_completion(&calldata->completion);
2981 2983
2982 status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin, 2984 status = nfs4_call_async(NFS_SERVER(inode)->client, &nfs4_locku_ops, calldata);
2983 &nfs4_locku_ops, calldata);
2984 if (status == 0) 2985 if (status == 0)
2985 wait_for_completion_interruptible(&calldata->completion); 2986 wait_for_completion_interruptible(&calldata->completion);
2986 do_vfs_lock(request->fl_file, request); 2987 do_vfs_lock(request->fl_file, request);
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 1494484ba86d..a65c7b53d558 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -87,10 +87,9 @@ nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data)
87 * We delay initializing RPC info until after the call to dentry_iput() 87 * We delay initializing RPC info until after the call to dentry_iput()
88 * in order to minimize races against rename(). 88 * in order to minimize races against rename().
89 */ 89 */
90static void 90static void nfs_async_unlink_init(struct rpc_task *task, void *calldata)
91nfs_async_unlink_init(struct rpc_task *task)
92{ 91{
93 struct nfs_unlinkdata *data = (struct nfs_unlinkdata *)task->tk_calldata; 92 struct nfs_unlinkdata *data = calldata;
94 struct dentry *dir = data->dir; 93 struct dentry *dir = data->dir;
95 struct rpc_message msg = { 94 struct rpc_message msg = {
96 .rpc_cred = data->cred, 95 .rpc_cred = data->cred,
@@ -147,6 +146,7 @@ static void nfs_async_unlink_release(void *calldata)
147} 146}
148 147
149static const struct rpc_call_ops nfs_unlink_ops = { 148static const struct rpc_call_ops nfs_unlink_ops = {
149 .rpc_call_prepare = nfs_async_unlink_init,
150 .rpc_call_done = nfs_async_unlink_done, 150 .rpc_call_done = nfs_async_unlink_done,
151 .rpc_release = nfs_async_unlink_release, 151 .rpc_release = nfs_async_unlink_release,
152}; 152};
@@ -160,7 +160,6 @@ nfs_async_unlink(struct dentry *dentry)
160{ 160{
161 struct dentry *dir = dentry->d_parent; 161 struct dentry *dir = dentry->d_parent;
162 struct nfs_unlinkdata *data; 162 struct nfs_unlinkdata *data;
163 struct rpc_task *task;
164 struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode); 163 struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode);
165 int status = -ENOMEM; 164 int status = -ENOMEM;
166 165
@@ -181,15 +180,13 @@ nfs_async_unlink(struct dentry *dentry)
181 nfs_deletes = data; 180 nfs_deletes = data;
182 data->count = 1; 181 data->count = 1;
183 182
184 task = &data->task; 183 rpc_init_task(&data->task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data);
185 rpc_init_task(task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data);
186 task->tk_action = nfs_async_unlink_init;
187 184
188 spin_lock(&dentry->d_lock); 185 spin_lock(&dentry->d_lock);
189 dentry->d_flags |= DCACHE_NFSFS_RENAMED; 186 dentry->d_flags |= DCACHE_NFSFS_RENAMED;
190 spin_unlock(&dentry->d_lock); 187 spin_unlock(&dentry->d_lock);
191 188
192 rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL); 189 rpc_sleep_on(&nfs_delete_queue, &data->task, NULL, NULL);
193 status = 0; 190 status = 0;
194 out: 191 out:
195 return status; 192 return status;
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 581d8cdc3b86..ac1326fc3e1a 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -112,6 +112,7 @@ struct rpc_task {
112typedef void (*rpc_action)(struct rpc_task *); 112typedef void (*rpc_action)(struct rpc_task *);
113 113
114struct rpc_call_ops { 114struct rpc_call_ops {
115 void (*rpc_call_prepare)(struct rpc_task *, void *);
115 void (*rpc_call_done)(struct rpc_task *, void *); 116 void (*rpc_call_done)(struct rpc_task *, void *);
116 void (*rpc_release)(void *); 117 void (*rpc_release)(void *);
117}; 118};
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 8d6233d3248b..2d74a1672028 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -555,6 +555,14 @@ __rpc_atrun(struct rpc_task *task)
555} 555}
556 556
557/* 557/*
558 * Helper to call task->tk_ops->rpc_call_prepare
559 */
560static void rpc_prepare_task(struct rpc_task *task)
561{
562 task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
563}
564
565/*
558 * Helper that calls task->tk_ops->rpc_call_done if it exists 566 * Helper that calls task->tk_ops->rpc_call_done if it exists
559 */ 567 */
560void rpc_exit_task(struct rpc_task *task) 568void rpc_exit_task(struct rpc_task *task)
@@ -756,6 +764,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
756 task->tk_client = clnt; 764 task->tk_client = clnt;
757 task->tk_flags = flags; 765 task->tk_flags = flags;
758 task->tk_ops = tk_ops; 766 task->tk_ops = tk_ops;
767 if (tk_ops->rpc_call_prepare != NULL)
768 task->tk_action = rpc_prepare_task;
759 task->tk_calldata = calldata; 769 task->tk_calldata = calldata;
760 770
761 /* Initialize retry counters */ 771 /* Initialize retry counters */