diff options
-rw-r--r-- | fs/nfs/nfs4proc.c | 21 | ||||
-rw-r--r-- | fs/nfs/unlink.c | 13 | ||||
-rw-r--r-- | include/linux/sunrpc/sched.h | 1 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 10 |
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 */ |
198 | static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin, | 198 | static 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 | ||
907 | static void nfs4_close_begin(struct rpc_task *task) | 908 | static 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 | ||
946 | static const struct rpc_call_ops nfs4_close_ops = { | 947 | static 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 | ||
2912 | static void nfs4_locku_begin(struct rpc_task *task) | 2913 | static 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 | ||
2934 | static const struct rpc_call_ops nfs4_locku_ops = { | 2935 | static 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 | */ |
90 | static void | 90 | static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) |
91 | nfs_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 | ||
149 | static const struct rpc_call_ops nfs_unlink_ops = { | 148 | static 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 { | |||
112 | typedef void (*rpc_action)(struct rpc_task *); | 112 | typedef void (*rpc_action)(struct rpc_task *); |
113 | 113 | ||
114 | struct rpc_call_ops { | 114 | struct 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 | */ | ||
560 | static 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 | */ |
560 | void rpc_exit_task(struct rpc_task *task) | 568 | void 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 */ |