Blame view
net/sunrpc/clnt.c
54.8 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
55aa4f58a [PATCH] RPC: clie... |
2 |
* linux/net/sunrpc/clnt.c |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 11 12 13 14 15 |
* * This file contains the high-level RPC interface. * It is modeled as a finite state machine to support both synchronous * and asynchronous requests. * * - RPC header generation and argument serialization. * - Credential refresh. * - TCP connect handling. * - Retry of operation when it is suspected the operation failed because * of uid squashing on the server, or when the credentials were stale * and need to be refreshed, or when a packet was damaged in transit. * This may be have to be moved to the VFS layer. * |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 |
* Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> */ |
1da177e4c Linux-2.6.12-rc2 |
19 20 21 |
#include <linux/module.h> #include <linux/types.h> |
cb3997b5a SUNRPC: Display s... |
22 |
#include <linux/kallsyms.h> |
1da177e4c Linux-2.6.12-rc2 |
23 |
#include <linux/mm.h> |
23ac65817 SUNRPC: clean up ... |
24 25 |
#include <linux/namei.h> #include <linux/mount.h> |
1da177e4c Linux-2.6.12-rc2 |
26 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
27 |
#include <linux/utsname.h> |
11c556b3d SUNRPC: provide a... |
28 |
#include <linux/workqueue.h> |
176e21ee2 SUNRPC: Support f... |
29 |
#include <linux/in.h> |
510deb0d7 SUNRPC: rpc_creat... |
30 |
#include <linux/in6.h> |
176e21ee2 SUNRPC: Support f... |
31 |
#include <linux/un.h> |
2446ab607 SUNRPC: Use RCU t... |
32 |
#include <linux/rcupdate.h> |
1da177e4c Linux-2.6.12-rc2 |
33 34 |
#include <linux/sunrpc/clnt.h> |
5976687a2 sunrpc: move addr... |
35 |
#include <linux/sunrpc/addr.h> |
1da177e4c Linux-2.6.12-rc2 |
36 |
#include <linux/sunrpc/rpc_pipe_fs.h> |
11c556b3d SUNRPC: provide a... |
37 |
#include <linux/sunrpc/metrics.h> |
55ae1aabf nfs41: Add backch... |
38 |
#include <linux/sunrpc/bc_xprt.h> |
5753cba17 SUNRPC: Adding st... |
39 |
#include <trace/events/sunrpc.h> |
1da177e4c Linux-2.6.12-rc2 |
40 |
|
55ae1aabf nfs41: Add backch... |
41 |
#include "sunrpc.h" |
70abc49b4 SUNRPC: make SUNP... |
42 |
#include "netns.h" |
1da177e4c Linux-2.6.12-rc2 |
43 |
|
1da177e4c Linux-2.6.12-rc2 |
44 45 46 |
#ifdef RPC_DEBUG # define RPCDBG_FACILITY RPCDBG_CALL #endif |
46121cf7d SUNRPC: fix print... |
47 48 49 |
#define dprint_status(t) \ dprintk("RPC: %5u %s (status %d) ", t->tk_pid, \ |
0dc47877a net: replace rema... |
50 |
__func__, t->tk_status) |
46121cf7d SUNRPC: fix print... |
51 |
|
188fef11d SUNRPC: Move rpc_... |
52 53 54 |
/* * All RPC clients are linked into this list */ |
188fef11d SUNRPC: Move rpc_... |
55 |
|
1da177e4c Linux-2.6.12-rc2 |
56 57 58 59 60 61 62 |
static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); static void call_start(struct rpc_task *task); static void call_reserve(struct rpc_task *task); static void call_reserveresult(struct rpc_task *task); static void call_allocate(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
63 64 |
static void call_decode(struct rpc_task *task); static void call_bind(struct rpc_task *task); |
da3518780 [PATCH] RPC: prop... |
65 |
static void call_bind_status(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
66 |
static void call_transmit(struct rpc_task *task); |
9e00abc3c SUNRPC: sunrpc sh... |
67 |
#if defined(CONFIG_SUNRPC_BACKCHANNEL) |
55ae1aabf nfs41: Add backch... |
68 |
static void call_bc_transmit(struct rpc_task *task); |
9e00abc3c SUNRPC: sunrpc sh... |
69 |
#endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1da177e4c Linux-2.6.12-rc2 |
70 |
static void call_status(struct rpc_task *task); |
940e3318c [PATCH] SUNRPC: d... |
71 |
static void call_transmit_status(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 76 |
static void call_refresh(struct rpc_task *task); static void call_refreshresult(struct rpc_task *task); static void call_timeout(struct rpc_task *task); static void call_connect(struct rpc_task *task); static void call_connect_status(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
77 |
|
b0e1c57ea SUNRPC: Rename "c... |
78 79 |
static __be32 *rpc_encode_header(struct rpc_task *task); static __be32 *rpc_verify_header(struct rpc_task *task); |
caabea8a5 SUNRPC: Use soft ... |
80 |
static int rpc_ping(struct rpc_clnt *clnt); |
64c91a1f1 SUNRPC: Make rpc_... |
81 |
|
188fef11d SUNRPC: Move rpc_... |
82 83 |
static void rpc_register_client(struct rpc_clnt *clnt) { |
2446ab607 SUNRPC: Use RCU t... |
84 85 |
struct net *net = rpc_net_ns(clnt); struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
70abc49b4 SUNRPC: make SUNP... |
86 87 88 89 |
spin_lock(&sn->rpc_client_lock); list_add(&clnt->cl_clients, &sn->all_clients); spin_unlock(&sn->rpc_client_lock); |
188fef11d SUNRPC: Move rpc_... |
90 91 92 93 |
} static void rpc_unregister_client(struct rpc_clnt *clnt) { |
2446ab607 SUNRPC: Use RCU t... |
94 95 |
struct net *net = rpc_net_ns(clnt); struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
70abc49b4 SUNRPC: make SUNP... |
96 97 |
spin_lock(&sn->rpc_client_lock); |
188fef11d SUNRPC: Move rpc_... |
98 |
list_del(&clnt->cl_clients); |
70abc49b4 SUNRPC: make SUNP... |
99 |
spin_unlock(&sn->rpc_client_lock); |
188fef11d SUNRPC: Move rpc_... |
100 |
} |
1da177e4c Linux-2.6.12-rc2 |
101 |
|
0157d021d SUNRPC: handle RP... |
102 103 |
static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) { |
30507f58c SUNRPC: remove RP... |
104 |
if (clnt->cl_dentry) { |
80df9d202 SUNRPC: subscribe... |
105 106 |
if (clnt->cl_auth && clnt->cl_auth->au_ops->pipes_destroy) clnt->cl_auth->au_ops->pipes_destroy(clnt->cl_auth); |
30507f58c SUNRPC: remove RP... |
107 |
rpc_remove_client_dir(clnt->cl_dentry); |
80df9d202 SUNRPC: subscribe... |
108 |
} |
30507f58c SUNRPC: remove RP... |
109 |
clnt->cl_dentry = NULL; |
0157d021d SUNRPC: handle RP... |
110 111 112 113 |
} static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) { |
2446ab607 SUNRPC: Use RCU t... |
114 |
struct net *net = rpc_net_ns(clnt); |
0157d021d SUNRPC: handle RP... |
115 |
struct super_block *pipefs_sb; |
0157d021d SUNRPC: handle RP... |
116 |
|
2446ab607 SUNRPC: Use RCU t... |
117 |
pipefs_sb = rpc_get_sb_net(net); |
0157d021d SUNRPC: handle RP... |
118 |
if (pipefs_sb) { |
0157d021d SUNRPC: handle RP... |
119 |
__rpc_clnt_remove_pipedir(clnt); |
2446ab607 SUNRPC: Use RCU t... |
120 |
rpc_put_sb_net(net); |
0157d021d SUNRPC: handle RP... |
121 |
} |
0157d021d SUNRPC: handle RP... |
122 123 124 |
} static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb, |
080b794ce SUNRPC: constify ... |
125 126 |
struct rpc_clnt *clnt, const char *dir_name) |
1da177e4c Linux-2.6.12-rc2 |
127 |
{ |
f134585a7 Revert "[PATCH] R... |
128 |
static uint32_t clntid; |
23ac65817 SUNRPC: clean up ... |
129 |
char name[15]; |
26fe57502 vfs: make it poss... |
130 |
struct qstr q = { .name = name }; |
0157d021d SUNRPC: handle RP... |
131 |
struct dentry *dir, *dentry; |
1da177e4c Linux-2.6.12-rc2 |
132 |
int error; |
0157d021d SUNRPC: handle RP... |
133 |
dir = rpc_d_lookup_sb(sb, dir_name); |
922eeac30 SUNRPC: remove BU... |
134 135 136 |
if (dir == NULL) { pr_info("RPC: pipefs directory doesn't exist: %s ", dir_name); |
0157d021d SUNRPC: handle RP... |
137 |
return dir; |
922eeac30 SUNRPC: remove BU... |
138 |
} |
f134585a7 Revert "[PATCH] R... |
139 |
for (;;) { |
23ac65817 SUNRPC: clean up ... |
140 141 142 |
q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++); name[sizeof(name) - 1] = '\0'; q.hash = full_name_hash(q.name, q.len); |
0157d021d SUNRPC: handle RP... |
143 144 |
dentry = rpc_create_client_dir(dir, &q, clnt); if (!IS_ERR(dentry)) |
23ac65817 SUNRPC: clean up ... |
145 |
break; |
0157d021d SUNRPC: handle RP... |
146 |
error = PTR_ERR(dentry); |
f134585a7 Revert "[PATCH] R... |
147 |
if (error != -EEXIST) { |
23ac65817 SUNRPC: clean up ... |
148 149 150 151 |
printk(KERN_INFO "RPC: Couldn't create pipefs entry" " %s/%s, error %d ", dir_name, name, error); |
0157d021d SUNRPC: handle RP... |
152 |
break; |
f134585a7 Revert "[PATCH] R... |
153 |
} |
1da177e4c Linux-2.6.12-rc2 |
154 |
} |
0157d021d SUNRPC: handle RP... |
155 156 157 158 159 |
dput(dir); return dentry; } static int |
080b794ce SUNRPC: constify ... |
160 |
rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) |
0157d021d SUNRPC: handle RP... |
161 |
{ |
2446ab607 SUNRPC: Use RCU t... |
162 |
struct net *net = rpc_net_ns(clnt); |
0157d021d SUNRPC: handle RP... |
163 |
struct super_block *pipefs_sb; |
30507f58c SUNRPC: remove RP... |
164 |
struct dentry *dentry; |
0157d021d SUNRPC: handle RP... |
165 |
|
30507f58c SUNRPC: remove RP... |
166 |
clnt->cl_dentry = NULL; |
0157d021d SUNRPC: handle RP... |
167 168 |
if (dir_name == NULL) return 0; |
2446ab607 SUNRPC: Use RCU t... |
169 |
pipefs_sb = rpc_get_sb_net(net); |
70fe25b6e SUNRPC: remove RP... |
170 171 |
if (!pipefs_sb) return 0; |
30507f58c SUNRPC: remove RP... |
172 |
dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name); |
2446ab607 SUNRPC: Use RCU t... |
173 |
rpc_put_sb_net(net); |
30507f58c SUNRPC: remove RP... |
174 175 176 |
if (IS_ERR(dentry)) return PTR_ERR(dentry); clnt->cl_dentry = dentry; |
23ac65817 SUNRPC: clean up ... |
177 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
178 |
} |
ea8cfa067 SUNRPC: traverse ... |
179 180 181 182 183 184 185 186 187 188 |
static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) { if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) return 1; return 0; } static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event, struct super_block *sb) |
80df9d202 SUNRPC: subscribe... |
189 190 191 192 193 194 |
{ struct dentry *dentry; int err = 0; switch (event) { case RPC_PIPEFS_MOUNT: |
80df9d202 SUNRPC: subscribe... |
195 196 |
dentry = rpc_setup_pipedir_sb(sb, clnt, clnt->cl_program->pipe_dir_name); |
922eeac30 SUNRPC: remove BU... |
197 198 |
if (!dentry) return -ENOENT; |
80df9d202 SUNRPC: subscribe... |
199 200 |
if (IS_ERR(dentry)) return PTR_ERR(dentry); |
30507f58c SUNRPC: remove RP... |
201 |
clnt->cl_dentry = dentry; |
80df9d202 SUNRPC: subscribe... |
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
if (clnt->cl_auth->au_ops->pipes_create) { err = clnt->cl_auth->au_ops->pipes_create(clnt->cl_auth); if (err) __rpc_clnt_remove_pipedir(clnt); } break; case RPC_PIPEFS_UMOUNT: __rpc_clnt_remove_pipedir(clnt); break; default: printk(KERN_ERR "%s: unknown event: %ld ", __func__, event); return -ENOTSUPP; } return err; } |
ea8cfa067 SUNRPC: traverse ... |
218 219 220 221 222 223 224 225 226 227 228 229 230 |
static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, struct super_block *sb) { int error = 0; for (;; clnt = clnt->cl_parent) { if (!rpc_clnt_skip_event(clnt, event)) error = __rpc_clnt_handle_event(clnt, event, sb); if (error || clnt == clnt->cl_parent) break; } return error; } |
da3b46229 SUNRPC: release p... |
231 232 233 234 235 236 237 |
static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) { struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); struct rpc_clnt *clnt; spin_lock(&sn->rpc_client_lock); list_for_each_entry(clnt, &sn->all_clients, cl_clients) { |
7aab449e5 SUNRPC: skip clie... |
238 |
if (clnt->cl_program->pipe_dir_name == NULL) |
cd6c59685 SUNRPC: continue ... |
239 |
continue; |
ea8cfa067 SUNRPC: traverse ... |
240 |
if (rpc_clnt_skip_event(clnt, event)) |
da3b46229 SUNRPC: release p... |
241 |
continue; |
a4dff1bc4 SUNRPC: skip dead... |
242 243 |
if (atomic_inc_not_zero(&clnt->cl_count) == 0) continue; |
da3b46229 SUNRPC: release p... |
244 245 246 247 248 249 |
spin_unlock(&sn->rpc_client_lock); return clnt; } spin_unlock(&sn->rpc_client_lock); return NULL; } |
80df9d202 SUNRPC: subscribe... |
250 251 252 253 254 255 |
static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr) { struct super_block *sb = ptr; struct rpc_clnt *clnt; int error = 0; |
80df9d202 SUNRPC: subscribe... |
256 |
|
da3b46229 SUNRPC: release p... |
257 |
while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { |
80df9d202 SUNRPC: subscribe... |
258 |
error = __rpc_pipefs_event(clnt, event, sb); |
da3b46229 SUNRPC: release p... |
259 |
rpc_release_client(clnt); |
80df9d202 SUNRPC: subscribe... |
260 261 262 |
if (error) break; } |
80df9d202 SUNRPC: subscribe... |
263 264 265 266 267 |
return error; } static struct notifier_block rpc_clients_block = { .notifier_call = rpc_pipefs_event, |
eee17325f NFS: idmap PipeFS... |
268 |
.priority = SUNRPC_PIPEFS_RPC_PRIO, |
80df9d202 SUNRPC: subscribe... |
269 270 271 272 273 274 275 276 277 278 279 |
}; int rpc_clients_notifier_register(void) { return rpc_pipefs_notifier_register(&rpc_clients_block); } void rpc_clients_notifier_unregister(void) { return rpc_pipefs_notifier_unregister(&rpc_clients_block); } |
cbbb34498 SUNRPC: RPC clien... |
280 281 282 283 284 285 286 |
static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename) { clnt->cl_nodelen = strlen(nodename); if (clnt->cl_nodelen > UNX_MAXNODENAME) clnt->cl_nodelen = UNX_MAXNODENAME; memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); } |
698b6d088 SUNRPC: cleanup f... |
287 |
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
1da177e4c Linux-2.6.12-rc2 |
288 |
{ |
a613fa168 SUNRPC: constify ... |
289 290 |
const struct rpc_program *program = args->program; const struct rpc_version *version; |
1da177e4c Linux-2.6.12-rc2 |
291 |
struct rpc_clnt *clnt = NULL; |
6a19275ad [PATCH] RPC: [PAT... |
292 |
struct rpc_auth *auth; |
1da177e4c Linux-2.6.12-rc2 |
293 |
int err; |
06b8d2552 SUNRPC: Make sure... |
294 295 |
/* sanity check the name before trying to print it */ |
46121cf7d SUNRPC: fix print... |
296 297 |
dprintk("RPC: creating %s client for %s (xprt %p) ", |
698b6d088 SUNRPC: cleanup f... |
298 |
program->name, args->servername, xprt); |
1da177e4c Linux-2.6.12-rc2 |
299 |
|
4ada539ed SUNRPC: Make crea... |
300 301 302 |
err = rpciod_up(); if (err) goto out_no_rpciod; |
698b6d088 SUNRPC: cleanup f... |
303 |
|
f05c124a7 SUNRPC: Fix a pot... |
304 |
err = -EINVAL; |
698b6d088 SUNRPC: cleanup f... |
305 306 307 308 |
if (args->version >= program->nrvers) goto out_err; version = program->version[args->version]; if (version == NULL) |
1da177e4c Linux-2.6.12-rc2 |
309 310 311 |
goto out_err; err = -ENOMEM; |
0da974f4f [NET]: Conversion... |
312 |
clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
313 314 |
if (!clnt) goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
315 |
clnt->cl_parent = clnt; |
2446ab607 SUNRPC: Use RCU t... |
316 |
rcu_assign_pointer(clnt->cl_xprt, xprt); |
1da177e4c Linux-2.6.12-rc2 |
317 318 319 |
clnt->cl_procinfo = version->procs; clnt->cl_maxproc = version->nrprocs; clnt->cl_protname = program->name; |
d5b337b48 nfsd: use nfs cli... |
320 |
clnt->cl_prog = args->prognumber ? : program->number; |
1da177e4c Linux-2.6.12-rc2 |
321 |
clnt->cl_vers = version->number; |
1da177e4c Linux-2.6.12-rc2 |
322 |
clnt->cl_stats = program->stats; |
11c556b3d SUNRPC: provide a... |
323 |
clnt->cl_metrics = rpc_alloc_iostats(clnt); |
23bf85ba4 SUNRPC: Handle th... |
324 325 326 |
err = -ENOMEM; if (clnt->cl_metrics == NULL) goto out_no_stats; |
3e32a5d99 SUNRPC: Give clon... |
327 |
clnt->cl_program = program; |
6529eba08 SUNRPC: Move rpc_... |
328 |
INIT_LIST_HEAD(&clnt->cl_tasks); |
4bef61ff7 SUNRPC: Add a per... |
329 |
spin_lock_init(&clnt->cl_lock); |
1da177e4c Linux-2.6.12-rc2 |
330 |
|
2446ab607 SUNRPC: Use RCU t... |
331 |
if (!xprt_bound(xprt)) |
1da177e4c Linux-2.6.12-rc2 |
332 |
clnt->cl_autobind = 1; |
ba7392bb3 SUNRPC: Add suppo... |
333 334 335 336 337 338 |
clnt->cl_timeout = xprt->timeout; if (args->timeout != NULL) { memcpy(&clnt->cl_timeout_default, args->timeout, sizeof(clnt->cl_timeout_default)); clnt->cl_timeout = &clnt->cl_timeout_default; } |
1da177e4c Linux-2.6.12-rc2 |
339 |
clnt->cl_rtt = &clnt->cl_rtt_default; |
ba7392bb3 SUNRPC: Add suppo... |
340 |
rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); |
608207e88 rpc: pass target ... |
341 342 343 344 345 346 |
clnt->cl_principal = NULL; if (args->client_name) { clnt->cl_principal = kstrdup(args->client_name, GFP_KERNEL); if (!clnt->cl_principal) goto out_no_principal; } |
1da177e4c Linux-2.6.12-rc2 |
347 |
|
006abe887 SUNRPC: Fix a rac... |
348 |
atomic_set(&clnt->cl_count, 1); |
34f52e359 SUNRPC: Convert r... |
349 |
|
1da177e4c Linux-2.6.12-rc2 |
350 351 352 |
err = rpc_setup_pipedir(clnt, program->pipe_dir_name); if (err < 0) goto out_no_path; |
698b6d088 SUNRPC: cleanup f... |
353 |
auth = rpcauth_create(args->authflavor, clnt); |
6a19275ad [PATCH] RPC: [PAT... |
354 |
if (IS_ERR(auth)) { |
9b1d75b75 SUNRPC: Don't spa... |
355 356 |
dprintk("RPC: Couldn't create auth handle (flavor %u) ", |
698b6d088 SUNRPC: cleanup f... |
357 |
args->authflavor); |
6a19275ad [PATCH] RPC: [PAT... |
358 |
err = PTR_ERR(auth); |
1da177e4c Linux-2.6.12-rc2 |
359 360 361 362 |
goto out_no_auth; } /* save the nodename */ |
cbbb34498 SUNRPC: RPC clien... |
363 |
rpc_clnt_set_nodename(clnt, utsname()->nodename); |
6529eba08 SUNRPC: Move rpc_... |
364 |
rpc_register_client(clnt); |
1da177e4c Linux-2.6.12-rc2 |
365 366 367 |
return clnt; out_no_auth: |
0157d021d SUNRPC: handle RP... |
368 |
rpc_clnt_remove_pipedir(clnt); |
1da177e4c Linux-2.6.12-rc2 |
369 |
out_no_path: |
608207e88 rpc: pass target ... |
370 371 |
kfree(clnt->cl_principal); out_no_principal: |
23bf85ba4 SUNRPC: Handle th... |
372 373 |
rpc_free_iostats(clnt->cl_metrics); out_no_stats: |
1da177e4c Linux-2.6.12-rc2 |
374 375 |
kfree(clnt); out_err: |
4ada539ed SUNRPC: Make crea... |
376 377 |
rpciod_down(); out_no_rpciod: |
f05c124a7 SUNRPC: Fix a pot... |
378 |
xprt_put(xprt); |
1da177e4c Linux-2.6.12-rc2 |
379 380 |
return ERR_PTR(err); } |
2c53040f0 net: Fix (nearly-... |
381 |
/** |
c2866763b SUNRPC: use socka... |
382 383 384 385 386 387 388 389 390 391 392 393 394 |
* rpc_create - create an RPC client and transport with one call * @args: rpc_clnt create argument structure * * Creates and initializes an RPC transport and an RPC client. * * It can ping the server in order to determine if it is up, and to see if * it supports this program and version. RPC_CLNT_CREATE_NOPING disables * this behavior so asynchronous tasks can also use rpc_create. */ struct rpc_clnt *rpc_create(struct rpc_create_args *args) { struct rpc_xprt *xprt; struct rpc_clnt *clnt; |
3c341b0b9 SUNRPC: rename th... |
395 |
struct xprt_create xprtargs = { |
9a23e332e sunrpc: Add net t... |
396 |
.net = args->net, |
4fa016eb2 NFS/SUNRPC: suppo... |
397 |
.ident = args->protocol, |
d3bc9a1de SUNRPC client: ad... |
398 |
.srcaddr = args->saddress, |
96802a095 SUNRPC: cleanup t... |
399 400 |
.dstaddr = args->address, .addrlen = args->addrsize, |
4e0038b6b SUNRPC: Move clnt... |
401 |
.servername = args->servername, |
f300baba5 nfsd41: sunrpc: a... |
402 |
.bc_xprt = args->bc_xprt, |
96802a095 SUNRPC: cleanup t... |
403 |
}; |
510deb0d7 SUNRPC: rpc_creat... |
404 |
char servername[48]; |
c2866763b SUNRPC: use socka... |
405 |
|
b7993cebb SUNRPC: Allow rpc... |
406 407 |
if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS) xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS; |
33d90ac05 SUNRPC: allow dis... |
408 409 |
if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT) xprtargs.flags |= XPRT_CREATE_NO_IDLE_TIMEOUT; |
c2866763b SUNRPC: use socka... |
410 |
/* |
43780b87f SUNRPC: Add a con... |
411 412 413 |
* If the caller chooses not to specify a hostname, whip * up a string representation of the passed-in address. */ |
4e0038b6b SUNRPC: Move clnt... |
414 |
if (xprtargs.servername == NULL) { |
176e21ee2 SUNRPC: Support f... |
415 416 |
struct sockaddr_un *sun = (struct sockaddr_un *)args->address; |
da09eb930 SUNRPC: Clean up ... |
417 418 419 420 |
struct sockaddr_in *sin = (struct sockaddr_in *)args->address; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)args->address; |
510deb0d7 SUNRPC: rpc_creat... |
421 422 |
servername[0] = '\0'; switch (args->address->sa_family) { |
176e21ee2 SUNRPC: Support f... |
423 424 425 426 |
case AF_LOCAL: snprintf(servername, sizeof(servername), "%s", sun->sun_path); break; |
da09eb930 SUNRPC: Clean up ... |
427 |
case AF_INET: |
21454aaad net: replace NIPQ... |
428 429 |
snprintf(servername, sizeof(servername), "%pI4", &sin->sin_addr.s_addr); |
510deb0d7 SUNRPC: rpc_creat... |
430 |
break; |
da09eb930 SUNRPC: Clean up ... |
431 |
case AF_INET6: |
5b095d989 net: replace %p6 ... |
432 |
snprintf(servername, sizeof(servername), "%pI6", |
da09eb930 SUNRPC: Clean up ... |
433 |
&sin6->sin6_addr); |
510deb0d7 SUNRPC: rpc_creat... |
434 |
break; |
510deb0d7 SUNRPC: rpc_creat... |
435 436 437 438 439 |
default: /* caller wants default server name, but * address family isn't recognized. */ return ERR_PTR(-EINVAL); } |
4e0038b6b SUNRPC: Move clnt... |
440 |
xprtargs.servername = servername; |
43780b87f SUNRPC: Add a con... |
441 |
} |
510deb0d7 SUNRPC: rpc_creat... |
442 443 444 |
xprt = xprt_create_transport(&xprtargs); if (IS_ERR(xprt)) return (struct rpc_clnt *)xprt; |
43780b87f SUNRPC: Add a con... |
445 |
/* |
c2866763b SUNRPC: use socka... |
446 447 448 449 450 451 452 453 |
* By default, kernel RPC client connects from a reserved port. * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, * but it is always enabled for rpciod, which handles the connect * operation. */ xprt->resvport = 1; if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) xprt->resvport = 0; |
698b6d088 SUNRPC: cleanup f... |
454 |
clnt = rpc_new_client(args, xprt); |
c2866763b SUNRPC: use socka... |
455 456 457 458 |
if (IS_ERR(clnt)) return clnt; if (!(args->flags & RPC_CLNT_CREATE_NOPING)) { |
caabea8a5 SUNRPC: Use soft ... |
459 |
int err = rpc_ping(clnt); |
c2866763b SUNRPC: use socka... |
460 461 462 463 464 465 466 467 468 |
if (err != 0) { rpc_shutdown_client(clnt); return ERR_PTR(err); } } clnt->cl_softrtry = 1; if (args->flags & RPC_CLNT_CREATE_HARDRTRY) clnt->cl_softrtry = 0; |
c2866763b SUNRPC: use socka... |
469 470 |
if (args->flags & RPC_CLNT_CREATE_AUTOBIND) clnt->cl_autobind = 1; |
43d78ef2b NFS: disconnect b... |
471 472 |
if (args->flags & RPC_CLNT_CREATE_DISCRTRY) clnt->cl_discrtry = 1; |
b6b6152c4 rpc: bring back c... |
473 474 |
if (!(args->flags & RPC_CLNT_CREATE_QUIET)) clnt->cl_chatty = 1; |
c2866763b SUNRPC: use socka... |
475 476 477 |
return clnt; } |
b86acd501 SUNRPC: export ne... |
478 |
EXPORT_SYMBOL_GPL(rpc_create); |
c2866763b SUNRPC: use socka... |
479 |
|
1da177e4c Linux-2.6.12-rc2 |
480 481 482 483 484 |
/* * This function clones the RPC client structure. It allows us to share the * same transport while varying parameters such as the authentication * flavour. */ |
1b63a7518 SUNRPC: Refactor ... |
485 486 |
static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, struct rpc_clnt *clnt) |
1da177e4c Linux-2.6.12-rc2 |
487 |
{ |
2446ab607 SUNRPC: Use RCU t... |
488 |
struct rpc_xprt *xprt; |
1b63a7518 SUNRPC: Refactor ... |
489 490 |
struct rpc_clnt *new; int err; |
1da177e4c Linux-2.6.12-rc2 |
491 |
|
1b63a7518 SUNRPC: Refactor ... |
492 |
err = -ENOMEM; |
2446ab607 SUNRPC: Use RCU t... |
493 494 495 496 |
rcu_read_lock(); xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); rcu_read_unlock(); if (xprt == NULL) |
1b63a7518 SUNRPC: Refactor ... |
497 498 499 500 501 502 |
goto out_err; args->servername = xprt->servername; new = rpc_new_client(args, xprt); if (IS_ERR(new)) { err = PTR_ERR(new); |
a58e0be6f SUNRPC: Remove ex... |
503 |
goto out_err; |
1b63a7518 SUNRPC: Refactor ... |
504 |
} |
006abe887 SUNRPC: Fix a rac... |
505 |
atomic_inc(&clnt->cl_count); |
1b63a7518 SUNRPC: Refactor ... |
506 507 508 509 510 511 512 |
new->cl_parent = clnt; /* Turn off autobind on clones */ new->cl_autobind = 0; new->cl_softrtry = clnt->cl_softrtry; new->cl_discrtry = clnt->cl_discrtry; new->cl_chatty = clnt->cl_chatty; |
1da177e4c Linux-2.6.12-rc2 |
513 |
return new; |
1b63a7518 SUNRPC: Refactor ... |
514 |
|
1b63a7518 SUNRPC: Refactor ... |
515 |
out_err: |
0dc47877a net: replace rema... |
516 517 |
dprintk("RPC: %s: returned error %d ", __func__, err); |
3e32a5d99 SUNRPC: Give clon... |
518 |
return ERR_PTR(err); |
1da177e4c Linux-2.6.12-rc2 |
519 |
} |
1b63a7518 SUNRPC: Refactor ... |
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
/** * rpc_clone_client - Clone an RPC client structure * * @clnt: RPC client whose parameters are copied * * Returns a fresh RPC client or an ERR_PTR. */ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt) { struct rpc_create_args args = { .program = clnt->cl_program, .prognumber = clnt->cl_prog, .version = clnt->cl_vers, .authflavor = clnt->cl_auth->au_flavor, .client_name = clnt->cl_principal, }; return __rpc_clone_client(&args, clnt); } |
e8914c65f SUNRPC: Restrict ... |
539 |
EXPORT_SYMBOL_GPL(rpc_clone_client); |
1da177e4c Linux-2.6.12-rc2 |
540 |
|
ba9b584c1 SUNRPC: Introduce... |
541 542 543 544 |
/** * rpc_clone_client_set_auth - Clone an RPC client structure and set its auth * * @clnt: RPC client whose parameters are copied |
7144bca68 nfs: fix sunrpc/c... |
545 |
* @flavor: security flavor for new client |
ba9b584c1 SUNRPC: Introduce... |
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
* * Returns a fresh RPC client or an ERR_PTR. */ struct rpc_clnt * rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor) { struct rpc_create_args args = { .program = clnt->cl_program, .prognumber = clnt->cl_prog, .version = clnt->cl_vers, .authflavor = flavor, .client_name = clnt->cl_principal, }; return __rpc_clone_client(&args, clnt); } EXPORT_SYMBOL_GPL(rpc_clone_client_set_auth); |
1da177e4c Linux-2.6.12-rc2 |
562 |
/* |
58f9612c6 SUNRPC: Move rema... |
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 |
* Kill all tasks for the given client. * XXX: kill their descendants as well? */ void rpc_killall_tasks(struct rpc_clnt *clnt) { struct rpc_task *rovr; if (list_empty(&clnt->cl_tasks)) return; dprintk("RPC: killing all tasks for client %p ", clnt); /* * Spin lock all_tasks to prevent changes... */ spin_lock(&clnt->cl_lock); list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) { if (!RPC_IS_ACTIVATED(rovr)) continue; if (!(rovr->tk_flags & RPC_TASK_KILLED)) { rovr->tk_flags |= RPC_TASK_KILLED; rpc_exit(rovr, -EIO); |
8e26de238 RPC: killing RPC ... |
585 586 587 |
if (RPC_IS_QUEUED(rovr)) rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr); |
58f9612c6 SUNRPC: Move rema... |
588 589 590 591 592 593 594 |
} } spin_unlock(&clnt->cl_lock); } EXPORT_SYMBOL_GPL(rpc_killall_tasks); /* |
1da177e4c Linux-2.6.12-rc2 |
595 |
* Properly shut down an RPC client, terminating all outstanding |
90c5755ff SUNRPC: Kill rpc_... |
596 |
* requests. |
1da177e4c Linux-2.6.12-rc2 |
597 |
*/ |
4c402b409 SUNRPC: Remove rp... |
598 |
void rpc_shutdown_client(struct rpc_clnt *clnt) |
1da177e4c Linux-2.6.12-rc2 |
599 |
{ |
168e4b39d SUNRPC: add WARN_... |
600 |
might_sleep(); |
4e0038b6b SUNRPC: Move clnt... |
601 602 603 604 |
dprintk_rcu("RPC: shutting down %s client for %s ", clnt->cl_protname, rcu_dereference(clnt->cl_xprt)->servername); |
1da177e4c Linux-2.6.12-rc2 |
605 |
|
34f52e359 SUNRPC: Convert r... |
606 |
while (!list_empty(&clnt->cl_tasks)) { |
1da177e4c Linux-2.6.12-rc2 |
607 |
rpc_killall_tasks(clnt); |
532347e2b [PATCH] nfs: slee... |
608 |
wait_event_timeout(destroy_wait, |
34f52e359 SUNRPC: Convert r... |
609 |
list_empty(&clnt->cl_tasks), 1*HZ); |
1da177e4c Linux-2.6.12-rc2 |
610 |
} |
4c402b409 SUNRPC: Remove rp... |
611 |
rpc_release_client(clnt); |
1da177e4c Linux-2.6.12-rc2 |
612 |
} |
e8914c65f SUNRPC: Restrict ... |
613 |
EXPORT_SYMBOL_GPL(rpc_shutdown_client); |
1da177e4c Linux-2.6.12-rc2 |
614 615 |
/* |
34f52e359 SUNRPC: Convert r... |
616 |
* Free an RPC client |
1da177e4c Linux-2.6.12-rc2 |
617 |
*/ |
34f52e359 SUNRPC: Convert r... |
618 |
static void |
006abe887 SUNRPC: Fix a rac... |
619 |
rpc_free_client(struct rpc_clnt *clnt) |
1da177e4c Linux-2.6.12-rc2 |
620 |
{ |
4e0038b6b SUNRPC: Move clnt... |
621 622 623 624 |
dprintk_rcu("RPC: destroying %s client for %s ", clnt->cl_protname, rcu_dereference(clnt->cl_xprt)->servername); |
6eac7d3f4 SUNRPC: constify ... |
625 |
if (clnt->cl_parent != clnt) |
8ad7c892e SUNRPC: Make rpc_... |
626 |
rpc_release_client(clnt->cl_parent); |
6529eba08 SUNRPC: Move rpc_... |
627 |
rpc_unregister_client(clnt); |
f5131257f SUNRPC: remove RP... |
628 |
rpc_clnt_remove_pipedir(clnt); |
11c556b3d SUNRPC: provide a... |
629 |
rpc_free_iostats(clnt->cl_metrics); |
608207e88 rpc: pass target ... |
630 |
kfree(clnt->cl_principal); |
11c556b3d SUNRPC: provide a... |
631 |
clnt->cl_metrics = NULL; |
2446ab607 SUNRPC: Use RCU t... |
632 |
xprt_put(rcu_dereference_raw(clnt->cl_xprt)); |
4ada539ed SUNRPC: Make crea... |
633 |
rpciod_down(); |
1da177e4c Linux-2.6.12-rc2 |
634 |
kfree(clnt); |
1da177e4c Linux-2.6.12-rc2 |
635 636 637 |
} /* |
1dd17ec69 SUNRPC: Allow rpc... |
638 639 640 |
* Free an RPC client */ static void |
006abe887 SUNRPC: Fix a rac... |
641 |
rpc_free_auth(struct rpc_clnt *clnt) |
1dd17ec69 SUNRPC: Allow rpc... |
642 |
{ |
1dd17ec69 SUNRPC: Allow rpc... |
643 |
if (clnt->cl_auth == NULL) { |
006abe887 SUNRPC: Fix a rac... |
644 |
rpc_free_client(clnt); |
1dd17ec69 SUNRPC: Allow rpc... |
645 646 647 648 649 650 651 652 |
return; } /* * Note: RPCSEC_GSS may need to send NULL RPC calls in order to * release remaining GSS contexts. This mechanism ensures * that it can do so safely. */ |
006abe887 SUNRPC: Fix a rac... |
653 |
atomic_inc(&clnt->cl_count); |
1dd17ec69 SUNRPC: Allow rpc... |
654 655 |
rpcauth_release(clnt->cl_auth); clnt->cl_auth = NULL; |
006abe887 SUNRPC: Fix a rac... |
656 657 |
if (atomic_dec_and_test(&clnt->cl_count)) rpc_free_client(clnt); |
1dd17ec69 SUNRPC: Allow rpc... |
658 659 660 |
} /* |
34f52e359 SUNRPC: Convert r... |
661 |
* Release reference to the RPC client |
1da177e4c Linux-2.6.12-rc2 |
662 663 664 665 |
*/ void rpc_release_client(struct rpc_clnt *clnt) { |
34f52e359 SUNRPC: Convert r... |
666 667 |
dprintk("RPC: rpc_release_client(%p) ", clnt); |
1da177e4c Linux-2.6.12-rc2 |
668 |
|
34f52e359 SUNRPC: Convert r... |
669 670 |
if (list_empty(&clnt->cl_tasks)) wake_up(&destroy_wait); |
006abe887 SUNRPC: Fix a rac... |
671 672 |
if (atomic_dec_and_test(&clnt->cl_count)) rpc_free_auth(clnt); |
34f52e359 SUNRPC: Convert r... |
673 |
} |
1d658336b SUNRPC: Add RPC b... |
674 |
EXPORT_SYMBOL_GPL(rpc_release_client); |
34f52e359 SUNRPC: Convert r... |
675 |
|
007e251f2 [PATCH] RPC: Allo... |
676 677 |
/** * rpc_bind_new_program - bind a new RPC program to an existing client |
65b6e42cd docbook: sunrpc f... |
678 679 680 |
* @old: old rpc_client * @program: rpc program to set * @vers: rpc program version |
007e251f2 [PATCH] RPC: Allo... |
681 682 683 684 685 686 |
* * Clones the rpc client and sets up a new RPC program. This is mainly * of use for enabling different RPC programs to share the same transport. * The Sun NFSv2/v3 ACL protocol can do this. */ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, |
a613fa168 SUNRPC: constify ... |
687 |
const struct rpc_program *program, |
89eb21c35 SUNRPC: fix a sig... |
688 |
u32 vers) |
007e251f2 [PATCH] RPC: Allo... |
689 |
{ |
f994c43d1 SUNRPC: Clean up ... |
690 691 692 693 694 695 696 |
struct rpc_create_args args = { .program = program, .prognumber = program->number, .version = vers, .authflavor = old->cl_auth->au_flavor, .client_name = old->cl_principal, }; |
007e251f2 [PATCH] RPC: Allo... |
697 |
struct rpc_clnt *clnt; |
007e251f2 [PATCH] RPC: Allo... |
698 |
int err; |
f994c43d1 SUNRPC: Clean up ... |
699 |
clnt = __rpc_clone_client(&args, old); |
007e251f2 [PATCH] RPC: Allo... |
700 701 |
if (IS_ERR(clnt)) goto out; |
caabea8a5 SUNRPC: Use soft ... |
702 |
err = rpc_ping(clnt); |
007e251f2 [PATCH] RPC: Allo... |
703 704 705 706 |
if (err != 0) { rpc_shutdown_client(clnt); clnt = ERR_PTR(err); } |
cca5172a7 [NET] SUNRPC: Fix... |
707 |
out: |
007e251f2 [PATCH] RPC: Allo... |
708 709 |
return clnt; } |
e8914c65f SUNRPC: Restrict ... |
710 |
EXPORT_SYMBOL_GPL(rpc_bind_new_program); |
007e251f2 [PATCH] RPC: Allo... |
711 |
|
58f9612c6 SUNRPC: Move rema... |
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 |
void rpc_task_release_client(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; if (clnt != NULL) { /* Remove from client task list */ spin_lock(&clnt->cl_lock); list_del(&task->tk_task); spin_unlock(&clnt->cl_lock); task->tk_client = NULL; rpc_release_client(clnt); } } static void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) { if (clnt != NULL) { rpc_task_release_client(task); task->tk_client = clnt; |
006abe887 SUNRPC: Fix a rac... |
733 |
atomic_inc(&clnt->cl_count); |
58f9612c6 SUNRPC: Move rema... |
734 735 |
if (clnt->cl_softrtry) task->tk_flags |= RPC_TASK_SOFT; |
a564b8f03 nfs: enable swap ... |
736 737 738 739 740 741 742 743 744 |
if (sk_memalloc_socks()) { struct rpc_xprt *xprt; rcu_read_lock(); xprt = rcu_dereference(clnt->cl_xprt); if (xprt->swapper) task->tk_flags |= RPC_TASK_SWAPPER; rcu_read_unlock(); } |
58f9612c6 SUNRPC: Move rema... |
745 746 747 748 749 750 |
/* Add to the client's list of all tasks */ spin_lock(&clnt->cl_lock); list_add_tail(&task->tk_task, &clnt->cl_tasks); spin_unlock(&clnt->cl_lock); } } |
cbdabc7f8 NFSv4.1: filelayo... |
751 752 753 754 755 756 |
void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt) { rpc_task_release_client(task); rpc_task_set_client(task, clnt); } EXPORT_SYMBOL_GPL(rpc_task_reset_client); |
58f9612c6 SUNRPC: Move rema... |
757 758 759 760 761 762 763 |
static void rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) { if (msg != NULL) { task->tk_msg.rpc_proc = msg->rpc_proc; task->tk_msg.rpc_argp = msg->rpc_argp; task->tk_msg.rpc_resp = msg->rpc_resp; |
a17c2153d SUNRPC: Move the ... |
764 765 |
if (msg->rpc_cred != NULL) task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred); |
58f9612c6 SUNRPC: Move rema... |
766 767 |
} } |
1da177e4c Linux-2.6.12-rc2 |
768 769 770 771 |
/* * Default callback for async RPC calls */ static void |
963d8fe53 RPC: Clean up RPC... |
772 |
rpc_default_callback(struct rpc_task *task, void *data) |
1da177e4c Linux-2.6.12-rc2 |
773 774 |
{ } |
963d8fe53 RPC: Clean up RPC... |
775 776 777 |
static const struct rpc_call_ops rpc_default_ops = { .rpc_call_done = rpc_default_callback, }; |
c970aa85e SUNRPC: Clean up ... |
778 779 780 781 782 |
/** * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it * @task_setup_data: pointer to task initialisation data */ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data) |
6e5b70e9d SUNRPC: clean up ... |
783 |
{ |
19445b99b SUNRPC: Cleanup -... |
784 |
struct rpc_task *task; |
6e5b70e9d SUNRPC: clean up ... |
785 |
|
84115e1cd SUNRPC: Cleanup o... |
786 |
task = rpc_new_task(task_setup_data); |
19445b99b SUNRPC: Cleanup -... |
787 |
if (IS_ERR(task)) |
508592590 SUNRPC: Mask sign... |
788 |
goto out; |
6e5b70e9d SUNRPC: clean up ... |
789 |
|
58f9612c6 SUNRPC: Move rema... |
790 791 |
rpc_task_set_client(task, task_setup_data->rpc_client); rpc_task_set_rpc_message(task, task_setup_data->rpc_message); |
58f9612c6 SUNRPC: Move rema... |
792 793 |
if (task->tk_action == NULL) rpc_call_start(task); |
6e5b70e9d SUNRPC: clean up ... |
794 795 |
atomic_inc(&task->tk_count); rpc_execute(task); |
6e5b70e9d SUNRPC: clean up ... |
796 |
out: |
19445b99b SUNRPC: Cleanup -... |
797 |
return task; |
6e5b70e9d SUNRPC: clean up ... |
798 |
} |
c970aa85e SUNRPC: Clean up ... |
799 |
EXPORT_SYMBOL_GPL(rpc_run_task); |
6e5b70e9d SUNRPC: clean up ... |
800 801 802 803 804 805 |
/** * rpc_call_sync - Perform a synchronous RPC call * @clnt: pointer to RPC client * @msg: RPC call parameters * @flags: RPC call flags |
1da177e4c Linux-2.6.12-rc2 |
806 |
*/ |
cbc200592 SUNRPC: Declare a... |
807 |
int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags) |
1da177e4c Linux-2.6.12-rc2 |
808 809 |
{ struct rpc_task *task; |
84115e1cd SUNRPC: Cleanup o... |
810 811 812 813 814 815 |
struct rpc_task_setup task_setup_data = { .rpc_client = clnt, .rpc_message = msg, .callback_ops = &rpc_default_ops, .flags = flags, }; |
6e5b70e9d SUNRPC: clean up ... |
816 |
int status; |
1da177e4c Linux-2.6.12-rc2 |
817 |
|
50d2bdb19 SUNRPC: remove BU... |
818 819 820 821 822 823 |
WARN_ON_ONCE(flags & RPC_TASK_ASYNC); if (flags & RPC_TASK_ASYNC) { rpc_release_calldata(task_setup_data.callback_ops, task_setup_data.callback_data); return -EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
824 |
|
c970aa85e SUNRPC: Clean up ... |
825 |
task = rpc_run_task(&task_setup_data); |
6e5b70e9d SUNRPC: clean up ... |
826 827 |
if (IS_ERR(task)) return PTR_ERR(task); |
e60859ac0 SUNRPC: rpc_execu... |
828 |
status = task->tk_status; |
bde8f00ce [PATCH] NFS: Fix ... |
829 |
rpc_put_task(task); |
1da177e4c Linux-2.6.12-rc2 |
830 831 |
return status; } |
e8914c65f SUNRPC: Restrict ... |
832 |
EXPORT_SYMBOL_GPL(rpc_call_sync); |
1da177e4c Linux-2.6.12-rc2 |
833 |
|
6e5b70e9d SUNRPC: clean up ... |
834 835 836 837 838 |
/** * rpc_call_async - Perform an asynchronous RPC call * @clnt: pointer to RPC client * @msg: RPC call parameters * @flags: RPC call flags |
65b6e42cd docbook: sunrpc f... |
839 |
* @tk_ops: RPC call ops |
6e5b70e9d SUNRPC: clean up ... |
840 |
* @data: user call data |
1da177e4c Linux-2.6.12-rc2 |
841 842 |
*/ int |
cbc200592 SUNRPC: Declare a... |
843 |
rpc_call_async(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags, |
963d8fe53 RPC: Clean up RPC... |
844 |
const struct rpc_call_ops *tk_ops, void *data) |
1da177e4c Linux-2.6.12-rc2 |
845 846 |
{ struct rpc_task *task; |
84115e1cd SUNRPC: Cleanup o... |
847 848 849 850 851 852 853 |
struct rpc_task_setup task_setup_data = { .rpc_client = clnt, .rpc_message = msg, .callback_ops = tk_ops, .callback_data = data, .flags = flags|RPC_TASK_ASYNC, }; |
1da177e4c Linux-2.6.12-rc2 |
854 |
|
c970aa85e SUNRPC: Clean up ... |
855 |
task = rpc_run_task(&task_setup_data); |
6e5b70e9d SUNRPC: clean up ... |
856 857 858 859 |
if (IS_ERR(task)) return PTR_ERR(task); rpc_put_task(task); return 0; |
1da177e4c Linux-2.6.12-rc2 |
860 |
} |
e8914c65f SUNRPC: Restrict ... |
861 |
EXPORT_SYMBOL_GPL(rpc_call_async); |
1da177e4c Linux-2.6.12-rc2 |
862 |
|
9e00abc3c SUNRPC: sunrpc sh... |
863 |
#if defined(CONFIG_SUNRPC_BACKCHANNEL) |
55ae1aabf nfs41: Add backch... |
864 865 866 |
/** * rpc_run_bc_task - Allocate a new RPC task for backchannel use, then run * rpc_execute against it |
7a73fdde3 net: fix htmldocs... |
867 868 |
* @req: RPC request * @tk_ops: RPC call ops |
55ae1aabf nfs41: Add backch... |
869 870 |
*/ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, |
7a73fdde3 net: fix htmldocs... |
871 |
const struct rpc_call_ops *tk_ops) |
55ae1aabf nfs41: Add backch... |
872 873 874 875 876 877 878 879 880 881 882 883 884 |
{ struct rpc_task *task; struct xdr_buf *xbufp = &req->rq_snd_buf; struct rpc_task_setup task_setup_data = { .callback_ops = tk_ops, }; dprintk("RPC: rpc_run_bc_task req= %p ", req); /* * Create an rpc_task to send the data */ task = rpc_new_task(&task_setup_data); |
19445b99b SUNRPC: Cleanup -... |
885 |
if (IS_ERR(task)) { |
55ae1aabf nfs41: Add backch... |
886 887 888 889 890 891 892 893 894 895 896 897 898 899 |
xprt_free_bc_request(req); goto out; } task->tk_rqstp = req; /* * Set up the xdr_buf length. * This also indicates that the buffer is XDR encoded already. */ xbufp->len = xbufp->head[0].iov_len + xbufp->page_len + xbufp->tail[0].iov_len; task->tk_action = call_bc_transmit; atomic_inc(&task->tk_count); |
9a6478f6c SUNRPC: remove BU... |
900 |
WARN_ON_ONCE(atomic_read(&task->tk_count) != 2); |
55ae1aabf nfs41: Add backch... |
901 902 903 904 905 906 907 |
rpc_execute(task); out: dprintk("RPC: rpc_run_bc_task: task= %p ", task); return task; } |
9e00abc3c SUNRPC: sunrpc sh... |
908 |
#endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
55ae1aabf nfs41: Add backch... |
909 |
|
1da177e4c Linux-2.6.12-rc2 |
910 |
void |
77de2c590 SUNRPC: Add a hel... |
911 912 913 914 915 |
rpc_call_start(struct rpc_task *task) { task->tk_action = call_start; } EXPORT_SYMBOL_GPL(rpc_call_start); |
ed39440a2 SUNRPC: create AP... |
916 917 918 919 |
/** * rpc_peeraddr - extract remote peer address from clnt's xprt * @clnt: RPC client structure * @buf: target buffer |
65b6e42cd docbook: sunrpc f... |
920 |
* @bufsize: length of target buffer |
ed39440a2 SUNRPC: create AP... |
921 922 923 924 925 926 |
* * Returns the number of bytes that are actually in the stored address. */ size_t rpc_peeraddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t bufsize) { size_t bytes; |
2446ab607 SUNRPC: Use RCU t... |
927 928 929 930 |
struct rpc_xprt *xprt; rcu_read_lock(); xprt = rcu_dereference(clnt->cl_xprt); |
ed39440a2 SUNRPC: create AP... |
931 |
|
2446ab607 SUNRPC: Use RCU t... |
932 |
bytes = xprt->addrlen; |
ed39440a2 SUNRPC: create AP... |
933 934 |
if (bytes > bufsize) bytes = bufsize; |
2446ab607 SUNRPC: Use RCU t... |
935 936 937 938 |
memcpy(buf, &xprt->addr, bytes); rcu_read_unlock(); return bytes; |
ed39440a2 SUNRPC: create AP... |
939 |
} |
b86acd501 SUNRPC: export ne... |
940 |
EXPORT_SYMBOL_GPL(rpc_peeraddr); |
ed39440a2 SUNRPC: create AP... |
941 |
|
f425eba43 SUNRPC: Create AP... |
942 943 944 945 946 |
/** * rpc_peeraddr2str - return remote peer address in printable format * @clnt: RPC client structure * @format: address format * |
2446ab607 SUNRPC: Use RCU t... |
947 948 949 |
* NB: the lifetime of the memory referenced by the returned pointer is * the same as the rpc_xprt itself. As long as the caller uses this * pointer, it must hold the RCU read lock. |
f425eba43 SUNRPC: Create AP... |
950 |
*/ |
b454ae906 SUNRPC: fewer con... |
951 952 |
const char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format) |
f425eba43 SUNRPC: Create AP... |
953 |
{ |
2446ab607 SUNRPC: Use RCU t... |
954 955 956 |
struct rpc_xprt *xprt; xprt = rcu_dereference(clnt->cl_xprt); |
7559c7a28 SUNRPC: Make addr... |
957 958 959 960 961 |
if (xprt->address_strings[format] != NULL) return xprt->address_strings[format]; else return "unprintable"; |
f425eba43 SUNRPC: Create AP... |
962 |
} |
b86acd501 SUNRPC: export ne... |
963 |
EXPORT_SYMBOL_GPL(rpc_peeraddr2str); |
f425eba43 SUNRPC: Create AP... |
964 |
|
2e738fdce SUNRPC: Add API t... |
965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 |
static const struct sockaddr_in rpc_inaddr_loopback = { .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_ANY), }; static const struct sockaddr_in6 rpc_in6addr_loopback = { .sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, }; /* * Try a getsockname() on a connected datagram socket. Using a * connected datagram socket prevents leaving a socket in TIME_WAIT. * This conserves the ephemeral port number space. * * Returns zero and fills in "buf" if successful; otherwise, a * negative errno is returned. */ static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen, struct sockaddr *buf, int buflen) { struct socket *sock; int err; err = __sock_create(net, sap->sa_family, SOCK_DGRAM, IPPROTO_UDP, &sock, 1); if (err < 0) { dprintk("RPC: can't create UDP socket (%d) ", err); goto out; } switch (sap->sa_family) { case AF_INET: err = kernel_bind(sock, (struct sockaddr *)&rpc_inaddr_loopback, sizeof(rpc_inaddr_loopback)); break; case AF_INET6: err = kernel_bind(sock, (struct sockaddr *)&rpc_in6addr_loopback, sizeof(rpc_in6addr_loopback)); break; default: err = -EAFNOSUPPORT; goto out; } if (err < 0) { dprintk("RPC: can't bind UDP socket (%d) ", err); goto out_release; } err = kernel_connect(sock, sap, salen, 0); if (err < 0) { dprintk("RPC: can't connect UDP socket (%d) ", err); goto out_release; } err = kernel_getsockname(sock, buf, &buflen); if (err < 0) { dprintk("RPC: getsockname failed (%d) ", err); goto out_release; } err = 0; if (buf->sa_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf; sin6->sin6_scope_id = 0; } dprintk("RPC: %s succeeded ", __func__); out_release: sock_release(sock); out: return err; } /* * Scraping a connected socket failed, so we don't have a useable * local address. Fallback: generate an address that will prevent * the server from calling us back. * * Returns zero and fills in "buf" if successful; otherwise, a * negative errno is returned. */ static int rpc_anyaddr(int family, struct sockaddr *buf, size_t buflen) { switch (family) { case AF_INET: if (buflen < sizeof(rpc_inaddr_loopback)) return -EINVAL; memcpy(buf, &rpc_inaddr_loopback, sizeof(rpc_inaddr_loopback)); break; case AF_INET6: if (buflen < sizeof(rpc_in6addr_loopback)) return -EINVAL; memcpy(buf, &rpc_in6addr_loopback, sizeof(rpc_in6addr_loopback)); default: dprintk("RPC: %s: address family not supported ", __func__); return -EAFNOSUPPORT; } dprintk("RPC: %s: succeeded ", __func__); return 0; } /** * rpc_localaddr - discover local endpoint address for an RPC client * @clnt: RPC client structure * @buf: target buffer * @buflen: size of target buffer, in bytes * * Returns zero and fills in "buf" and "buflen" if successful; * otherwise, a negative errno is returned. * * This works even if the underlying transport is not currently connected, * or if the upper layer never previously provided a source address. * * The result of this function call is transient: multiple calls in * succession may give different results, depending on how local * networking configuration changes over time. */ int rpc_localaddr(struct rpc_clnt *clnt, struct sockaddr *buf, size_t buflen) { struct sockaddr_storage address; struct sockaddr *sap = (struct sockaddr *)&address; struct rpc_xprt *xprt; struct net *net; size_t salen; int err; rcu_read_lock(); xprt = rcu_dereference(clnt->cl_xprt); salen = xprt->addrlen; memcpy(sap, &xprt->addr, salen); net = get_net(xprt->xprt_net); rcu_read_unlock(); rpc_set_port(sap, 0); err = rpc_sockname(net, sap, salen, buf, buflen); put_net(net); if (err != 0) /* Couldn't discover local address, return ANYADDR */ return rpc_anyaddr(sap->sa_family, buf, buflen); return 0; } EXPORT_SYMBOL_GPL(rpc_localaddr); |
1da177e4c Linux-2.6.12-rc2 |
1120 1121 1122 |
void rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize) { |
2446ab607 SUNRPC: Use RCU t... |
1123 1124 1125 1126 |
struct rpc_xprt *xprt; rcu_read_lock(); xprt = rcu_dereference(clnt->cl_xprt); |
470056c28 [PATCH] RPC: rati... |
1127 1128 |
if (xprt->ops->set_buffer_size) xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); |
2446ab607 SUNRPC: Use RCU t... |
1129 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
1130 |
} |
e8914c65f SUNRPC: Restrict ... |
1131 |
EXPORT_SYMBOL_GPL(rpc_setbufsize); |
1da177e4c Linux-2.6.12-rc2 |
1132 |
|
2446ab607 SUNRPC: Use RCU t... |
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 |
/** * rpc_protocol - Get transport protocol number for an RPC client * @clnt: RPC client to query * */ int rpc_protocol(struct rpc_clnt *clnt) { int protocol; rcu_read_lock(); protocol = rcu_dereference(clnt->cl_xprt)->prot; rcu_read_unlock(); return protocol; } EXPORT_SYMBOL_GPL(rpc_protocol); /** * rpc_net_ns - Get the network namespace for this RPC client * @clnt: RPC client to query * */ struct net *rpc_net_ns(struct rpc_clnt *clnt) { struct net *ret; rcu_read_lock(); ret = rcu_dereference(clnt->cl_xprt)->xprt_net; rcu_read_unlock(); return ret; } EXPORT_SYMBOL_GPL(rpc_net_ns); /** * rpc_max_payload - Get maximum payload size for a transport, in bytes * @clnt: RPC client to query |
1da177e4c Linux-2.6.12-rc2 |
1168 1169 1170 1171 1172 1173 1174 1175 |
* * For stream transports, this is one RPC record fragment (see RFC * 1831), as we don't support multi-record requests yet. For datagram * transports, this is the size of an IP packet minus the IP, UDP, and * RPC header sizes. */ size_t rpc_max_payload(struct rpc_clnt *clnt) { |
2446ab607 SUNRPC: Use RCU t... |
1176 1177 1178 1179 1180 1181 |
size_t ret; rcu_read_lock(); ret = rcu_dereference(clnt->cl_xprt)->max_payload; rcu_read_unlock(); return ret; |
1da177e4c Linux-2.6.12-rc2 |
1182 |
} |
b86acd501 SUNRPC: export ne... |
1183 |
EXPORT_SYMBOL_GPL(rpc_max_payload); |
1da177e4c Linux-2.6.12-rc2 |
1184 |
|
35f5a422c SUNRPC: new inter... |
1185 |
/** |
512e4b291 SUNRPC: One line ... |
1186 |
* rpc_get_timeout - Get timeout for transport in units of HZ |
edddbb1ed SUNRPC: add call ... |
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 |
* @clnt: RPC client to query */ unsigned long rpc_get_timeout(struct rpc_clnt *clnt) { unsigned long ret; rcu_read_lock(); ret = rcu_dereference(clnt->cl_xprt)->timeout->to_initval; rcu_read_unlock(); return ret; } EXPORT_SYMBOL_GPL(rpc_get_timeout); /** |
35f5a422c SUNRPC: new inter... |
1201 1202 1203 1204 1205 1206 |
* rpc_force_rebind - force transport to check that remote port is unchanged * @clnt: client to rebind * */ void rpc_force_rebind(struct rpc_clnt *clnt) { |
2446ab607 SUNRPC: Use RCU t... |
1207 1208 1209 1210 1211 |
if (clnt->cl_autobind) { rcu_read_lock(); xprt_clear_bound(rcu_dereference(clnt->cl_xprt)); rcu_read_unlock(); } |
35f5a422c SUNRPC: new inter... |
1212 |
} |
b86acd501 SUNRPC: export ne... |
1213 |
EXPORT_SYMBOL_GPL(rpc_force_rebind); |
35f5a422c SUNRPC: new inter... |
1214 |
|
1da177e4c Linux-2.6.12-rc2 |
1215 |
/* |
aae2006e9 nfs41: sunrpc: Ex... |
1216 1217 1218 |
* Restart an (async) RPC call from the call_prepare state. * Usually called from within the exit handler. */ |
f1f88fc7e SUNRPC: The funct... |
1219 |
int |
aae2006e9 nfs41: sunrpc: Ex... |
1220 1221 1222 |
rpc_restart_call_prepare(struct rpc_task *task) { if (RPC_ASSASSINATED(task)) |
f1f88fc7e SUNRPC: The funct... |
1223 |
return 0; |
d00c5d438 NFS: Get rid of n... |
1224 1225 1226 |
task->tk_action = call_start; if (task->tk_ops->rpc_call_prepare != NULL) task->tk_action = rpc_prepare_task; |
f1f88fc7e SUNRPC: The funct... |
1227 |
return 1; |
aae2006e9 nfs41: sunrpc: Ex... |
1228 1229 1230 1231 |
} EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); /* |
1da177e4c Linux-2.6.12-rc2 |
1232 1233 1234 |
* Restart an (async) RPC call. Usually called from within the * exit handler. */ |
f1f88fc7e SUNRPC: The funct... |
1235 |
int |
1da177e4c Linux-2.6.12-rc2 |
1236 1237 1238 |
rpc_restart_call(struct rpc_task *task) { if (RPC_ASSASSINATED(task)) |
f1f88fc7e SUNRPC: The funct... |
1239 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1240 |
task->tk_action = call_start; |
f1f88fc7e SUNRPC: The funct... |
1241 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
1242 |
} |
e8914c65f SUNRPC: Restrict ... |
1243 |
EXPORT_SYMBOL_GPL(rpc_restart_call); |
1da177e4c Linux-2.6.12-rc2 |
1244 |
|
3748f1e44 SUNRPC: Add a fun... |
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 |
#ifdef RPC_DEBUG static const char *rpc_proc_name(const struct rpc_task *task) { const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; if (proc) { if (proc->p_name) return proc->p_name; else return "NULL"; } else return "no proc"; } #endif |
1da177e4c Linux-2.6.12-rc2 |
1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 |
/* * 0. Initial state * * Other FSM states can be visited zero or more times, but * this state is visited exactly once for each RPC. */ static void call_start(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; |
3748f1e44 SUNRPC: Add a fun... |
1269 1270 |
dprintk("RPC: %5u call_start %s%d proc %s (%s) ", task->tk_pid, |
46121cf7d SUNRPC: fix print... |
1271 |
clnt->cl_protname, clnt->cl_vers, |
3748f1e44 SUNRPC: Add a fun... |
1272 |
rpc_proc_name(task), |
46121cf7d SUNRPC: fix print... |
1273 |
(RPC_IS_ASYNC(task) ? "async" : "sync")); |
1da177e4c Linux-2.6.12-rc2 |
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 |
/* Increment call count */ task->tk_msg.rpc_proc->p_count++; clnt->cl_stats->rpccnt++; task->tk_action = call_reserve; } /* * 1. Reserve an RPC call slot */ static void call_reserve(struct rpc_task *task) { |
46121cf7d SUNRPC: fix print... |
1287 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1288 |
|
1da177e4c Linux-2.6.12-rc2 |
1289 1290 1291 1292 |
task->tk_status = 0; task->tk_action = call_reserveresult; xprt_reserve(task); } |
ba60eb25f SUNRPC: Fix a liv... |
1293 |
static void call_retry_reserve(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
1294 1295 1296 1297 1298 1299 1300 |
/* * 1b. Grok the result of xprt_reserve() */ static void call_reserveresult(struct rpc_task *task) { int status = task->tk_status; |
46121cf7d SUNRPC: fix print... |
1301 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1302 1303 1304 1305 1306 1307 1308 1309 |
/* * After a call to xprt_reserve(), we must have either * a request slot or else an error status. */ task->tk_status = 0; if (status >= 0) { if (task->tk_rqstp) { |
f2d47d02f Fix null derefere... |
1310 |
task->tk_action = call_refresh; |
1da177e4c Linux-2.6.12-rc2 |
1311 1312 1313 1314 1315 |
return; } printk(KERN_ERR "%s: status=%d, but no request slot, exiting ", |
0dc47877a net: replace rema... |
1316 |
__func__, status); |
1da177e4c Linux-2.6.12-rc2 |
1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 |
rpc_exit(task, -EIO); return; } /* * Even though there was an error, we may have acquired * a request slot somehow. Make sure not to leak it. */ if (task->tk_rqstp) { printk(KERN_ERR "%s: status=%d, request allocated anyway ", |
0dc47877a net: replace rema... |
1328 |
__func__, status); |
1da177e4c Linux-2.6.12-rc2 |
1329 1330 1331 1332 |
xprt_release(task); } switch (status) { |
1afeaf5c2 sunrpc: fix loss ... |
1333 1334 |
case -ENOMEM: rpc_delay(task, HZ >> 2); |
1da177e4c Linux-2.6.12-rc2 |
1335 |
case -EAGAIN: /* woken up; retry */ |
ba60eb25f SUNRPC: Fix a liv... |
1336 |
task->tk_action = call_retry_reserve; |
1da177e4c Linux-2.6.12-rc2 |
1337 1338 1339 1340 1341 1342 |
return; case -EIO: /* probably a shutdown */ break; default: printk(KERN_ERR "%s: unrecognized error %d, exiting ", |
0dc47877a net: replace rema... |
1343 |
__func__, status); |
1da177e4c Linux-2.6.12-rc2 |
1344 1345 1346 1347 1348 1349 |
break; } rpc_exit(task, status); } /* |
ba60eb25f SUNRPC: Fix a liv... |
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 |
* 1c. Retry reserving an RPC call slot */ static void call_retry_reserve(struct rpc_task *task) { dprint_status(task); task->tk_status = 0; task->tk_action = call_reserveresult; xprt_retry_reserve(task); } /* |
55576244e SUNRPC: cleanup s... |
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 |
* 2. Bind and/or refresh the credentials */ static void call_refresh(struct rpc_task *task) { dprint_status(task); task->tk_action = call_refreshresult; task->tk_status = 0; task->tk_client->cl_stats->rpcauthrefresh++; rpcauth_refreshcred(task); } /* * 2a. Process the results of a credential refresh */ static void call_refreshresult(struct rpc_task *task) { int status = task->tk_status; dprint_status(task); task->tk_status = 0; |
5fc43978a SUNRPC: Fix an in... |
1387 |
task->tk_action = call_refresh; |
55576244e SUNRPC: cleanup s... |
1388 |
switch (status) { |
5fc43978a SUNRPC: Fix an in... |
1389 1390 1391 |
case 0: if (rpcauth_uptodatecred(task)) task->tk_action = call_allocate; |
55576244e SUNRPC: cleanup s... |
1392 1393 1394 |
return; case -ETIMEDOUT: rpc_delay(task, 3*HZ); |
eb96d5c97 SUNRPC handle EKE... |
1395 |
case -EKEYEXPIRED: |
5fc43978a SUNRPC: Fix an in... |
1396 1397 1398 1399 1400 1401 1402 1403 1404 |
case -EAGAIN: status = -EACCES; if (!task->tk_cred_retry) break; task->tk_cred_retry--; dprintk("RPC: %5u %s: retry refresh creds ", task->tk_pid, __func__); return; |
55576244e SUNRPC: cleanup s... |
1405 |
} |
5fc43978a SUNRPC: Fix an in... |
1406 1407 1408 1409 |
dprintk("RPC: %5u %s: refresh creds failed with error %d ", task->tk_pid, __func__, status); rpc_exit(task, status); |
55576244e SUNRPC: cleanup s... |
1410 1411 1412 1413 |
} /* * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc. |
021071483 SUNRPC: switchabl... |
1414 |
* (Note: buffer memory is freed in xprt_release). |
1da177e4c Linux-2.6.12-rc2 |
1415 1416 1417 1418 |
*/ static void call_allocate(struct rpc_task *task) { |
f2d47d02f Fix null derefere... |
1419 |
unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; |
021071483 SUNRPC: switchabl... |
1420 |
struct rpc_rqst *req = task->tk_rqstp; |
a4f0835c6 SUNRPC: Eliminate... |
1421 |
struct rpc_xprt *xprt = req->rq_xprt; |
2bea90d43 SUNRPC: RPC buffe... |
1422 |
struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
1da177e4c Linux-2.6.12-rc2 |
1423 |
|
46121cf7d SUNRPC: fix print... |
1424 |
dprint_status(task); |
2bea90d43 SUNRPC: RPC buffe... |
1425 |
task->tk_status = 0; |
f2d47d02f Fix null derefere... |
1426 |
task->tk_action = call_bind; |
2bea90d43 SUNRPC: RPC buffe... |
1427 |
|
021071483 SUNRPC: switchabl... |
1428 |
if (req->rq_buffer) |
1da177e4c Linux-2.6.12-rc2 |
1429 |
return; |
2bea90d43 SUNRPC: RPC buffe... |
1430 1431 1432 1433 1434 |
if (proc->p_proc != 0) { BUG_ON(proc->p_arglen == 0); if (proc->p_decode != NULL) BUG_ON(proc->p_replen == 0); } |
1da177e4c Linux-2.6.12-rc2 |
1435 |
|
2bea90d43 SUNRPC: RPC buffe... |
1436 1437 1438 1439 1440 1441 1442 1443 1444 |
/* * Calculate the size (in quads) of the RPC call * and reply headers, and convert both values * to byte sizes. */ req->rq_callsize = RPC_CALLHDRSIZE + (slack << 1) + proc->p_arglen; req->rq_callsize <<= 2; req->rq_rcvsize = RPC_REPHDRSIZE + slack + proc->p_replen; req->rq_rcvsize <<= 2; |
c5a4dd8b7 SUNRPC: Eliminate... |
1445 1446 |
req->rq_buffer = xprt->ops->buf_alloc(task, req->rq_callsize + req->rq_rcvsize); |
2bea90d43 SUNRPC: RPC buffe... |
1447 |
if (req->rq_buffer != NULL) |
1da177e4c Linux-2.6.12-rc2 |
1448 |
return; |
46121cf7d SUNRPC: fix print... |
1449 1450 1451 |
dprintk("RPC: %5u rpc_buffer allocation failed ", task->tk_pid); |
1da177e4c Linux-2.6.12-rc2 |
1452 |
|
5afa9133c SUNRPC: Ensure th... |
1453 |
if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) { |
b6e9c713f SUNRPC: Don't cal... |
1454 |
task->tk_action = call_allocate; |
1da177e4c Linux-2.6.12-rc2 |
1455 1456 1457 1458 1459 1460 |
rpc_delay(task, HZ>>4); return; } rpc_exit(task, -ERESTARTSYS); } |
940e3318c [PATCH] SUNRPC: d... |
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 |
static inline int rpc_task_need_encode(struct rpc_task *task) { return task->tk_rqstp->rq_snd_buf.len == 0; } static inline void rpc_task_force_reencode(struct rpc_task *task) { task->tk_rqstp->rq_snd_buf.len = 0; |
2574cc9f4 SUNRPC: Fix rpc_t... |
1471 |
task->tk_rqstp->rq_bytes_sent = 0; |
940e3318c [PATCH] SUNRPC: d... |
1472 |
} |
2bea90d43 SUNRPC: RPC buffe... |
1473 1474 1475 1476 1477 1478 1479 |
static inline void rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) { buf->head[0].iov_base = start; buf->head[0].iov_len = len; buf->tail[0].iov_len = 0; buf->page_len = 0; |
4f22ccc34 SUNRPC: mark bulk... |
1480 |
buf->flags = 0; |
2bea90d43 SUNRPC: RPC buffe... |
1481 1482 1483 |
buf->len = 0; buf->buflen = len; } |
1da177e4c Linux-2.6.12-rc2 |
1484 1485 1486 1487 |
/* * 3. Encode arguments of an RPC call */ static void |
b0e1c57ea SUNRPC: Rename "c... |
1488 |
rpc_xdr_encode(struct rpc_task *task) |
1da177e4c Linux-2.6.12-rc2 |
1489 |
{ |
1da177e4c Linux-2.6.12-rc2 |
1490 |
struct rpc_rqst *req = task->tk_rqstp; |
9f06c719f SUNRPC: New xdr_s... |
1491 |
kxdreproc_t encode; |
d8ed029d6 [SUNRPC]: trivial... |
1492 |
__be32 *p; |
1da177e4c Linux-2.6.12-rc2 |
1493 |
|
46121cf7d SUNRPC: fix print... |
1494 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1495 |
|
2bea90d43 SUNRPC: RPC buffe... |
1496 1497 1498 1499 1500 1501 |
rpc_xdr_buf_init(&req->rq_snd_buf, req->rq_buffer, req->rq_callsize); rpc_xdr_buf_init(&req->rq_rcv_buf, (char *)req->rq_buffer + req->rq_callsize, req->rq_rcvsize); |
1da177e4c Linux-2.6.12-rc2 |
1502 |
|
b0e1c57ea SUNRPC: Rename "c... |
1503 1504 1505 1506 |
p = rpc_encode_header(task); if (p == NULL) { printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO "); |
1da177e4c Linux-2.6.12-rc2 |
1507 1508 1509 |
rpc_exit(task, -EIO); return; } |
b0e1c57ea SUNRPC: Rename "c... |
1510 1511 |
encode = task->tk_msg.rpc_proc->p_encode; |
f3680312a SUNRPC: Retry wra... |
1512 1513 1514 1515 1516 |
if (encode == NULL) return; task->tk_status = rpcauth_wrap_req(task, encode, req, p, task->tk_msg.rpc_argp); |
1da177e4c Linux-2.6.12-rc2 |
1517 1518 1519 1520 1521 1522 1523 1524 |
} /* * 4. Get the server port number if not yet set */ static void call_bind(struct rpc_task *task) { |
ad2368d6f SUNRPC: Avoid RCU... |
1525 |
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; |
1da177e4c Linux-2.6.12-rc2 |
1526 |
|
46121cf7d SUNRPC: fix print... |
1527 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1528 |
|
da3518780 [PATCH] RPC: prop... |
1529 |
task->tk_action = call_connect; |
ec739ef03 SUNRPC: Create a ... |
1530 |
if (!xprt_bound(xprt)) { |
da3518780 [PATCH] RPC: prop... |
1531 |
task->tk_action = call_bind_status; |
ec739ef03 SUNRPC: Create a ... |
1532 |
task->tk_timeout = xprt->bind_timeout; |
bbf7c1dd2 SUNRPC: Introduce... |
1533 |
xprt->ops->rpcbind(task); |
1da177e4c Linux-2.6.12-rc2 |
1534 1535 1536 1537 |
} } /* |
da3518780 [PATCH] RPC: prop... |
1538 1539 1540 1541 1542 |
* 4a. Sort out bind result */ static void call_bind_status(struct rpc_task *task) { |
906462af4 SUNRPC: Split ano... |
1543 |
int status = -EIO; |
da3518780 [PATCH] RPC: prop... |
1544 1545 |
if (task->tk_status >= 0) { |
46121cf7d SUNRPC: fix print... |
1546 |
dprint_status(task); |
da3518780 [PATCH] RPC: prop... |
1547 1548 1549 1550 |
task->tk_status = 0; task->tk_action = call_connect; return; } |
5753cba17 SUNRPC: Adding st... |
1551 |
trace_rpc_bind_status(task); |
da3518780 [PATCH] RPC: prop... |
1552 |
switch (task->tk_status) { |
381ba74af SUNRPC: Ensure ou... |
1553 1554 1555 1556 |
case -ENOMEM: dprintk("RPC: %5u rpcbind out of memory ", task->tk_pid); rpc_delay(task, HZ >> 2); |
2429cbf6a SUNRPC: Add a new... |
1557 |
goto retry_timeout; |
da3518780 [PATCH] RPC: prop... |
1558 |
case -EACCES: |
46121cf7d SUNRPC: fix print... |
1559 1560 1561 |
dprintk("RPC: %5u remote rpcbind: RPC program/version " "unavailable ", task->tk_pid); |
b79dc8ced SUNRPC: RPC bind ... |
1562 1563 1564 1565 1566 |
/* fail immediately if this is an RPC ping */ if (task->tk_msg.rpc_proc->p_proc == 0) { status = -EOPNOTSUPP; break; } |
0b760113a NLM: Don't hang f... |
1567 1568 1569 |
if (task->tk_rebind_retry == 0) break; task->tk_rebind_retry--; |
ea635a517 SUNRPC: Retry rpc... |
1570 |
rpc_delay(task, 3*HZ); |
da45828e2 SUNRPC: Clean up ... |
1571 |
goto retry_timeout; |
da3518780 [PATCH] RPC: prop... |
1572 |
case -ETIMEDOUT: |
46121cf7d SUNRPC: fix print... |
1573 1574 |
dprintk("RPC: %5u rpcbind request timed out ", |
da3518780 [PATCH] RPC: prop... |
1575 |
task->tk_pid); |
da45828e2 SUNRPC: Clean up ... |
1576 |
goto retry_timeout; |
da3518780 [PATCH] RPC: prop... |
1577 |
case -EPFNOSUPPORT: |
906462af4 SUNRPC: Split ano... |
1578 |
/* server doesn't support any rpcbind version we know of */ |
012da158f SUNRPC: Use soft ... |
1579 1580 |
dprintk("RPC: %5u unrecognized remote rpcbind service ", |
da3518780 [PATCH] RPC: prop... |
1581 1582 1583 |
task->tk_pid); break; case -EPROTONOSUPPORT: |
00a6e7bbf SUNRPC: RPC clien... |
1584 1585 |
dprintk("RPC: %5u remote rpcbind version unavailable, retrying ", |
da3518780 [PATCH] RPC: prop... |
1586 |
task->tk_pid); |
00a6e7bbf SUNRPC: RPC clien... |
1587 1588 1589 |
task->tk_status = 0; task->tk_action = call_bind; return; |
012da158f SUNRPC: Use soft ... |
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 |
case -ECONNREFUSED: /* connection problems */ case -ECONNRESET: case -ENOTCONN: case -EHOSTDOWN: case -EHOSTUNREACH: case -ENETUNREACH: case -EPIPE: dprintk("RPC: %5u remote rpcbind unreachable: %d ", task->tk_pid, task->tk_status); if (!RPC_IS_SOFTCONN(task)) { rpc_delay(task, 5*HZ); goto retry_timeout; } status = task->tk_status; break; |
da3518780 [PATCH] RPC: prop... |
1606 |
default: |
46121cf7d SUNRPC: fix print... |
1607 1608 |
dprintk("RPC: %5u unrecognized rpcbind error (%d) ", |
da3518780 [PATCH] RPC: prop... |
1609 |
task->tk_pid, -task->tk_status); |
da3518780 [PATCH] RPC: prop... |
1610 1611 1612 1613 |
} rpc_exit(task, status); return; |
da45828e2 SUNRPC: Clean up ... |
1614 1615 |
retry_timeout: task->tk_action = call_timeout; |
da3518780 [PATCH] RPC: prop... |
1616 1617 1618 1619 |
} /* * 4b. Connect to the RPC server |
1da177e4c Linux-2.6.12-rc2 |
1620 1621 1622 1623 |
*/ static void call_connect(struct rpc_task *task) { |
ad2368d6f SUNRPC: Avoid RCU... |
1624 |
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; |
1da177e4c Linux-2.6.12-rc2 |
1625 |
|
46121cf7d SUNRPC: fix print... |
1626 1627 |
dprintk("RPC: %5u call_connect xprt %p %s connected ", |
da3518780 [PATCH] RPC: prop... |
1628 1629 |
task->tk_pid, xprt, (xprt_connected(xprt) ? "is" : "is not")); |
1da177e4c Linux-2.6.12-rc2 |
1630 |
|
da3518780 [PATCH] RPC: prop... |
1631 1632 1633 1634 1635 |
task->tk_action = call_transmit; if (!xprt_connected(xprt)) { task->tk_action = call_connect_status; if (task->tk_status < 0) return; |
4662ffcbe SUNRPC: If the rp... |
1636 1637 1638 1639 |
if (task->tk_flags & RPC_TASK_NOCONNECT) { rpc_exit(task, -ENOTCONN); return; } |
da3518780 [PATCH] RPC: prop... |
1640 |
xprt_connect(task); |
1da177e4c Linux-2.6.12-rc2 |
1641 |
} |
1da177e4c Linux-2.6.12-rc2 |
1642 1643 1644 |
} /* |
da3518780 [PATCH] RPC: prop... |
1645 |
* 4c. Sort out connect result |
1da177e4c Linux-2.6.12-rc2 |
1646 1647 1648 1649 1650 1651 |
*/ static void call_connect_status(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; int status = task->tk_status; |
46121cf7d SUNRPC: fix print... |
1652 |
dprint_status(task); |
da3518780 [PATCH] RPC: prop... |
1653 |
|
5753cba17 SUNRPC: Adding st... |
1654 |
trace_rpc_connect_status(task, status); |
1da177e4c Linux-2.6.12-rc2 |
1655 |
switch (status) { |
da45828e2 SUNRPC: Clean up ... |
1656 1657 1658 |
/* if soft mounted, test if we've timed out */ case -ETIMEDOUT: task->tk_action = call_timeout; |
3ed5e2a2c SUNRPC: Report ne... |
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 |
return; case -ECONNREFUSED: case -ECONNRESET: case -ENETUNREACH: if (RPC_IS_SOFTCONN(task)) break; /* retry with existing socket, after a delay */ case 0: case -EAGAIN: task->tk_status = 0; clnt->cl_stats->netreconn++; task->tk_action = call_transmit; return; |
1da177e4c Linux-2.6.12-rc2 |
1672 |
} |
3ed5e2a2c SUNRPC: Report ne... |
1673 |
rpc_exit(task, status); |
1da177e4c Linux-2.6.12-rc2 |
1674 1675 1676 1677 1678 1679 1680 1681 |
} /* * 5. Transmit the RPC request, and wait for reply */ static void call_transmit(struct rpc_task *task) { |
46121cf7d SUNRPC: fix print... |
1682 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1683 1684 1685 1686 1687 1688 1689 |
task->tk_action = call_status; if (task->tk_status < 0) return; task->tk_status = xprt_prepare_transmit(task); if (task->tk_status != 0) return; |
e0ab53dea RPC: Ensure that ... |
1690 |
task->tk_action = call_transmit_status; |
1da177e4c Linux-2.6.12-rc2 |
1691 |
/* Encode here so that rpcsec_gss can use correct sequence number. */ |
940e3318c [PATCH] SUNRPC: d... |
1692 |
if (rpc_task_need_encode(task)) { |
b0e1c57ea SUNRPC: Rename "c... |
1693 |
rpc_xdr_encode(task); |
5e5ce5be6 RPC: allow call_e... |
1694 |
/* Did the encode result in an error condition? */ |
8b39f2b41 SUNRPC: Ensure we... |
1695 1696 1697 1698 1699 1700 |
if (task->tk_status != 0) { /* Was the error nonfatal? */ if (task->tk_status == -EAGAIN) rpc_delay(task, HZ >> 4); else rpc_exit(task, task->tk_status); |
e0ab53dea RPC: Ensure that ... |
1701 |
return; |
8b39f2b41 SUNRPC: Ensure we... |
1702 |
} |
5e5ce5be6 RPC: allow call_e... |
1703 |
} |
1da177e4c Linux-2.6.12-rc2 |
1704 1705 1706 |
xprt_transmit(task); if (task->tk_status < 0) return; |
e0ab53dea RPC: Ensure that ... |
1707 1708 1709 1710 1711 |
/* * On success, ensure that we call xprt_end_transmit() before sleeping * in order to allow access to the socket to other RPC requests. */ call_transmit_status(task); |
55ae1aabf nfs41: Add backch... |
1712 |
if (rpc_reply_expected(task)) |
e0ab53dea RPC: Ensure that ... |
1713 1714 |
return; task->tk_action = rpc_exit_task; |
a4f0835c6 SUNRPC: Eliminate... |
1715 |
rpc_wake_up_queued_task(&task->tk_rqstp->rq_xprt->pending, task); |
e0ab53dea RPC: Ensure that ... |
1716 1717 1718 1719 1720 1721 1722 1723 1724 |
} /* * 5a. Handle cleanup after a transmission */ static void call_transmit_status(struct rpc_task *task) { task->tk_action = call_status; |
206a134b4 SUNRPC: Check exp... |
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 |
/* * Common case: success. Force the compiler to put this * test first. */ if (task->tk_status == 0) { xprt_end_transmit(task); rpc_task_force_reencode(task); return; } |
15f081ca8 SUNRPC: Avoid an ... |
1735 1736 1737 1738 |
switch (task->tk_status) { case -EAGAIN: break; default: |
206a134b4 SUNRPC: Check exp... |
1739 |
dprint_status(task); |
15f081ca8 SUNRPC: Avoid an ... |
1740 |
xprt_end_transmit(task); |
09a21c410 SUNRPC: Allow RPC... |
1741 1742 |
rpc_task_force_reencode(task); break; |
15f081ca8 SUNRPC: Avoid an ... |
1743 1744 1745 1746 1747 1748 1749 |
/* * Special cases: if we've been waiting on the * socket's write_space() callback, or if the * socket just returned a connection error, * then hold onto the transport lock. */ case -ECONNREFUSED: |
15f081ca8 SUNRPC: Avoid an ... |
1750 1751 1752 |
case -EHOSTDOWN: case -EHOSTUNREACH: case -ENETUNREACH: |
09a21c410 SUNRPC: Allow RPC... |
1753 1754 1755 1756 1757 1758 1759 |
if (RPC_IS_SOFTCONN(task)) { xprt_end_transmit(task); rpc_exit(task, task->tk_status); break; } case -ECONNRESET: case -ENOTCONN: |
c8485e4d6 SUNRPC: Handle EC... |
1760 |
case -EPIPE: |
15f081ca8 SUNRPC: Avoid an ... |
1761 1762 |
rpc_task_force_reencode(task); } |
1da177e4c Linux-2.6.12-rc2 |
1763 |
} |
9e00abc3c SUNRPC: sunrpc sh... |
1764 |
#if defined(CONFIG_SUNRPC_BACKCHANNEL) |
55ae1aabf nfs41: Add backch... |
1765 1766 1767 1768 1769 1770 1771 1772 |
/* * 5b. Send the backchannel RPC reply. On error, drop the reply. In * addition, disconnect on connectivity errors. */ static void call_bc_transmit(struct rpc_task *task) { struct rpc_rqst *req = task->tk_rqstp; |
55ae1aabf nfs41: Add backch... |
1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 |
task->tk_status = xprt_prepare_transmit(task); if (task->tk_status == -EAGAIN) { /* * Could not reserve the transport. Try again after the * transport is released. */ task->tk_status = 0; task->tk_action = call_bc_transmit; return; } task->tk_action = rpc_exit_task; if (task->tk_status < 0) { printk(KERN_NOTICE "RPC: Could not send backchannel reply " "error: %d ", task->tk_status); return; } xprt_transmit(task); xprt_end_transmit(task); dprint_status(task); switch (task->tk_status) { case 0: /* Success */ break; case -EHOSTDOWN: case -EHOSTUNREACH: case -ENETUNREACH: case -ETIMEDOUT: /* * Problem reaching the server. Disconnect and let the * forechannel reestablish the connection. The server will * have to retransmit the backchannel request and we'll * reprocess it. Since these ops are idempotent, there's no * need to cache our reply at this time. */ printk(KERN_NOTICE "RPC: Could not send backchannel reply " "error: %d ", task->tk_status); |
a4f0835c6 SUNRPC: Eliminate... |
1813 |
xprt_conditional_disconnect(req->rq_xprt, |
55ae1aabf nfs41: Add backch... |
1814 1815 1816 1817 1818 1819 1820 |
req->rq_connect_cookie); break; default: /* * We were unable to reply and will have to drop the * request. The server should reconnect and retransmit. */ |
1facf4c4a SUNRPC: remove BU... |
1821 |
WARN_ON_ONCE(task->tk_status == -EAGAIN); |
55ae1aabf nfs41: Add backch... |
1822 1823 1824 1825 1826 1827 1828 |
printk(KERN_NOTICE "RPC: Could not send backchannel reply " "error: %d ", task->tk_status); break; } rpc_wake_up_queued_task(&req->rq_xprt->pending, task); } |
9e00abc3c SUNRPC: sunrpc sh... |
1829 |
#endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
55ae1aabf nfs41: Add backch... |
1830 |
|
1da177e4c Linux-2.6.12-rc2 |
1831 1832 1833 1834 1835 1836 1837 1838 1839 |
/* * 6. Sort out the RPC call status */ static void call_status(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; struct rpc_rqst *req = task->tk_rqstp; int status; |
dd2b63d04 nfs41: Rename rq_... |
1840 1841 |
if (req->rq_reply_bytes_recvd > 0 && !req->rq_bytes_sent) task->tk_status = req->rq_reply_bytes_recvd; |
1da177e4c Linux-2.6.12-rc2 |
1842 |
|
46121cf7d SUNRPC: fix print... |
1843 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1844 1845 1846 1847 1848 1849 |
status = task->tk_status; if (status >= 0) { task->tk_action = call_decode; return; } |
5753cba17 SUNRPC: Adding st... |
1850 |
trace_rpc_call_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1851 1852 |
task->tk_status = 0; switch(status) { |
76303992b SUNRPC: Handle EN... |
1853 1854 1855 1856 1857 1858 1859 1860 |
case -EHOSTDOWN: case -EHOSTUNREACH: case -ENETUNREACH: /* * Delay any retries for 3 seconds, then handle as if it * were a timeout. */ rpc_delay(task, 3*HZ); |
1da177e4c Linux-2.6.12-rc2 |
1861 1862 |
case -ETIMEDOUT: task->tk_action = call_timeout; |
241c39b9a RPC: Fix the TCP ... |
1863 |
if (task->tk_client->cl_discrtry) |
a4f0835c6 SUNRPC: Eliminate... |
1864 |
xprt_conditional_disconnect(req->rq_xprt, |
7c1d71cf5 SUNRPC: Don't dis... |
1865 |
req->rq_connect_cookie); |
1da177e4c Linux-2.6.12-rc2 |
1866 |
break; |
c8485e4d6 SUNRPC: Handle EC... |
1867 |
case -ECONNRESET: |
1da177e4c Linux-2.6.12-rc2 |
1868 |
case -ECONNREFUSED: |
35f5a422c SUNRPC: new inter... |
1869 |
rpc_force_rebind(clnt); |
c8485e4d6 SUNRPC: Handle EC... |
1870 1871 1872 |
rpc_delay(task, 3*HZ); case -EPIPE: case -ENOTCONN: |
1da177e4c Linux-2.6.12-rc2 |
1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 |
task->tk_action = call_bind; break; case -EAGAIN: task->tk_action = call_transmit; break; case -EIO: /* shutdown or soft timeout */ rpc_exit(task, status); break; default: |
b6b6152c4 rpc: bring back c... |
1883 1884 1885 |
if (clnt->cl_chatty) printk("%s: RPC call returned error %d ", |
1da177e4c Linux-2.6.12-rc2 |
1886 1887 |
clnt->cl_protname, -status); rpc_exit(task, status); |
1da177e4c Linux-2.6.12-rc2 |
1888 1889 1890 1891 |
} } /* |
e0ab53dea RPC: Ensure that ... |
1892 |
* 6a. Handle RPC timeout |
1da177e4c Linux-2.6.12-rc2 |
1893 1894 1895 1896 1897 1898 1899 1900 1901 |
* We do not release the request slot, so we keep using the * same XID for all retransmits. */ static void call_timeout(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; if (xprt_adjust_timeout(task->tk_rqstp) == 0) { |
46121cf7d SUNRPC: fix print... |
1902 1903 |
dprintk("RPC: %5u call_timeout (minor) ", task->tk_pid); |
1da177e4c Linux-2.6.12-rc2 |
1904 1905 |
goto retry; } |
46121cf7d SUNRPC: fix print... |
1906 1907 |
dprintk("RPC: %5u call_timeout (major) ", task->tk_pid); |
ef759a2e5 SUNRPC: introduce... |
1908 |
task->tk_timeouts++; |
3a28becc3 SUNRPC: soft conn... |
1909 1910 1911 1912 |
if (RPC_IS_SOFTCONN(task)) { rpc_exit(task, -ETIMEDOUT); return; } |
1da177e4c Linux-2.6.12-rc2 |
1913 |
if (RPC_IS_SOFT(task)) { |
cac5d07e3 sunrpc: clnt: Add... |
1914 |
if (clnt->cl_chatty) { |
4e0038b6b SUNRPC: Move clnt... |
1915 |
rcu_read_lock(); |
b6b6152c4 rpc: bring back c... |
1916 1917 |
printk(KERN_NOTICE "%s: server %s not responding, timed out ", |
4e0038b6b SUNRPC: Move clnt... |
1918 1919 1920 |
clnt->cl_protname, rcu_dereference(clnt->cl_xprt)->servername); rcu_read_unlock(); |
cac5d07e3 sunrpc: clnt: Add... |
1921 |
} |
7494d00c7 SUNRPC: Allow RPC... |
1922 1923 1924 1925 |
if (task->tk_flags & RPC_TASK_TIMEOUT) rpc_exit(task, -ETIMEDOUT); else rpc_exit(task, -EIO); |
1da177e4c Linux-2.6.12-rc2 |
1926 1927 |
return; } |
f518e35ae SUNRPC: get rid o... |
1928 |
if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { |
1da177e4c Linux-2.6.12-rc2 |
1929 |
task->tk_flags |= RPC_CALL_MAJORSEEN; |
4e0038b6b SUNRPC: Move clnt... |
1930 1931 |
if (clnt->cl_chatty) { rcu_read_lock(); |
b6b6152c4 rpc: bring back c... |
1932 1933 |
printk(KERN_NOTICE "%s: server %s not responding, still trying ", |
4e0038b6b SUNRPC: Move clnt... |
1934 1935 1936 1937 |
clnt->cl_protname, rcu_dereference(clnt->cl_xprt)->servername); rcu_read_unlock(); } |
1da177e4c Linux-2.6.12-rc2 |
1938 |
} |
35f5a422c SUNRPC: new inter... |
1939 |
rpc_force_rebind(clnt); |
b48633bd0 SUNRPC: Invalidat... |
1940 1941 1942 1943 1944 |
/* * Did our request time out due to an RPCSEC_GSS out-of-sequence * event? RFC2203 requires the server to drop all such requests. */ rpcauth_invalcred(task); |
1da177e4c Linux-2.6.12-rc2 |
1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 |
retry: clnt->cl_stats->rpcretrans++; task->tk_action = call_bind; task->tk_status = 0; } /* * 7. Decode the RPC reply */ static void call_decode(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; struct rpc_rqst *req = task->tk_rqstp; |
bf2695516 SUNRPC: New xdr_s... |
1960 |
kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; |
d8ed029d6 [SUNRPC]: trivial... |
1961 |
__be32 *p; |
1da177e4c Linux-2.6.12-rc2 |
1962 |
|
726fd6ad5 sunrpc: use dprin... |
1963 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1964 |
|
f518e35ae SUNRPC: get rid o... |
1965 |
if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
4e0038b6b SUNRPC: Move clnt... |
1966 1967 |
if (clnt->cl_chatty) { rcu_read_lock(); |
b6b6152c4 rpc: bring back c... |
1968 1969 |
printk(KERN_NOTICE "%s: server %s OK ", |
4e0038b6b SUNRPC: Move clnt... |
1970 1971 1972 1973 |
clnt->cl_protname, rcu_dereference(clnt->cl_xprt)->servername); rcu_read_unlock(); } |
1da177e4c Linux-2.6.12-rc2 |
1974 1975 |
task->tk_flags &= ~RPC_CALL_MAJORSEEN; } |
43ac3f296 SUNRPC: Fix memor... |
1976 1977 |
/* * Ensure that we see all writes made by xprt_complete_rqst() |
dd2b63d04 nfs41: Rename rq_... |
1978 |
* before it changed req->rq_reply_bytes_recvd. |
43ac3f296 SUNRPC: Fix memor... |
1979 1980 |
*/ smp_rmb(); |
1da177e4c Linux-2.6.12-rc2 |
1981 1982 1983 1984 1985 |
req->rq_rcv_buf.len = req->rq_private_buf.len; /* Check that the softirq receive buffer is valid */ WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf, sizeof(req->rq_rcv_buf)) != 0); |
1e799b673 SUNRPC: Fix read ... |
1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 |
if (req->rq_rcv_buf.len < 12) { if (!RPC_IS_SOFT(task)) { task->tk_action = call_bind; clnt->cl_stats->rpcretrans++; goto out_retry; } dprintk("RPC: %s: too small RPC reply size (%d bytes) ", clnt->cl_protname, task->tk_status); task->tk_action = call_timeout; goto out_retry; } |
b0e1c57ea SUNRPC: Rename "c... |
1998 |
p = rpc_verify_header(task); |
abbcf28f2 SUNRPC: Yet more ... |
1999 2000 2001 2002 |
if (IS_ERR(p)) { if (p == ERR_PTR(-EAGAIN)) goto out_retry; return; |
1da177e4c Linux-2.6.12-rc2 |
2003 |
} |
abbcf28f2 SUNRPC: Yet more ... |
2004 |
task->tk_action = rpc_exit_task; |
1da177e4c Linux-2.6.12-rc2 |
2005 |
|
6d5fcb5a5 SUNRPC: Remove BK... |
2006 |
if (decode) { |
1da177e4c Linux-2.6.12-rc2 |
2007 2008 |
task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, task->tk_msg.rpc_resp); |
6d5fcb5a5 SUNRPC: Remove BK... |
2009 |
} |
46121cf7d SUNRPC: fix print... |
2010 2011 2012 |
dprintk("RPC: %5u call_decode result %d ", task->tk_pid, task->tk_status); |
1da177e4c Linux-2.6.12-rc2 |
2013 2014 |
return; out_retry: |
1da177e4c Linux-2.6.12-rc2 |
2015 |
task->tk_status = 0; |
b0e1c57ea SUNRPC: Rename "c... |
2016 |
/* Note: rpc_verify_header() may have freed the RPC slot */ |
24b74bf0c SUNRPC: Fix a bug... |
2017 |
if (task->tk_rqstp == req) { |
dd2b63d04 nfs41: Rename rq_... |
2018 |
req->rq_reply_bytes_recvd = req->rq_rcv_buf.len = 0; |
24b74bf0c SUNRPC: Fix a bug... |
2019 |
if (task->tk_client->cl_discrtry) |
a4f0835c6 SUNRPC: Eliminate... |
2020 |
xprt_conditional_disconnect(req->rq_xprt, |
7c1d71cf5 SUNRPC: Don't dis... |
2021 |
req->rq_connect_cookie); |
24b74bf0c SUNRPC: Fix a bug... |
2022 |
} |
1da177e4c Linux-2.6.12-rc2 |
2023 |
} |
d8ed029d6 [SUNRPC]: trivial... |
2024 |
static __be32 * |
b0e1c57ea SUNRPC: Rename "c... |
2025 |
rpc_encode_header(struct rpc_task *task) |
1da177e4c Linux-2.6.12-rc2 |
2026 2027 |
{ struct rpc_clnt *clnt = task->tk_client; |
1da177e4c Linux-2.6.12-rc2 |
2028 |
struct rpc_rqst *req = task->tk_rqstp; |
d8ed029d6 [SUNRPC]: trivial... |
2029 |
__be32 *p = req->rq_svec[0].iov_base; |
1da177e4c Linux-2.6.12-rc2 |
2030 2031 |
/* FIXME: check buffer size? */ |
808012fbb [PATCH] RPC: skip... |
2032 |
|
a4f0835c6 SUNRPC: Eliminate... |
2033 |
p = xprt_skip_transport_header(req->rq_xprt, p); |
1da177e4c Linux-2.6.12-rc2 |
2034 2035 2036 2037 2038 2039 |
*p++ = req->rq_xid; /* XID */ *p++ = htonl(RPC_CALL); /* CALL */ *p++ = htonl(RPC_VERSION); /* RPC version */ *p++ = htonl(clnt->cl_prog); /* program number */ *p++ = htonl(clnt->cl_vers); /* program version */ *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */ |
334ccfd54 [PATCH] RPC: Ensu... |
2040 2041 2042 |
p = rpcauth_marshcred(task, p); req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p); return p; |
1da177e4c Linux-2.6.12-rc2 |
2043 |
} |
d8ed029d6 [SUNRPC]: trivial... |
2044 |
static __be32 * |
b0e1c57ea SUNRPC: Rename "c... |
2045 |
rpc_verify_header(struct rpc_task *task) |
1da177e4c Linux-2.6.12-rc2 |
2046 |
{ |
4e0038b6b SUNRPC: Move clnt... |
2047 |
struct rpc_clnt *clnt = task->tk_client; |
1da177e4c Linux-2.6.12-rc2 |
2048 2049 |
struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; int len = task->tk_rqstp->rq_rcv_buf.len >> 2; |
d8ed029d6 [SUNRPC]: trivial... |
2050 2051 |
__be32 *p = iov->iov_base; u32 n; |
1da177e4c Linux-2.6.12-rc2 |
2052 |
int error = -EACCES; |
e8896495b NFS: Check length... |
2053 2054 2055 2056 2057 2058 |
if ((task->tk_rqstp->rq_rcv_buf.len & 3) != 0) { /* RFC-1014 says that the representation of XDR data must be a * multiple of four bytes * - if it isn't pointer subtraction in the NFS client may give * undefined results */ |
8a702bbb7 SUNRPC: Suppress ... |
2059 |
dprintk("RPC: %5u %s: XDR representation not a multiple of" |
0dc47877a net: replace rema... |
2060 2061 |
" 4 bytes: 0x%x ", task->tk_pid, __func__, |
8a702bbb7 SUNRPC: Suppress ... |
2062 |
task->tk_rqstp->rq_rcv_buf.len); |
e8896495b NFS: Check length... |
2063 2064 |
goto out_eio; } |
1da177e4c Linux-2.6.12-rc2 |
2065 2066 |
if ((len -= 3) < 0) goto out_overflow; |
1da177e4c Linux-2.6.12-rc2 |
2067 |
|
f4a2e418b nfs41: Process th... |
2068 |
p += 1; /* skip XID */ |
1da177e4c Linux-2.6.12-rc2 |
2069 |
if ((n = ntohl(*p++)) != RPC_REPLY) { |
8a702bbb7 SUNRPC: Suppress ... |
2070 2071 |
dprintk("RPC: %5u %s: not an RPC reply: %x ", |
f4a2e418b nfs41: Process th... |
2072 |
task->tk_pid, __func__, n); |
abbcf28f2 SUNRPC: Yet more ... |
2073 |
goto out_garbage; |
1da177e4c Linux-2.6.12-rc2 |
2074 |
} |
f4a2e418b nfs41: Process th... |
2075 |
|
1da177e4c Linux-2.6.12-rc2 |
2076 2077 2078 2079 |
if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { if (--len < 0) goto out_overflow; switch ((n = ntohl(*p++))) { |
89f0e4fea sunrpc: Reduce sw... |
2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 |
case RPC_AUTH_ERROR: break; case RPC_MISMATCH: dprintk("RPC: %5u %s: RPC call version mismatch! ", task->tk_pid, __func__); error = -EPROTONOSUPPORT; goto out_err; default: dprintk("RPC: %5u %s: RPC call rejected, " "unknown error: %x ", task->tk_pid, __func__, n); goto out_eio; |
1da177e4c Linux-2.6.12-rc2 |
2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 |
} if (--len < 0) goto out_overflow; switch ((n = ntohl(*p++))) { case RPC_AUTH_REJECTEDCRED: case RPC_AUTH_REJECTEDVERF: case RPCSEC_GSS_CREDPROBLEM: case RPCSEC_GSS_CTXPROBLEM: if (!task->tk_cred_retry) break; task->tk_cred_retry--; |
46121cf7d SUNRPC: fix print... |
2105 2106 |
dprintk("RPC: %5u %s: retry stale creds ", |
0dc47877a net: replace rema... |
2107 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
2108 |
rpcauth_invalcred(task); |
220bcc2af SUNRPC: Don't cal... |
2109 2110 |
/* Ensure we obtain a new XID! */ xprt_release(task); |
118df3d17 SUNRPC: After cal... |
2111 |
task->tk_action = call_reserve; |
abbcf28f2 SUNRPC: Yet more ... |
2112 |
goto out_retry; |
1da177e4c Linux-2.6.12-rc2 |
2113 2114 2115 2116 2117 2118 |
case RPC_AUTH_BADCRED: case RPC_AUTH_BADVERF: /* possibly garbled cred/verf? */ if (!task->tk_garb_retry) break; task->tk_garb_retry--; |
46121cf7d SUNRPC: fix print... |
2119 2120 |
dprintk("RPC: %5u %s: retry garbled creds ", |
0dc47877a net: replace rema... |
2121 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
2122 |
task->tk_action = call_bind; |
abbcf28f2 SUNRPC: Yet more ... |
2123 |
goto out_retry; |
1da177e4c Linux-2.6.12-rc2 |
2124 |
case RPC_AUTH_TOOWEAK: |
4e0038b6b SUNRPC: Move clnt... |
2125 |
rcu_read_lock(); |
b0e1c57ea SUNRPC: Rename "c... |
2126 |
printk(KERN_NOTICE "RPC: server %s requires stronger " |
4e0038b6b SUNRPC: Move clnt... |
2127 2128 2129 2130 |
"authentication. ", rcu_dereference(clnt->cl_xprt)->servername); rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
2131 2132 |
break; default: |
8a702bbb7 SUNRPC: Suppress ... |
2133 2134 |
dprintk("RPC: %5u %s: unknown auth error: %x ", |
0dc47877a net: replace rema... |
2135 |
task->tk_pid, __func__, n); |
1da177e4c Linux-2.6.12-rc2 |
2136 2137 |
error = -EIO; } |
46121cf7d SUNRPC: fix print... |
2138 2139 |
dprintk("RPC: %5u %s: call rejected %d ", |
0dc47877a net: replace rema... |
2140 |
task->tk_pid, __func__, n); |
1da177e4c Linux-2.6.12-rc2 |
2141 2142 2143 |
goto out_err; } if (!(p = rpcauth_checkverf(task, p))) { |
8a702bbb7 SUNRPC: Suppress ... |
2144 2145 |
dprintk("RPC: %5u %s: auth check failed ", |
0dc47877a net: replace rema... |
2146 |
task->tk_pid, __func__); |
abbcf28f2 SUNRPC: Yet more ... |
2147 |
goto out_garbage; /* bad verifier, retry */ |
1da177e4c Linux-2.6.12-rc2 |
2148 |
} |
d8ed029d6 [SUNRPC]: trivial... |
2149 |
len = p - (__be32 *)iov->iov_base - 1; |
1da177e4c Linux-2.6.12-rc2 |
2150 2151 2152 2153 2154 2155 |
if (len < 0) goto out_overflow; switch ((n = ntohl(*p++))) { case RPC_SUCCESS: return p; case RPC_PROG_UNAVAIL: |
4e0038b6b SUNRPC: Move clnt... |
2156 2157 2158 2159 2160 |
dprintk_rcu("RPC: %5u %s: program %u is unsupported " "by server %s ", task->tk_pid, __func__, (unsigned int)clnt->cl_prog, rcu_dereference(clnt->cl_xprt)->servername); |
cdf477068 [PATCH] RPC: Retu... |
2161 2162 |
error = -EPFNOSUPPORT; goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
2163 |
case RPC_PROG_MISMATCH: |
4e0038b6b SUNRPC: Move clnt... |
2164 2165 2166 2167 2168 2169 |
dprintk_rcu("RPC: %5u %s: program %u, version %u unsupported " "by server %s ", task->tk_pid, __func__, (unsigned int)clnt->cl_prog, (unsigned int)clnt->cl_vers, rcu_dereference(clnt->cl_xprt)->servername); |
cdf477068 [PATCH] RPC: Retu... |
2170 2171 |
error = -EPROTONOSUPPORT; goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
2172 |
case RPC_PROC_UNAVAIL: |
4e0038b6b SUNRPC: Move clnt... |
2173 |
dprintk_rcu("RPC: %5u %s: proc %s unsupported by program %u, " |
46121cf7d SUNRPC: fix print... |
2174 2175 |
"version %u on server %s ", |
0dc47877a net: replace rema... |
2176 |
task->tk_pid, __func__, |
3748f1e44 SUNRPC: Add a fun... |
2177 |
rpc_proc_name(task), |
4e0038b6b SUNRPC: Move clnt... |
2178 2179 |
clnt->cl_prog, clnt->cl_vers, rcu_dereference(clnt->cl_xprt)->servername); |
cdf477068 [PATCH] RPC: Retu... |
2180 2181 |
error = -EOPNOTSUPP; goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
2182 |
case RPC_GARBAGE_ARGS: |
46121cf7d SUNRPC: fix print... |
2183 2184 |
dprintk("RPC: %5u %s: server saw garbage ", |
0dc47877a net: replace rema... |
2185 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
2186 2187 |
break; /* retry */ default: |
8a702bbb7 SUNRPC: Suppress ... |
2188 2189 |
dprintk("RPC: %5u %s: server accept status: %x ", |
0dc47877a net: replace rema... |
2190 |
task->tk_pid, __func__, n); |
1da177e4c Linux-2.6.12-rc2 |
2191 2192 |
/* Also retry */ } |
abbcf28f2 SUNRPC: Yet more ... |
2193 |
out_garbage: |
4e0038b6b SUNRPC: Move clnt... |
2194 |
clnt->cl_stats->rpcgarbage++; |
1da177e4c Linux-2.6.12-rc2 |
2195 2196 |
if (task->tk_garb_retry) { task->tk_garb_retry--; |
46121cf7d SUNRPC: fix print... |
2197 2198 |
dprintk("RPC: %5u %s: retrying ", |
0dc47877a net: replace rema... |
2199 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
2200 |
task->tk_action = call_bind; |
abbcf28f2 SUNRPC: Yet more ... |
2201 2202 |
out_retry: return ERR_PTR(-EAGAIN); |
1da177e4c Linux-2.6.12-rc2 |
2203 |
} |
1da177e4c Linux-2.6.12-rc2 |
2204 2205 2206 2207 |
out_eio: error = -EIO; out_err: rpc_exit(task, error); |
8a702bbb7 SUNRPC: Suppress ... |
2208 2209 |
dprintk("RPC: %5u %s: call failed with error %d ", task->tk_pid, |
0dc47877a net: replace rema... |
2210 |
__func__, error); |
abbcf28f2 SUNRPC: Yet more ... |
2211 |
return ERR_PTR(error); |
1da177e4c Linux-2.6.12-rc2 |
2212 |
out_overflow: |
8a702bbb7 SUNRPC: Suppress ... |
2213 2214 |
dprintk("RPC: %5u %s: server reply was truncated. ", task->tk_pid, |
0dc47877a net: replace rema... |
2215 |
__func__); |
abbcf28f2 SUNRPC: Yet more ... |
2216 |
goto out_garbage; |
1da177e4c Linux-2.6.12-rc2 |
2217 |
} |
5ee0ed7d3 [PATCH] RPC: Make... |
2218 |
|
9f06c719f SUNRPC: New xdr_s... |
2219 |
static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
5ee0ed7d3 [PATCH] RPC: Make... |
2220 |
{ |
5ee0ed7d3 [PATCH] RPC: Make... |
2221 |
} |
bf2695516 SUNRPC: New xdr_s... |
2222 |
static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
5ee0ed7d3 [PATCH] RPC: Make... |
2223 2224 2225 2226 2227 2228 2229 2230 |
{ return 0; } static struct rpc_procinfo rpcproc_null = { .p_encode = rpcproc_encode_null, .p_decode = rpcproc_decode_null, }; |
caabea8a5 SUNRPC: Use soft ... |
2231 |
static int rpc_ping(struct rpc_clnt *clnt) |
5ee0ed7d3 [PATCH] RPC: Make... |
2232 2233 2234 2235 2236 2237 |
{ struct rpc_message msg = { .rpc_proc = &rpcproc_null, }; int err; msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0); |
caabea8a5 SUNRPC: Use soft ... |
2238 |
err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN); |
5ee0ed7d3 [PATCH] RPC: Make... |
2239 2240 2241 |
put_rpccred(msg.rpc_cred); return err; } |
188fef11d SUNRPC: Move rpc_... |
2242 |
|
5e1550d6a SUNRPC: Add the h... |
2243 2244 2245 2246 2247 2248 |
struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags) { struct rpc_message msg = { .rpc_proc = &rpcproc_null, .rpc_cred = cred, }; |
84115e1cd SUNRPC: Cleanup o... |
2249 2250 2251 2252 2253 2254 |
struct rpc_task_setup task_setup_data = { .rpc_client = clnt, .rpc_message = &msg, .callback_ops = &rpc_default_ops, .flags = flags, }; |
c970aa85e SUNRPC: Clean up ... |
2255 |
return rpc_run_task(&task_setup_data); |
5e1550d6a SUNRPC: Add the h... |
2256 |
} |
e8914c65f SUNRPC: Restrict ... |
2257 |
EXPORT_SYMBOL_GPL(rpc_call_null); |
5e1550d6a SUNRPC: Add the h... |
2258 |
|
188fef11d SUNRPC: Move rpc_... |
2259 |
#ifdef RPC_DEBUG |
68a23ee94 SUNRPC: Don't dis... |
2260 2261 |
static void rpc_show_header(void) { |
cb3997b5a SUNRPC: Display s... |
2262 2263 2264 |
printk(KERN_INFO "-pid- flgs status -client- --rqstp- " "-timeout ---ops-- "); |
68a23ee94 SUNRPC: Don't dis... |
2265 |
} |
38e886e0c SUNRPC: Refactor ... |
2266 2267 2268 2269 |
static void rpc_show_task(const struct rpc_clnt *clnt, const struct rpc_task *task) { const char *rpc_waitq = "none"; |
38e886e0c SUNRPC: Refactor ... |
2270 2271 2272 |
if (RPC_IS_QUEUED(task)) rpc_waitq = rpc_qname(task->tk_waitqueue); |
b3bcedadf net/sunrpc/clnt.c... |
2273 2274 |
printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s ", |
cb3997b5a SUNRPC: Display s... |
2275 2276 2277 |
task->tk_pid, task->tk_flags, task->tk_status, clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), |
b3bcedadf net/sunrpc/clnt.c... |
2278 |
task->tk_action, rpc_waitq); |
38e886e0c SUNRPC: Refactor ... |
2279 |
} |
70abc49b4 SUNRPC: make SUNP... |
2280 |
void rpc_show_tasks(struct net *net) |
188fef11d SUNRPC: Move rpc_... |
2281 2282 |
{ struct rpc_clnt *clnt; |
38e886e0c SUNRPC: Refactor ... |
2283 |
struct rpc_task *task; |
68a23ee94 SUNRPC: Don't dis... |
2284 |
int header = 0; |
70abc49b4 SUNRPC: make SUNP... |
2285 |
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
188fef11d SUNRPC: Move rpc_... |
2286 |
|
70abc49b4 SUNRPC: make SUNP... |
2287 2288 |
spin_lock(&sn->rpc_client_lock); list_for_each_entry(clnt, &sn->all_clients, cl_clients) { |
188fef11d SUNRPC: Move rpc_... |
2289 |
spin_lock(&clnt->cl_lock); |
38e886e0c SUNRPC: Refactor ... |
2290 |
list_for_each_entry(task, &clnt->cl_tasks, tk_task) { |
68a23ee94 SUNRPC: Don't dis... |
2291 2292 2293 2294 |
if (!header) { rpc_show_header(); header++; } |
38e886e0c SUNRPC: Refactor ... |
2295 |
rpc_show_task(clnt, task); |
188fef11d SUNRPC: Move rpc_... |
2296 2297 2298 |
} spin_unlock(&clnt->cl_lock); } |
70abc49b4 SUNRPC: make SUNP... |
2299 |
spin_unlock(&sn->rpc_client_lock); |
188fef11d SUNRPC: Move rpc_... |
2300 2301 |
} #endif |