diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/sunrpc/clnt.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 735 |
1 files changed, 172 insertions, 563 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 507b5e84fbd..c5347d29cfb 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> | 17 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <asm/system.h> | ||
20 | 21 | ||
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/types.h> | 23 | #include <linux/types.h> |
@@ -30,16 +31,13 @@ | |||
30 | #include <linux/in.h> | 31 | #include <linux/in.h> |
31 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
32 | #include <linux/un.h> | 33 | #include <linux/un.h> |
33 | #include <linux/rcupdate.h> | ||
34 | 34 | ||
35 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
36 | #include <linux/sunrpc/rpc_pipe_fs.h> | 36 | #include <linux/sunrpc/rpc_pipe_fs.h> |
37 | #include <linux/sunrpc/metrics.h> | 37 | #include <linux/sunrpc/metrics.h> |
38 | #include <linux/sunrpc/bc_xprt.h> | 38 | #include <linux/sunrpc/bc_xprt.h> |
39 | #include <trace/events/sunrpc.h> | ||
40 | 39 | ||
41 | #include "sunrpc.h" | 40 | #include "sunrpc.h" |
42 | #include "netns.h" | ||
43 | 41 | ||
44 | #ifdef RPC_DEBUG | 42 | #ifdef RPC_DEBUG |
45 | # define RPCDBG_FACILITY RPCDBG_CALL | 43 | # define RPCDBG_FACILITY RPCDBG_CALL |
@@ -52,6 +50,8 @@ | |||
52 | /* | 50 | /* |
53 | * All RPC clients are linked into this list | 51 | * All RPC clients are linked into this list |
54 | */ | 52 | */ |
53 | static LIST_HEAD(all_clients); | ||
54 | static DEFINE_SPINLOCK(rpc_client_lock); | ||
55 | 55 | ||
56 | static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); | 56 | static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); |
57 | 57 | ||
@@ -81,222 +81,82 @@ static int rpc_ping(struct rpc_clnt *clnt); | |||
81 | 81 | ||
82 | static void rpc_register_client(struct rpc_clnt *clnt) | 82 | static void rpc_register_client(struct rpc_clnt *clnt) |
83 | { | 83 | { |
84 | struct net *net = rpc_net_ns(clnt); | 84 | spin_lock(&rpc_client_lock); |
85 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | 85 | list_add(&clnt->cl_clients, &all_clients); |
86 | 86 | spin_unlock(&rpc_client_lock); | |
87 | spin_lock(&sn->rpc_client_lock); | ||
88 | list_add(&clnt->cl_clients, &sn->all_clients); | ||
89 | spin_unlock(&sn->rpc_client_lock); | ||
90 | } | 87 | } |
91 | 88 | ||
92 | static void rpc_unregister_client(struct rpc_clnt *clnt) | 89 | static void rpc_unregister_client(struct rpc_clnt *clnt) |
93 | { | 90 | { |
94 | struct net *net = rpc_net_ns(clnt); | 91 | spin_lock(&rpc_client_lock); |
95 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
96 | |||
97 | spin_lock(&sn->rpc_client_lock); | ||
98 | list_del(&clnt->cl_clients); | 92 | list_del(&clnt->cl_clients); |
99 | spin_unlock(&sn->rpc_client_lock); | 93 | spin_unlock(&rpc_client_lock); |
100 | } | ||
101 | |||
102 | static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) | ||
103 | { | ||
104 | if (clnt->cl_dentry) { | ||
105 | if (clnt->cl_auth && clnt->cl_auth->au_ops->pipes_destroy) | ||
106 | clnt->cl_auth->au_ops->pipes_destroy(clnt->cl_auth); | ||
107 | rpc_remove_client_dir(clnt->cl_dentry); | ||
108 | } | ||
109 | clnt->cl_dentry = NULL; | ||
110 | } | 94 | } |
111 | 95 | ||
112 | static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) | 96 | static int |
113 | { | 97 | rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) |
114 | struct net *net = rpc_net_ns(clnt); | ||
115 | struct super_block *pipefs_sb; | ||
116 | |||
117 | pipefs_sb = rpc_get_sb_net(net); | ||
118 | if (pipefs_sb) { | ||
119 | __rpc_clnt_remove_pipedir(clnt); | ||
120 | rpc_put_sb_net(net); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb, | ||
125 | struct rpc_clnt *clnt, | ||
126 | const char *dir_name) | ||
127 | { | 98 | { |
128 | static uint32_t clntid; | 99 | static uint32_t clntid; |
100 | struct path path, dir; | ||
129 | char name[15]; | 101 | char name[15]; |
130 | struct qstr q = { .name = name }; | 102 | struct qstr q = { |
131 | struct dentry *dir, *dentry; | 103 | .name = name, |
104 | }; | ||
132 | int error; | 105 | int error; |
133 | 106 | ||
134 | dir = rpc_d_lookup_sb(sb, dir_name); | 107 | clnt->cl_path.mnt = ERR_PTR(-ENOENT); |
135 | if (dir == NULL) { | 108 | clnt->cl_path.dentry = ERR_PTR(-ENOENT); |
136 | pr_info("RPC: pipefs directory doesn't exist: %s\n", dir_name); | 109 | if (dir_name == NULL) |
137 | return dir; | 110 | return 0; |
138 | } | 111 | |
112 | path.mnt = rpc_get_mount(); | ||
113 | if (IS_ERR(path.mnt)) | ||
114 | return PTR_ERR(path.mnt); | ||
115 | error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &dir); | ||
116 | if (error) | ||
117 | goto err; | ||
118 | |||
139 | for (;;) { | 119 | for (;;) { |
140 | q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++); | 120 | q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++); |
141 | name[sizeof(name) - 1] = '\0'; | 121 | name[sizeof(name) - 1] = '\0'; |
142 | q.hash = full_name_hash(q.name, q.len); | 122 | q.hash = full_name_hash(q.name, q.len); |
143 | dentry = rpc_create_client_dir(dir, &q, clnt); | 123 | path.dentry = rpc_create_client_dir(dir.dentry, &q, clnt); |
144 | if (!IS_ERR(dentry)) | 124 | if (!IS_ERR(path.dentry)) |
145 | break; | 125 | break; |
146 | error = PTR_ERR(dentry); | 126 | error = PTR_ERR(path.dentry); |
147 | if (error != -EEXIST) { | 127 | if (error != -EEXIST) { |
148 | printk(KERN_INFO "RPC: Couldn't create pipefs entry" | 128 | printk(KERN_INFO "RPC: Couldn't create pipefs entry" |
149 | " %s/%s, error %d\n", | 129 | " %s/%s, error %d\n", |
150 | dir_name, name, error); | 130 | dir_name, name, error); |
151 | break; | 131 | goto err_path_put; |
152 | } | 132 | } |
153 | } | 133 | } |
154 | dput(dir); | 134 | path_put(&dir); |
155 | return dentry; | 135 | clnt->cl_path = path; |
156 | } | ||
157 | |||
158 | static int | ||
159 | rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) | ||
160 | { | ||
161 | struct net *net = rpc_net_ns(clnt); | ||
162 | struct super_block *pipefs_sb; | ||
163 | struct dentry *dentry; | ||
164 | |||
165 | clnt->cl_dentry = NULL; | ||
166 | if (dir_name == NULL) | ||
167 | return 0; | ||
168 | pipefs_sb = rpc_get_sb_net(net); | ||
169 | if (!pipefs_sb) | ||
170 | return 0; | ||
171 | dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name); | ||
172 | rpc_put_sb_net(net); | ||
173 | if (IS_ERR(dentry)) | ||
174 | return PTR_ERR(dentry); | ||
175 | clnt->cl_dentry = dentry; | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) | ||
180 | { | ||
181 | if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || | ||
182 | ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) | ||
183 | return 1; | ||
184 | return 0; | 136 | return 0; |
185 | } | 137 | err_path_put: |
186 | 138 | path_put(&dir); | |
187 | static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event, | 139 | err: |
188 | struct super_block *sb) | 140 | rpc_put_mount(); |
189 | { | ||
190 | struct dentry *dentry; | ||
191 | int err = 0; | ||
192 | |||
193 | switch (event) { | ||
194 | case RPC_PIPEFS_MOUNT: | ||
195 | dentry = rpc_setup_pipedir_sb(sb, clnt, | ||
196 | clnt->cl_program->pipe_dir_name); | ||
197 | if (!dentry) | ||
198 | return -ENOENT; | ||
199 | if (IS_ERR(dentry)) | ||
200 | return PTR_ERR(dentry); | ||
201 | clnt->cl_dentry = dentry; | ||
202 | if (clnt->cl_auth->au_ops->pipes_create) { | ||
203 | err = clnt->cl_auth->au_ops->pipes_create(clnt->cl_auth); | ||
204 | if (err) | ||
205 | __rpc_clnt_remove_pipedir(clnt); | ||
206 | } | ||
207 | break; | ||
208 | case RPC_PIPEFS_UMOUNT: | ||
209 | __rpc_clnt_remove_pipedir(clnt); | ||
210 | break; | ||
211 | default: | ||
212 | printk(KERN_ERR "%s: unknown event: %ld\n", __func__, event); | ||
213 | return -ENOTSUPP; | ||
214 | } | ||
215 | return err; | ||
216 | } | ||
217 | |||
218 | static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, | ||
219 | struct super_block *sb) | ||
220 | { | ||
221 | int error = 0; | ||
222 | |||
223 | for (;; clnt = clnt->cl_parent) { | ||
224 | if (!rpc_clnt_skip_event(clnt, event)) | ||
225 | error = __rpc_clnt_handle_event(clnt, event, sb); | ||
226 | if (error || clnt == clnt->cl_parent) | ||
227 | break; | ||
228 | } | ||
229 | return error; | ||
230 | } | ||
231 | |||
232 | static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) | ||
233 | { | ||
234 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
235 | struct rpc_clnt *clnt; | ||
236 | |||
237 | spin_lock(&sn->rpc_client_lock); | ||
238 | list_for_each_entry(clnt, &sn->all_clients, cl_clients) { | ||
239 | if (clnt->cl_program->pipe_dir_name == NULL) | ||
240 | continue; | ||
241 | if (rpc_clnt_skip_event(clnt, event)) | ||
242 | continue; | ||
243 | if (atomic_inc_not_zero(&clnt->cl_count) == 0) | ||
244 | continue; | ||
245 | spin_unlock(&sn->rpc_client_lock); | ||
246 | return clnt; | ||
247 | } | ||
248 | spin_unlock(&sn->rpc_client_lock); | ||
249 | return NULL; | ||
250 | } | ||
251 | |||
252 | static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, | ||
253 | void *ptr) | ||
254 | { | ||
255 | struct super_block *sb = ptr; | ||
256 | struct rpc_clnt *clnt; | ||
257 | int error = 0; | ||
258 | |||
259 | while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { | ||
260 | error = __rpc_pipefs_event(clnt, event, sb); | ||
261 | rpc_release_client(clnt); | ||
262 | if (error) | ||
263 | break; | ||
264 | } | ||
265 | return error; | 141 | return error; |
266 | } | 142 | } |
267 | 143 | ||
268 | static struct notifier_block rpc_clients_block = { | ||
269 | .notifier_call = rpc_pipefs_event, | ||
270 | .priority = SUNRPC_PIPEFS_RPC_PRIO, | ||
271 | }; | ||
272 | |||
273 | int rpc_clients_notifier_register(void) | ||
274 | { | ||
275 | return rpc_pipefs_notifier_register(&rpc_clients_block); | ||
276 | } | ||
277 | |||
278 | void rpc_clients_notifier_unregister(void) | ||
279 | { | ||
280 | return rpc_pipefs_notifier_unregister(&rpc_clients_block); | ||
281 | } | ||
282 | |||
283 | static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename) | ||
284 | { | ||
285 | clnt->cl_nodelen = strlen(nodename); | ||
286 | if (clnt->cl_nodelen > UNX_MAXNODENAME) | ||
287 | clnt->cl_nodelen = UNX_MAXNODENAME; | ||
288 | memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); | ||
289 | } | ||
290 | |||
291 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) | 144 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
292 | { | 145 | { |
293 | const struct rpc_program *program = args->program; | 146 | struct rpc_program *program = args->program; |
294 | const struct rpc_version *version; | 147 | struct rpc_version *version; |
295 | struct rpc_clnt *clnt = NULL; | 148 | struct rpc_clnt *clnt = NULL; |
296 | struct rpc_auth *auth; | 149 | struct rpc_auth *auth; |
297 | int err; | 150 | int err; |
151 | size_t len; | ||
298 | 152 | ||
299 | /* sanity check the name before trying to print it */ | 153 | /* sanity check the name before trying to print it */ |
154 | err = -EINVAL; | ||
155 | len = strlen(args->servername); | ||
156 | if (len > RPC_MAXNETNAMELEN) | ||
157 | goto out_no_rpciod; | ||
158 | len++; | ||
159 | |||
300 | dprintk("RPC: creating %s client for %s (xprt %p)\n", | 160 | dprintk("RPC: creating %s client for %s (xprt %p)\n", |
301 | program->name, args->servername, xprt); | 161 | program->name, args->servername, xprt); |
302 | 162 | ||
@@ -319,7 +179,17 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
319 | goto out_err; | 179 | goto out_err; |
320 | clnt->cl_parent = clnt; | 180 | clnt->cl_parent = clnt; |
321 | 181 | ||
322 | rcu_assign_pointer(clnt->cl_xprt, xprt); | 182 | clnt->cl_server = clnt->cl_inline_name; |
183 | if (len > sizeof(clnt->cl_inline_name)) { | ||
184 | char *buf = kmalloc(len, GFP_KERNEL); | ||
185 | if (buf != NULL) | ||
186 | clnt->cl_server = buf; | ||
187 | else | ||
188 | len = sizeof(clnt->cl_inline_name); | ||
189 | } | ||
190 | strlcpy(clnt->cl_server, args->servername, len); | ||
191 | |||
192 | clnt->cl_xprt = xprt; | ||
323 | clnt->cl_procinfo = version->procs; | 193 | clnt->cl_procinfo = version->procs; |
324 | clnt->cl_maxproc = version->nrprocs; | 194 | clnt->cl_maxproc = version->nrprocs; |
325 | clnt->cl_protname = program->name; | 195 | clnt->cl_protname = program->name; |
@@ -334,7 +204,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
334 | INIT_LIST_HEAD(&clnt->cl_tasks); | 204 | INIT_LIST_HEAD(&clnt->cl_tasks); |
335 | spin_lock_init(&clnt->cl_lock); | 205 | spin_lock_init(&clnt->cl_lock); |
336 | 206 | ||
337 | if (!xprt_bound(xprt)) | 207 | if (!xprt_bound(clnt->cl_xprt)) |
338 | clnt->cl_autobind = 1; | 208 | clnt->cl_autobind = 1; |
339 | 209 | ||
340 | clnt->cl_timeout = xprt->timeout; | 210 | clnt->cl_timeout = xprt->timeout; |
@@ -368,17 +238,25 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
368 | } | 238 | } |
369 | 239 | ||
370 | /* save the nodename */ | 240 | /* save the nodename */ |
371 | rpc_clnt_set_nodename(clnt, utsname()->nodename); | 241 | clnt->cl_nodelen = strlen(init_utsname()->nodename); |
242 | if (clnt->cl_nodelen > UNX_MAXNODENAME) | ||
243 | clnt->cl_nodelen = UNX_MAXNODENAME; | ||
244 | memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen); | ||
372 | rpc_register_client(clnt); | 245 | rpc_register_client(clnt); |
373 | return clnt; | 246 | return clnt; |
374 | 247 | ||
375 | out_no_auth: | 248 | out_no_auth: |
376 | rpc_clnt_remove_pipedir(clnt); | 249 | if (!IS_ERR(clnt->cl_path.dentry)) { |
250 | rpc_remove_client_dir(clnt->cl_path.dentry); | ||
251 | rpc_put_mount(); | ||
252 | } | ||
377 | out_no_path: | 253 | out_no_path: |
378 | kfree(clnt->cl_principal); | 254 | kfree(clnt->cl_principal); |
379 | out_no_principal: | 255 | out_no_principal: |
380 | rpc_free_iostats(clnt->cl_metrics); | 256 | rpc_free_iostats(clnt->cl_metrics); |
381 | out_no_stats: | 257 | out_no_stats: |
258 | if (clnt->cl_server != clnt->cl_inline_name) | ||
259 | kfree(clnt->cl_server); | ||
382 | kfree(clnt); | 260 | kfree(clnt); |
383 | out_err: | 261 | out_err: |
384 | xprt_put(xprt); | 262 | xprt_put(xprt); |
@@ -388,7 +266,7 @@ out_no_rpciod: | |||
388 | return ERR_PTR(err); | 266 | return ERR_PTR(err); |
389 | } | 267 | } |
390 | 268 | ||
391 | /** | 269 | /* |
392 | * rpc_create - create an RPC client and transport with one call | 270 | * rpc_create - create an RPC client and transport with one call |
393 | * @args: rpc_clnt create argument structure | 271 | * @args: rpc_clnt create argument structure |
394 | * | 272 | * |
@@ -408,7 +286,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
408 | .srcaddr = args->saddress, | 286 | .srcaddr = args->saddress, |
409 | .dstaddr = args->address, | 287 | .dstaddr = args->address, |
410 | .addrlen = args->addrsize, | 288 | .addrlen = args->addrsize, |
411 | .servername = args->servername, | ||
412 | .bc_xprt = args->bc_xprt, | 289 | .bc_xprt = args->bc_xprt, |
413 | }; | 290 | }; |
414 | char servername[48]; | 291 | char servername[48]; |
@@ -417,7 +294,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
417 | * If the caller chooses not to specify a hostname, whip | 294 | * If the caller chooses not to specify a hostname, whip |
418 | * up a string representation of the passed-in address. | 295 | * up a string representation of the passed-in address. |
419 | */ | 296 | */ |
420 | if (xprtargs.servername == NULL) { | 297 | if (args->servername == NULL) { |
421 | struct sockaddr_un *sun = | 298 | struct sockaddr_un *sun = |
422 | (struct sockaddr_un *)args->address; | 299 | (struct sockaddr_un *)args->address; |
423 | struct sockaddr_in *sin = | 300 | struct sockaddr_in *sin = |
@@ -444,7 +321,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
444 | * address family isn't recognized. */ | 321 | * address family isn't recognized. */ |
445 | return ERR_PTR(-EINVAL); | 322 | return ERR_PTR(-EINVAL); |
446 | } | 323 | } |
447 | xprtargs.servername = servername; | 324 | args->servername = servername; |
448 | } | 325 | } |
449 | 326 | ||
450 | xprt = xprt_create_transport(&xprtargs); | 327 | xprt = xprt_create_transport(&xprtargs); |
@@ -493,86 +370,52 @@ EXPORT_SYMBOL_GPL(rpc_create); | |||
493 | * same transport while varying parameters such as the authentication | 370 | * same transport while varying parameters such as the authentication |
494 | * flavour. | 371 | * flavour. |
495 | */ | 372 | */ |
496 | static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, | 373 | struct rpc_clnt * |
497 | struct rpc_clnt *clnt) | 374 | rpc_clone_client(struct rpc_clnt *clnt) |
498 | { | 375 | { |
499 | struct rpc_xprt *xprt; | ||
500 | struct rpc_clnt *new; | 376 | struct rpc_clnt *new; |
501 | int err; | 377 | int err = -ENOMEM; |
502 | |||
503 | err = -ENOMEM; | ||
504 | rcu_read_lock(); | ||
505 | xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); | ||
506 | rcu_read_unlock(); | ||
507 | if (xprt == NULL) | ||
508 | goto out_err; | ||
509 | args->servername = xprt->servername; | ||
510 | 378 | ||
511 | new = rpc_new_client(args, xprt); | 379 | new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); |
512 | if (IS_ERR(new)) { | 380 | if (!new) |
513 | err = PTR_ERR(new); | 381 | goto out_no_clnt; |
514 | goto out_put; | ||
515 | } | ||
516 | |||
517 | atomic_inc(&clnt->cl_count); | ||
518 | new->cl_parent = clnt; | 382 | new->cl_parent = clnt; |
519 | |||
520 | /* Turn off autobind on clones */ | 383 | /* Turn off autobind on clones */ |
521 | new->cl_autobind = 0; | 384 | new->cl_autobind = 0; |
522 | new->cl_softrtry = clnt->cl_softrtry; | 385 | INIT_LIST_HEAD(&new->cl_tasks); |
523 | new->cl_discrtry = clnt->cl_discrtry; | 386 | spin_lock_init(&new->cl_lock); |
524 | new->cl_chatty = clnt->cl_chatty; | 387 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval); |
388 | new->cl_metrics = rpc_alloc_iostats(clnt); | ||
389 | if (new->cl_metrics == NULL) | ||
390 | goto out_no_stats; | ||
391 | if (clnt->cl_principal) { | ||
392 | new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL); | ||
393 | if (new->cl_principal == NULL) | ||
394 | goto out_no_principal; | ||
395 | } | ||
396 | atomic_set(&new->cl_count, 1); | ||
397 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); | ||
398 | if (err != 0) | ||
399 | goto out_no_path; | ||
400 | if (new->cl_auth) | ||
401 | atomic_inc(&new->cl_auth->au_count); | ||
402 | xprt_get(clnt->cl_xprt); | ||
403 | atomic_inc(&clnt->cl_count); | ||
404 | rpc_register_client(new); | ||
405 | rpciod_up(); | ||
525 | return new; | 406 | return new; |
526 | 407 | out_no_path: | |
527 | out_put: | 408 | kfree(new->cl_principal); |
528 | xprt_put(xprt); | 409 | out_no_principal: |
529 | out_err: | 410 | rpc_free_iostats(new->cl_metrics); |
411 | out_no_stats: | ||
412 | kfree(new); | ||
413 | out_no_clnt: | ||
530 | dprintk("RPC: %s: returned error %d\n", __func__, err); | 414 | dprintk("RPC: %s: returned error %d\n", __func__, err); |
531 | return ERR_PTR(err); | 415 | return ERR_PTR(err); |
532 | } | 416 | } |
533 | |||
534 | /** | ||
535 | * rpc_clone_client - Clone an RPC client structure | ||
536 | * | ||
537 | * @clnt: RPC client whose parameters are copied | ||
538 | * | ||
539 | * Returns a fresh RPC client or an ERR_PTR. | ||
540 | */ | ||
541 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt) | ||
542 | { | ||
543 | struct rpc_create_args args = { | ||
544 | .program = clnt->cl_program, | ||
545 | .prognumber = clnt->cl_prog, | ||
546 | .version = clnt->cl_vers, | ||
547 | .authflavor = clnt->cl_auth->au_flavor, | ||
548 | .client_name = clnt->cl_principal, | ||
549 | }; | ||
550 | return __rpc_clone_client(&args, clnt); | ||
551 | } | ||
552 | EXPORT_SYMBOL_GPL(rpc_clone_client); | 417 | EXPORT_SYMBOL_GPL(rpc_clone_client); |
553 | 418 | ||
554 | /** | ||
555 | * rpc_clone_client_set_auth - Clone an RPC client structure and set its auth | ||
556 | * | ||
557 | * @clnt: RPC client whose parameters are copied | ||
558 | * @flavor: security flavor for new client | ||
559 | * | ||
560 | * Returns a fresh RPC client or an ERR_PTR. | ||
561 | */ | ||
562 | struct rpc_clnt * | ||
563 | rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | ||
564 | { | ||
565 | struct rpc_create_args args = { | ||
566 | .program = clnt->cl_program, | ||
567 | .prognumber = clnt->cl_prog, | ||
568 | .version = clnt->cl_vers, | ||
569 | .authflavor = flavor, | ||
570 | .client_name = clnt->cl_principal, | ||
571 | }; | ||
572 | return __rpc_clone_client(&args, clnt); | ||
573 | } | ||
574 | EXPORT_SYMBOL_GPL(rpc_clone_client_set_auth); | ||
575 | |||
576 | /* | 419 | /* |
577 | * Kill all tasks for the given client. | 420 | * Kill all tasks for the given client. |
578 | * XXX: kill their descendants as well? | 421 | * XXX: kill their descendants as well? |
@@ -610,11 +453,8 @@ EXPORT_SYMBOL_GPL(rpc_killall_tasks); | |||
610 | */ | 453 | */ |
611 | void rpc_shutdown_client(struct rpc_clnt *clnt) | 454 | void rpc_shutdown_client(struct rpc_clnt *clnt) |
612 | { | 455 | { |
613 | might_sleep(); | 456 | dprintk("RPC: shutting down %s client for %s\n", |
614 | 457 | clnt->cl_protname, clnt->cl_server); | |
615 | dprintk_rcu("RPC: shutting down %s client for %s\n", | ||
616 | clnt->cl_protname, | ||
617 | rcu_dereference(clnt->cl_xprt)->servername); | ||
618 | 458 | ||
619 | while (!list_empty(&clnt->cl_tasks)) { | 459 | while (!list_empty(&clnt->cl_tasks)) { |
620 | rpc_killall_tasks(clnt); | 460 | rpc_killall_tasks(clnt); |
@@ -632,17 +472,24 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); | |||
632 | static void | 472 | static void |
633 | rpc_free_client(struct rpc_clnt *clnt) | 473 | rpc_free_client(struct rpc_clnt *clnt) |
634 | { | 474 | { |
635 | dprintk_rcu("RPC: destroying %s client for %s\n", | 475 | dprintk("RPC: destroying %s client for %s\n", |
636 | clnt->cl_protname, | 476 | clnt->cl_protname, clnt->cl_server); |
637 | rcu_dereference(clnt->cl_xprt)->servername); | 477 | if (!IS_ERR(clnt->cl_path.dentry)) { |
638 | if (clnt->cl_parent != clnt) | 478 | rpc_remove_client_dir(clnt->cl_path.dentry); |
479 | rpc_put_mount(); | ||
480 | } | ||
481 | if (clnt->cl_parent != clnt) { | ||
639 | rpc_release_client(clnt->cl_parent); | 482 | rpc_release_client(clnt->cl_parent); |
483 | goto out_free; | ||
484 | } | ||
485 | if (clnt->cl_server != clnt->cl_inline_name) | ||
486 | kfree(clnt->cl_server); | ||
487 | out_free: | ||
640 | rpc_unregister_client(clnt); | 488 | rpc_unregister_client(clnt); |
641 | rpc_clnt_remove_pipedir(clnt); | ||
642 | rpc_free_iostats(clnt->cl_metrics); | 489 | rpc_free_iostats(clnt->cl_metrics); |
643 | kfree(clnt->cl_principal); | 490 | kfree(clnt->cl_principal); |
644 | clnt->cl_metrics = NULL; | 491 | clnt->cl_metrics = NULL; |
645 | xprt_put(rcu_dereference_raw(clnt->cl_xprt)); | 492 | xprt_put(clnt->cl_xprt); |
646 | rpciod_down(); | 493 | rpciod_down(); |
647 | kfree(clnt); | 494 | kfree(clnt); |
648 | } | 495 | } |
@@ -695,22 +542,24 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
695 | * The Sun NFSv2/v3 ACL protocol can do this. | 542 | * The Sun NFSv2/v3 ACL protocol can do this. |
696 | */ | 543 | */ |
697 | struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, | 544 | struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, |
698 | const struct rpc_program *program, | 545 | struct rpc_program *program, |
699 | u32 vers) | 546 | u32 vers) |
700 | { | 547 | { |
701 | struct rpc_create_args args = { | ||
702 | .program = program, | ||
703 | .prognumber = program->number, | ||
704 | .version = vers, | ||
705 | .authflavor = old->cl_auth->au_flavor, | ||
706 | .client_name = old->cl_principal, | ||
707 | }; | ||
708 | struct rpc_clnt *clnt; | 548 | struct rpc_clnt *clnt; |
549 | struct rpc_version *version; | ||
709 | int err; | 550 | int err; |
710 | 551 | ||
711 | clnt = __rpc_clone_client(&args, old); | 552 | BUG_ON(vers >= program->nrvers || !program->version[vers]); |
553 | version = program->version[vers]; | ||
554 | clnt = rpc_clone_client(old); | ||
712 | if (IS_ERR(clnt)) | 555 | if (IS_ERR(clnt)) |
713 | goto out; | 556 | goto out; |
557 | clnt->cl_procinfo = version->procs; | ||
558 | clnt->cl_maxproc = version->nrprocs; | ||
559 | clnt->cl_protname = program->name; | ||
560 | clnt->cl_prog = program->number; | ||
561 | clnt->cl_vers = version->number; | ||
562 | clnt->cl_stats = program->stats; | ||
714 | err = rpc_ping(clnt); | 563 | err = rpc_ping(clnt); |
715 | if (err != 0) { | 564 | if (err != 0) { |
716 | rpc_shutdown_client(clnt); | 565 | rpc_shutdown_client(clnt); |
@@ -745,15 +594,6 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) | |||
745 | atomic_inc(&clnt->cl_count); | 594 | atomic_inc(&clnt->cl_count); |
746 | if (clnt->cl_softrtry) | 595 | if (clnt->cl_softrtry) |
747 | task->tk_flags |= RPC_TASK_SOFT; | 596 | task->tk_flags |= RPC_TASK_SOFT; |
748 | if (sk_memalloc_socks()) { | ||
749 | struct rpc_xprt *xprt; | ||
750 | |||
751 | rcu_read_lock(); | ||
752 | xprt = rcu_dereference(clnt->cl_xprt); | ||
753 | if (xprt->swapper) | ||
754 | task->tk_flags |= RPC_TASK_SWAPPER; | ||
755 | rcu_read_unlock(); | ||
756 | } | ||
757 | /* Add to the client's list of all tasks */ | 597 | /* Add to the client's list of all tasks */ |
758 | spin_lock(&clnt->cl_lock); | 598 | spin_lock(&clnt->cl_lock); |
759 | list_add_tail(&task->tk_task, &clnt->cl_tasks); | 599 | list_add_tail(&task->tk_task, &clnt->cl_tasks); |
@@ -835,12 +675,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flag | |||
835 | }; | 675 | }; |
836 | int status; | 676 | int status; |
837 | 677 | ||
838 | WARN_ON_ONCE(flags & RPC_TASK_ASYNC); | 678 | BUG_ON(flags & RPC_TASK_ASYNC); |
839 | if (flags & RPC_TASK_ASYNC) { | ||
840 | rpc_release_calldata(task_setup_data.callback_ops, | ||
841 | task_setup_data.callback_data); | ||
842 | return -EINVAL; | ||
843 | } | ||
844 | 679 | ||
845 | task = rpc_run_task(&task_setup_data); | 680 | task = rpc_run_task(&task_setup_data); |
846 | if (IS_ERR(task)) | 681 | if (IS_ERR(task)) |
@@ -916,7 +751,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, | |||
916 | 751 | ||
917 | task->tk_action = call_bc_transmit; | 752 | task->tk_action = call_bc_transmit; |
918 | atomic_inc(&task->tk_count); | 753 | atomic_inc(&task->tk_count); |
919 | WARN_ON_ONCE(atomic_read(&task->tk_count) != 2); | 754 | BUG_ON(atomic_read(&task->tk_count) != 2); |
920 | rpc_execute(task); | 755 | rpc_execute(task); |
921 | 756 | ||
922 | out: | 757 | out: |
@@ -943,18 +778,13 @@ EXPORT_SYMBOL_GPL(rpc_call_start); | |||
943 | size_t rpc_peeraddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t bufsize) | 778 | size_t rpc_peeraddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t bufsize) |
944 | { | 779 | { |
945 | size_t bytes; | 780 | size_t bytes; |
946 | struct rpc_xprt *xprt; | 781 | struct rpc_xprt *xprt = clnt->cl_xprt; |
947 | 782 | ||
948 | rcu_read_lock(); | 783 | bytes = sizeof(xprt->addr); |
949 | xprt = rcu_dereference(clnt->cl_xprt); | ||
950 | |||
951 | bytes = xprt->addrlen; | ||
952 | if (bytes > bufsize) | 784 | if (bytes > bufsize) |
953 | bytes = bufsize; | 785 | bytes = bufsize; |
954 | memcpy(buf, &xprt->addr, bytes); | 786 | memcpy(buf, &clnt->cl_xprt->addr, bytes); |
955 | rcu_read_unlock(); | 787 | return xprt->addrlen; |
956 | |||
957 | return bytes; | ||
958 | } | 788 | } |
959 | EXPORT_SYMBOL_GPL(rpc_peeraddr); | 789 | EXPORT_SYMBOL_GPL(rpc_peeraddr); |
960 | 790 | ||
@@ -963,16 +793,11 @@ EXPORT_SYMBOL_GPL(rpc_peeraddr); | |||
963 | * @clnt: RPC client structure | 793 | * @clnt: RPC client structure |
964 | * @format: address format | 794 | * @format: address format |
965 | * | 795 | * |
966 | * NB: the lifetime of the memory referenced by the returned pointer is | ||
967 | * the same as the rpc_xprt itself. As long as the caller uses this | ||
968 | * pointer, it must hold the RCU read lock. | ||
969 | */ | 796 | */ |
970 | const char *rpc_peeraddr2str(struct rpc_clnt *clnt, | 797 | const char *rpc_peeraddr2str(struct rpc_clnt *clnt, |
971 | enum rpc_display_format_t format) | 798 | enum rpc_display_format_t format) |
972 | { | 799 | { |
973 | struct rpc_xprt *xprt; | 800 | struct rpc_xprt *xprt = clnt->cl_xprt; |
974 | |||
975 | xprt = rcu_dereference(clnt->cl_xprt); | ||
976 | 801 | ||
977 | if (xprt->address_strings[format] != NULL) | 802 | if (xprt->address_strings[format] != NULL) |
978 | return xprt->address_strings[format]; | 803 | return xprt->address_strings[format]; |
@@ -981,203 +806,17 @@ const char *rpc_peeraddr2str(struct rpc_clnt *clnt, | |||
981 | } | 806 | } |
982 | EXPORT_SYMBOL_GPL(rpc_peeraddr2str); | 807 | EXPORT_SYMBOL_GPL(rpc_peeraddr2str); |
983 | 808 | ||
984 | static const struct sockaddr_in rpc_inaddr_loopback = { | ||
985 | .sin_family = AF_INET, | ||
986 | .sin_addr.s_addr = htonl(INADDR_ANY), | ||
987 | }; | ||
988 | |||
989 | static const struct sockaddr_in6 rpc_in6addr_loopback = { | ||
990 | .sin6_family = AF_INET6, | ||
991 | .sin6_addr = IN6ADDR_ANY_INIT, | ||
992 | }; | ||
993 | |||
994 | /* | ||
995 | * Try a getsockname() on a connected datagram socket. Using a | ||
996 | * connected datagram socket prevents leaving a socket in TIME_WAIT. | ||
997 | * This conserves the ephemeral port number space. | ||
998 | * | ||
999 | * Returns zero and fills in "buf" if successful; otherwise, a | ||
1000 | * negative errno is returned. | ||
1001 | */ | ||
1002 | static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen, | ||
1003 | struct sockaddr *buf, int buflen) | ||
1004 | { | ||
1005 | struct socket *sock; | ||
1006 | int err; | ||
1007 | |||
1008 | err = __sock_create(net, sap->sa_family, | ||
1009 | SOCK_DGRAM, IPPROTO_UDP, &sock, 1); | ||
1010 | if (err < 0) { | ||
1011 | dprintk("RPC: can't create UDP socket (%d)\n", err); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | |||
1015 | switch (sap->sa_family) { | ||
1016 | case AF_INET: | ||
1017 | err = kernel_bind(sock, | ||
1018 | (struct sockaddr *)&rpc_inaddr_loopback, | ||
1019 | sizeof(rpc_inaddr_loopback)); | ||
1020 | break; | ||
1021 | case AF_INET6: | ||
1022 | err = kernel_bind(sock, | ||
1023 | (struct sockaddr *)&rpc_in6addr_loopback, | ||
1024 | sizeof(rpc_in6addr_loopback)); | ||
1025 | break; | ||
1026 | default: | ||
1027 | err = -EAFNOSUPPORT; | ||
1028 | goto out; | ||
1029 | } | ||
1030 | if (err < 0) { | ||
1031 | dprintk("RPC: can't bind UDP socket (%d)\n", err); | ||
1032 | goto out_release; | ||
1033 | } | ||
1034 | |||
1035 | err = kernel_connect(sock, sap, salen, 0); | ||
1036 | if (err < 0) { | ||
1037 | dprintk("RPC: can't connect UDP socket (%d)\n", err); | ||
1038 | goto out_release; | ||
1039 | } | ||
1040 | |||
1041 | err = kernel_getsockname(sock, buf, &buflen); | ||
1042 | if (err < 0) { | ||
1043 | dprintk("RPC: getsockname failed (%d)\n", err); | ||
1044 | goto out_release; | ||
1045 | } | ||
1046 | |||
1047 | err = 0; | ||
1048 | if (buf->sa_family == AF_INET6) { | ||
1049 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf; | ||
1050 | sin6->sin6_scope_id = 0; | ||
1051 | } | ||
1052 | dprintk("RPC: %s succeeded\n", __func__); | ||
1053 | |||
1054 | out_release: | ||
1055 | sock_release(sock); | ||
1056 | out: | ||
1057 | return err; | ||
1058 | } | ||
1059 | |||
1060 | /* | ||
1061 | * Scraping a connected socket failed, so we don't have a useable | ||
1062 | * local address. Fallback: generate an address that will prevent | ||
1063 | * the server from calling us back. | ||
1064 | * | ||
1065 | * Returns zero and fills in "buf" if successful; otherwise, a | ||
1066 | * negative errno is returned. | ||
1067 | */ | ||
1068 | static int rpc_anyaddr(int family, struct sockaddr *buf, size_t buflen) | ||
1069 | { | ||
1070 | switch (family) { | ||
1071 | case AF_INET: | ||
1072 | if (buflen < sizeof(rpc_inaddr_loopback)) | ||
1073 | return -EINVAL; | ||
1074 | memcpy(buf, &rpc_inaddr_loopback, | ||
1075 | sizeof(rpc_inaddr_loopback)); | ||
1076 | break; | ||
1077 | case AF_INET6: | ||
1078 | if (buflen < sizeof(rpc_in6addr_loopback)) | ||
1079 | return -EINVAL; | ||
1080 | memcpy(buf, &rpc_in6addr_loopback, | ||
1081 | sizeof(rpc_in6addr_loopback)); | ||
1082 | default: | ||
1083 | dprintk("RPC: %s: address family not supported\n", | ||
1084 | __func__); | ||
1085 | return -EAFNOSUPPORT; | ||
1086 | } | ||
1087 | dprintk("RPC: %s: succeeded\n", __func__); | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | /** | ||
1092 | * rpc_localaddr - discover local endpoint address for an RPC client | ||
1093 | * @clnt: RPC client structure | ||
1094 | * @buf: target buffer | ||
1095 | * @buflen: size of target buffer, in bytes | ||
1096 | * | ||
1097 | * Returns zero and fills in "buf" and "buflen" if successful; | ||
1098 | * otherwise, a negative errno is returned. | ||
1099 | * | ||
1100 | * This works even if the underlying transport is not currently connected, | ||
1101 | * or if the upper layer never previously provided a source address. | ||
1102 | * | ||
1103 | * The result of this function call is transient: multiple calls in | ||
1104 | * succession may give different results, depending on how local | ||
1105 | * networking configuration changes over time. | ||
1106 | */ | ||
1107 | int rpc_localaddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t buflen) | ||
1108 | { | ||
1109 | struct sockaddr_storage address; | ||
1110 | struct sockaddr *sap = (struct sockaddr *)&address; | ||
1111 | struct rpc_xprt *xprt; | ||
1112 | struct net *net; | ||
1113 | size_t salen; | ||
1114 | int err; | ||
1115 | |||
1116 | rcu_read_lock(); | ||
1117 | xprt = rcu_dereference(clnt->cl_xprt); | ||
1118 | salen = xprt->addrlen; | ||
1119 | memcpy(sap, &xprt->addr, salen); | ||
1120 | net = get_net(xprt->xprt_net); | ||
1121 | rcu_read_unlock(); | ||
1122 | |||
1123 | rpc_set_port(sap, 0); | ||
1124 | err = rpc_sockname(net, sap, salen, buf, buflen); | ||
1125 | put_net(net); | ||
1126 | if (err != 0) | ||
1127 | /* Couldn't discover local address, return ANYADDR */ | ||
1128 | return rpc_anyaddr(sap->sa_family, buf, buflen); | ||
1129 | return 0; | ||
1130 | } | ||
1131 | EXPORT_SYMBOL_GPL(rpc_localaddr); | ||
1132 | |||
1133 | void | 809 | void |
1134 | rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize) | 810 | rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize) |
1135 | { | 811 | { |
1136 | struct rpc_xprt *xprt; | 812 | struct rpc_xprt *xprt = clnt->cl_xprt; |
1137 | |||
1138 | rcu_read_lock(); | ||
1139 | xprt = rcu_dereference(clnt->cl_xprt); | ||
1140 | if (xprt->ops->set_buffer_size) | 813 | if (xprt->ops->set_buffer_size) |
1141 | xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); | 814 | xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); |
1142 | rcu_read_unlock(); | ||
1143 | } | 815 | } |
1144 | EXPORT_SYMBOL_GPL(rpc_setbufsize); | 816 | EXPORT_SYMBOL_GPL(rpc_setbufsize); |
1145 | 817 | ||
1146 | /** | 818 | /* |
1147 | * rpc_protocol - Get transport protocol number for an RPC client | 819 | * Return size of largest payload RPC client can support, in bytes |
1148 | * @clnt: RPC client to query | ||
1149 | * | ||
1150 | */ | ||
1151 | int rpc_protocol(struct rpc_clnt *clnt) | ||
1152 | { | ||
1153 | int protocol; | ||
1154 | |||
1155 | rcu_read_lock(); | ||
1156 | protocol = rcu_dereference(clnt->cl_xprt)->prot; | ||
1157 | rcu_read_unlock(); | ||
1158 | return protocol; | ||
1159 | } | ||
1160 | EXPORT_SYMBOL_GPL(rpc_protocol); | ||
1161 | |||
1162 | /** | ||
1163 | * rpc_net_ns - Get the network namespace for this RPC client | ||
1164 | * @clnt: RPC client to query | ||
1165 | * | ||
1166 | */ | ||
1167 | struct net *rpc_net_ns(struct rpc_clnt *clnt) | ||
1168 | { | ||
1169 | struct net *ret; | ||
1170 | |||
1171 | rcu_read_lock(); | ||
1172 | ret = rcu_dereference(clnt->cl_xprt)->xprt_net; | ||
1173 | rcu_read_unlock(); | ||
1174 | return ret; | ||
1175 | } | ||
1176 | EXPORT_SYMBOL_GPL(rpc_net_ns); | ||
1177 | |||
1178 | /** | ||
1179 | * rpc_max_payload - Get maximum payload size for a transport, in bytes | ||
1180 | * @clnt: RPC client to query | ||
1181 | * | 820 | * |
1182 | * For stream transports, this is one RPC record fragment (see RFC | 821 | * For stream transports, this is one RPC record fragment (see RFC |
1183 | * 1831), as we don't support multi-record requests yet. For datagram | 822 | * 1831), as we don't support multi-record requests yet. For datagram |
@@ -1186,12 +825,7 @@ EXPORT_SYMBOL_GPL(rpc_net_ns); | |||
1186 | */ | 825 | */ |
1187 | size_t rpc_max_payload(struct rpc_clnt *clnt) | 826 | size_t rpc_max_payload(struct rpc_clnt *clnt) |
1188 | { | 827 | { |
1189 | size_t ret; | 828 | return clnt->cl_xprt->max_payload; |
1190 | |||
1191 | rcu_read_lock(); | ||
1192 | ret = rcu_dereference(clnt->cl_xprt)->max_payload; | ||
1193 | rcu_read_unlock(); | ||
1194 | return ret; | ||
1195 | } | 829 | } |
1196 | EXPORT_SYMBOL_GPL(rpc_max_payload); | 830 | EXPORT_SYMBOL_GPL(rpc_max_payload); |
1197 | 831 | ||
@@ -1202,11 +836,8 @@ EXPORT_SYMBOL_GPL(rpc_max_payload); | |||
1202 | */ | 836 | */ |
1203 | void rpc_force_rebind(struct rpc_clnt *clnt) | 837 | void rpc_force_rebind(struct rpc_clnt *clnt) |
1204 | { | 838 | { |
1205 | if (clnt->cl_autobind) { | 839 | if (clnt->cl_autobind) |
1206 | rcu_read_lock(); | 840 | xprt_clear_bound(clnt->cl_xprt); |
1207 | xprt_clear_bound(rcu_dereference(clnt->cl_xprt)); | ||
1208 | rcu_read_unlock(); | ||
1209 | } | ||
1210 | } | 841 | } |
1211 | EXPORT_SYMBOL_GPL(rpc_force_rebind); | 842 | EXPORT_SYMBOL_GPL(rpc_force_rebind); |
1212 | 843 | ||
@@ -1219,9 +850,7 @@ rpc_restart_call_prepare(struct rpc_task *task) | |||
1219 | { | 850 | { |
1220 | if (RPC_ASSASSINATED(task)) | 851 | if (RPC_ASSASSINATED(task)) |
1221 | return 0; | 852 | return 0; |
1222 | task->tk_action = call_start; | 853 | task->tk_action = rpc_prepare_task; |
1223 | if (task->tk_ops->rpc_call_prepare != NULL) | ||
1224 | task->tk_action = rpc_prepare_task; | ||
1225 | return 1; | 854 | return 1; |
1226 | } | 855 | } |
1227 | EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); | 856 | EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); |
@@ -1328,8 +957,6 @@ call_reserveresult(struct rpc_task *task) | |||
1328 | } | 957 | } |
1329 | 958 | ||
1330 | switch (status) { | 959 | switch (status) { |
1331 | case -ENOMEM: | ||
1332 | rpc_delay(task, HZ >> 2); | ||
1333 | case -EAGAIN: /* woken up; retry */ | 960 | case -EAGAIN: /* woken up; retry */ |
1334 | task->tk_action = call_reserve; | 961 | task->tk_action = call_reserve; |
1335 | return; | 962 | return; |
@@ -1376,7 +1003,6 @@ call_refreshresult(struct rpc_task *task) | |||
1376 | return; | 1003 | return; |
1377 | case -ETIMEDOUT: | 1004 | case -ETIMEDOUT: |
1378 | rpc_delay(task, 3*HZ); | 1005 | rpc_delay(task, 3*HZ); |
1379 | case -EKEYEXPIRED: | ||
1380 | case -EAGAIN: | 1006 | case -EAGAIN: |
1381 | status = -EACCES; | 1007 | status = -EACCES; |
1382 | if (!task->tk_cred_retry) | 1008 | if (!task->tk_cred_retry) |
@@ -1535,7 +1161,6 @@ call_bind_status(struct rpc_task *task) | |||
1535 | return; | 1161 | return; |
1536 | } | 1162 | } |
1537 | 1163 | ||
1538 | trace_rpc_bind_status(task); | ||
1539 | switch (task->tk_status) { | 1164 | switch (task->tk_status) { |
1540 | case -ENOMEM: | 1165 | case -ENOMEM: |
1541 | dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); | 1166 | dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); |
@@ -1635,7 +1260,6 @@ call_connect_status(struct rpc_task *task) | |||
1635 | return; | 1260 | return; |
1636 | } | 1261 | } |
1637 | 1262 | ||
1638 | trace_rpc_connect_status(task, status); | ||
1639 | switch (status) { | 1263 | switch (status) { |
1640 | /* if soft mounted, test if we've timed out */ | 1264 | /* if soft mounted, test if we've timed out */ |
1641 | case -ETIMEDOUT: | 1265 | case -ETIMEDOUT: |
@@ -1663,6 +1287,7 @@ call_transmit(struct rpc_task *task) | |||
1663 | task->tk_action = call_transmit_status; | 1287 | task->tk_action = call_transmit_status; |
1664 | /* Encode here so that rpcsec_gss can use correct sequence number. */ | 1288 | /* Encode here so that rpcsec_gss can use correct sequence number. */ |
1665 | if (rpc_task_need_encode(task)) { | 1289 | if (rpc_task_need_encode(task)) { |
1290 | BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); | ||
1666 | rpc_xdr_encode(task); | 1291 | rpc_xdr_encode(task); |
1667 | /* Did the encode result in an error condition? */ | 1292 | /* Did the encode result in an error condition? */ |
1668 | if (task->tk_status != 0) { | 1293 | if (task->tk_status != 0) { |
@@ -1746,6 +1371,7 @@ call_bc_transmit(struct rpc_task *task) | |||
1746 | { | 1371 | { |
1747 | struct rpc_rqst *req = task->tk_rqstp; | 1372 | struct rpc_rqst *req = task->tk_rqstp; |
1748 | 1373 | ||
1374 | BUG_ON(task->tk_status != 0); | ||
1749 | task->tk_status = xprt_prepare_transmit(task); | 1375 | task->tk_status = xprt_prepare_transmit(task); |
1750 | if (task->tk_status == -EAGAIN) { | 1376 | if (task->tk_status == -EAGAIN) { |
1751 | /* | 1377 | /* |
@@ -1792,7 +1418,7 @@ call_bc_transmit(struct rpc_task *task) | |||
1792 | * We were unable to reply and will have to drop the | 1418 | * We were unable to reply and will have to drop the |
1793 | * request. The server should reconnect and retransmit. | 1419 | * request. The server should reconnect and retransmit. |
1794 | */ | 1420 | */ |
1795 | WARN_ON_ONCE(task->tk_status == -EAGAIN); | 1421 | BUG_ON(task->tk_status == -EAGAIN); |
1796 | printk(KERN_NOTICE "RPC: Could not send backchannel reply " | 1422 | printk(KERN_NOTICE "RPC: Could not send backchannel reply " |
1797 | "error: %d\n", task->tk_status); | 1423 | "error: %d\n", task->tk_status); |
1798 | break; | 1424 | break; |
@@ -1822,7 +1448,6 @@ call_status(struct rpc_task *task) | |||
1822 | return; | 1448 | return; |
1823 | } | 1449 | } |
1824 | 1450 | ||
1825 | trace_rpc_call_status(task); | ||
1826 | task->tk_status = 0; | 1451 | task->tk_status = 0; |
1827 | switch(status) { | 1452 | switch(status) { |
1828 | case -EHOSTDOWN: | 1453 | case -EHOSTDOWN: |
@@ -1885,13 +1510,9 @@ call_timeout(struct rpc_task *task) | |||
1885 | return; | 1510 | return; |
1886 | } | 1511 | } |
1887 | if (RPC_IS_SOFT(task)) { | 1512 | if (RPC_IS_SOFT(task)) { |
1888 | if (clnt->cl_chatty) { | 1513 | if (clnt->cl_chatty) |
1889 | rcu_read_lock(); | ||
1890 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | 1514 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", |
1891 | clnt->cl_protname, | 1515 | clnt->cl_protname, clnt->cl_server); |
1892 | rcu_dereference(clnt->cl_xprt)->servername); | ||
1893 | rcu_read_unlock(); | ||
1894 | } | ||
1895 | if (task->tk_flags & RPC_TASK_TIMEOUT) | 1516 | if (task->tk_flags & RPC_TASK_TIMEOUT) |
1896 | rpc_exit(task, -ETIMEDOUT); | 1517 | rpc_exit(task, -ETIMEDOUT); |
1897 | else | 1518 | else |
@@ -1901,13 +1522,9 @@ call_timeout(struct rpc_task *task) | |||
1901 | 1522 | ||
1902 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { | 1523 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { |
1903 | task->tk_flags |= RPC_CALL_MAJORSEEN; | 1524 | task->tk_flags |= RPC_CALL_MAJORSEEN; |
1904 | if (clnt->cl_chatty) { | 1525 | if (clnt->cl_chatty) |
1905 | rcu_read_lock(); | ||
1906 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | 1526 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", |
1907 | clnt->cl_protname, | 1527 | clnt->cl_protname, clnt->cl_server); |
1908 | rcu_dereference(clnt->cl_xprt)->servername); | ||
1909 | rcu_read_unlock(); | ||
1910 | } | ||
1911 | } | 1528 | } |
1912 | rpc_force_rebind(clnt); | 1529 | rpc_force_rebind(clnt); |
1913 | /* | 1530 | /* |
@@ -1936,13 +1553,9 @@ call_decode(struct rpc_task *task) | |||
1936 | dprint_status(task); | 1553 | dprint_status(task); |
1937 | 1554 | ||
1938 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { | 1555 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
1939 | if (clnt->cl_chatty) { | 1556 | if (clnt->cl_chatty) |
1940 | rcu_read_lock(); | ||
1941 | printk(KERN_NOTICE "%s: server %s OK\n", | 1557 | printk(KERN_NOTICE "%s: server %s OK\n", |
1942 | clnt->cl_protname, | 1558 | clnt->cl_protname, clnt->cl_server); |
1943 | rcu_dereference(clnt->cl_xprt)->servername); | ||
1944 | rcu_read_unlock(); | ||
1945 | } | ||
1946 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; | 1559 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; |
1947 | } | 1560 | } |
1948 | 1561 | ||
@@ -2020,7 +1633,6 @@ rpc_encode_header(struct rpc_task *task) | |||
2020 | static __be32 * | 1633 | static __be32 * |
2021 | rpc_verify_header(struct rpc_task *task) | 1634 | rpc_verify_header(struct rpc_task *task) |
2022 | { | 1635 | { |
2023 | struct rpc_clnt *clnt = task->tk_client; | ||
2024 | struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; | 1636 | struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; |
2025 | int len = task->tk_rqstp->rq_rcv_buf.len >> 2; | 1637 | int len = task->tk_rqstp->rq_rcv_buf.len >> 2; |
2026 | __be32 *p = iov->iov_base; | 1638 | __be32 *p = iov->iov_base; |
@@ -2093,11 +1705,8 @@ rpc_verify_header(struct rpc_task *task) | |||
2093 | task->tk_action = call_bind; | 1705 | task->tk_action = call_bind; |
2094 | goto out_retry; | 1706 | goto out_retry; |
2095 | case RPC_AUTH_TOOWEAK: | 1707 | case RPC_AUTH_TOOWEAK: |
2096 | rcu_read_lock(); | ||
2097 | printk(KERN_NOTICE "RPC: server %s requires stronger " | 1708 | printk(KERN_NOTICE "RPC: server %s requires stronger " |
2098 | "authentication.\n", | 1709 | "authentication.\n", task->tk_client->cl_server); |
2099 | rcu_dereference(clnt->cl_xprt)->servername); | ||
2100 | rcu_read_unlock(); | ||
2101 | break; | 1710 | break; |
2102 | default: | 1711 | default: |
2103 | dprintk("RPC: %5u %s: unknown auth error: %x\n", | 1712 | dprintk("RPC: %5u %s: unknown auth error: %x\n", |
@@ -2120,27 +1729,28 @@ rpc_verify_header(struct rpc_task *task) | |||
2120 | case RPC_SUCCESS: | 1729 | case RPC_SUCCESS: |
2121 | return p; | 1730 | return p; |
2122 | case RPC_PROG_UNAVAIL: | 1731 | case RPC_PROG_UNAVAIL: |
2123 | dprintk_rcu("RPC: %5u %s: program %u is unsupported " | 1732 | dprintk("RPC: %5u %s: program %u is unsupported by server %s\n", |
2124 | "by server %s\n", task->tk_pid, __func__, | 1733 | task->tk_pid, __func__, |
2125 | (unsigned int)clnt->cl_prog, | 1734 | (unsigned int)task->tk_client->cl_prog, |
2126 | rcu_dereference(clnt->cl_xprt)->servername); | 1735 | task->tk_client->cl_server); |
2127 | error = -EPFNOSUPPORT; | 1736 | error = -EPFNOSUPPORT; |
2128 | goto out_err; | 1737 | goto out_err; |
2129 | case RPC_PROG_MISMATCH: | 1738 | case RPC_PROG_MISMATCH: |
2130 | dprintk_rcu("RPC: %5u %s: program %u, version %u unsupported " | 1739 | dprintk("RPC: %5u %s: program %u, version %u unsupported by " |
2131 | "by server %s\n", task->tk_pid, __func__, | 1740 | "server %s\n", task->tk_pid, __func__, |
2132 | (unsigned int)clnt->cl_prog, | 1741 | (unsigned int)task->tk_client->cl_prog, |
2133 | (unsigned int)clnt->cl_vers, | 1742 | (unsigned int)task->tk_client->cl_vers, |
2134 | rcu_dereference(clnt->cl_xprt)->servername); | 1743 | task->tk_client->cl_server); |
2135 | error = -EPROTONOSUPPORT; | 1744 | error = -EPROTONOSUPPORT; |
2136 | goto out_err; | 1745 | goto out_err; |
2137 | case RPC_PROC_UNAVAIL: | 1746 | case RPC_PROC_UNAVAIL: |
2138 | dprintk_rcu("RPC: %5u %s: proc %s unsupported by program %u, " | 1747 | dprintk("RPC: %5u %s: proc %s unsupported by program %u, " |
2139 | "version %u on server %s\n", | 1748 | "version %u on server %s\n", |
2140 | task->tk_pid, __func__, | 1749 | task->tk_pid, __func__, |
2141 | rpc_proc_name(task), | 1750 | rpc_proc_name(task), |
2142 | clnt->cl_prog, clnt->cl_vers, | 1751 | task->tk_client->cl_prog, |
2143 | rcu_dereference(clnt->cl_xprt)->servername); | 1752 | task->tk_client->cl_vers, |
1753 | task->tk_client->cl_server); | ||
2144 | error = -EOPNOTSUPP; | 1754 | error = -EOPNOTSUPP; |
2145 | goto out_err; | 1755 | goto out_err; |
2146 | case RPC_GARBAGE_ARGS: | 1756 | case RPC_GARBAGE_ARGS: |
@@ -2154,7 +1764,7 @@ rpc_verify_header(struct rpc_task *task) | |||
2154 | } | 1764 | } |
2155 | 1765 | ||
2156 | out_garbage: | 1766 | out_garbage: |
2157 | clnt->cl_stats->rpcgarbage++; | 1767 | task->tk_client->cl_stats->rpcgarbage++; |
2158 | if (task->tk_garb_retry) { | 1768 | if (task->tk_garb_retry) { |
2159 | task->tk_garb_retry--; | 1769 | task->tk_garb_retry--; |
2160 | dprintk("RPC: %5u %s: retrying\n", | 1770 | dprintk("RPC: %5u %s: retrying\n", |
@@ -2240,15 +1850,14 @@ static void rpc_show_task(const struct rpc_clnt *clnt, | |||
2240 | task->tk_action, rpc_waitq); | 1850 | task->tk_action, rpc_waitq); |
2241 | } | 1851 | } |
2242 | 1852 | ||
2243 | void rpc_show_tasks(struct net *net) | 1853 | void rpc_show_tasks(void) |
2244 | { | 1854 | { |
2245 | struct rpc_clnt *clnt; | 1855 | struct rpc_clnt *clnt; |
2246 | struct rpc_task *task; | 1856 | struct rpc_task *task; |
2247 | int header = 0; | 1857 | int header = 0; |
2248 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
2249 | 1858 | ||
2250 | spin_lock(&sn->rpc_client_lock); | 1859 | spin_lock(&rpc_client_lock); |
2251 | list_for_each_entry(clnt, &sn->all_clients, cl_clients) { | 1860 | list_for_each_entry(clnt, &all_clients, cl_clients) { |
2252 | spin_lock(&clnt->cl_lock); | 1861 | spin_lock(&clnt->cl_lock); |
2253 | list_for_each_entry(task, &clnt->cl_tasks, tk_task) { | 1862 | list_for_each_entry(task, &clnt->cl_tasks, tk_task) { |
2254 | if (!header) { | 1863 | if (!header) { |
@@ -2259,6 +1868,6 @@ void rpc_show_tasks(struct net *net) | |||
2259 | } | 1868 | } |
2260 | spin_unlock(&clnt->cl_lock); | 1869 | spin_unlock(&clnt->cl_lock); |
2261 | } | 1870 | } |
2262 | spin_unlock(&sn->rpc_client_lock); | 1871 | spin_unlock(&rpc_client_lock); |
2263 | } | 1872 | } |
2264 | #endif | 1873 | #endif |