Blame view
net/sunrpc/clnt.c
44.5 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 19 20 21 22 23 |
* Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> */ #include <asm/system.h> #include <linux/module.h> #include <linux/types.h> |
cb3997b5a SUNRPC: Display s... |
24 |
#include <linux/kallsyms.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
#include <linux/mm.h> |
23ac65817 SUNRPC: clean up ... |
26 27 |
#include <linux/namei.h> #include <linux/mount.h> |
1da177e4c Linux-2.6.12-rc2 |
28 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
29 |
#include <linux/utsname.h> |
11c556b3d SUNRPC: provide a... |
30 |
#include <linux/workqueue.h> |
176e21ee2 SUNRPC: Support f... |
31 |
#include <linux/in.h> |
510deb0d7 SUNRPC: rpc_creat... |
32 |
#include <linux/in6.h> |
176e21ee2 SUNRPC: Support f... |
33 |
#include <linux/un.h> |
1da177e4c Linux-2.6.12-rc2 |
34 35 |
#include <linux/sunrpc/clnt.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> |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
55ae1aabf nfs41: Add backch... |
40 |
#include "sunrpc.h" |
1da177e4c Linux-2.6.12-rc2 |
41 |
|
1da177e4c Linux-2.6.12-rc2 |
42 43 44 |
#ifdef RPC_DEBUG # define RPCDBG_FACILITY RPCDBG_CALL #endif |
46121cf7d SUNRPC: fix print... |
45 46 47 |
#define dprint_status(t) \ dprintk("RPC: %5u %s (status %d) ", t->tk_pid, \ |
0dc47877a net: replace rema... |
48 |
__func__, t->tk_status) |
46121cf7d SUNRPC: fix print... |
49 |
|
188fef11d SUNRPC: Move rpc_... |
50 51 52 53 54 |
/* * All RPC clients are linked into this list */ static LIST_HEAD(all_clients); static DEFINE_SPINLOCK(rpc_client_lock); |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 |
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 |
62 63 |
static void call_decode(struct rpc_task *task); static void call_bind(struct rpc_task *task); |
da3518780 [PATCH] RPC: prop... |
64 |
static void call_bind_status(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
65 |
static void call_transmit(struct rpc_task *task); |
9e00abc3c SUNRPC: sunrpc sh... |
66 |
#if defined(CONFIG_SUNRPC_BACKCHANNEL) |
55ae1aabf nfs41: Add backch... |
67 |
static void call_bc_transmit(struct rpc_task *task); |
9e00abc3c SUNRPC: sunrpc sh... |
68 |
#endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1da177e4c Linux-2.6.12-rc2 |
69 |
static void call_status(struct rpc_task *task); |
940e3318c [PATCH] SUNRPC: d... |
70 |
static void call_transmit_status(struct rpc_task *task); |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 75 |
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 |
76 |
|
b0e1c57ea SUNRPC: Rename "c... |
77 78 |
static __be32 *rpc_encode_header(struct rpc_task *task); static __be32 *rpc_verify_header(struct rpc_task *task); |
caabea8a5 SUNRPC: Use soft ... |
79 |
static int rpc_ping(struct rpc_clnt *clnt); |
64c91a1f1 SUNRPC: Make rpc_... |
80 |
|
188fef11d SUNRPC: Move rpc_... |
81 82 83 84 85 86 87 88 89 90 91 92 93 |
static void rpc_register_client(struct rpc_clnt *clnt) { spin_lock(&rpc_client_lock); list_add(&clnt->cl_clients, &all_clients); spin_unlock(&rpc_client_lock); } static void rpc_unregister_client(struct rpc_clnt *clnt) { spin_lock(&rpc_client_lock); list_del(&clnt->cl_clients); spin_unlock(&rpc_client_lock); } |
1da177e4c Linux-2.6.12-rc2 |
94 95 96 97 |
static int rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) { |
f134585a7 Revert "[PATCH] R... |
98 |
static uint32_t clntid; |
e0a012493 switch vfs_path_l... |
99 |
struct path path, dir; |
23ac65817 SUNRPC: clean up ... |
100 101 102 103 |
char name[15]; struct qstr q = { .name = name, }; |
1da177e4c Linux-2.6.12-rc2 |
104 |
int error; |
7d217caca SUNRPC: Replace r... |
105 106 |
clnt->cl_path.mnt = ERR_PTR(-ENOENT); clnt->cl_path.dentry = ERR_PTR(-ENOENT); |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
if (dir_name == NULL) return 0; |
542815482 SUNRPC: Fix a 'Bu... |
109 |
|
23ac65817 SUNRPC: clean up ... |
110 111 112 |
path.mnt = rpc_get_mount(); if (IS_ERR(path.mnt)) return PTR_ERR(path.mnt); |
e0a012493 switch vfs_path_l... |
113 |
error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &dir); |
23ac65817 SUNRPC: clean up ... |
114 115 |
if (error) goto err; |
542815482 SUNRPC: Fix a 'Bu... |
116 |
|
f134585a7 Revert "[PATCH] R... |
117 |
for (;;) { |
23ac65817 SUNRPC: clean up ... |
118 119 120 |
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); |
e0a012493 switch vfs_path_l... |
121 |
path.dentry = rpc_create_client_dir(dir.dentry, &q, clnt); |
23ac65817 SUNRPC: clean up ... |
122 123 124 |
if (!IS_ERR(path.dentry)) break; error = PTR_ERR(path.dentry); |
f134585a7 Revert "[PATCH] R... |
125 |
if (error != -EEXIST) { |
23ac65817 SUNRPC: clean up ... |
126 127 128 129 130 |
printk(KERN_INFO "RPC: Couldn't create pipefs entry" " %s/%s, error %d ", dir_name, name, error); goto err_path_put; |
f134585a7 Revert "[PATCH] R... |
131 |
} |
1da177e4c Linux-2.6.12-rc2 |
132 |
} |
e0a012493 switch vfs_path_l... |
133 |
path_put(&dir); |
23ac65817 SUNRPC: clean up ... |
134 135 136 |
clnt->cl_path = path; return 0; err_path_put: |
e0a012493 switch vfs_path_l... |
137 |
path_put(&dir); |
23ac65817 SUNRPC: clean up ... |
138 139 140 |
err: rpc_put_mount(); return error; |
1da177e4c Linux-2.6.12-rc2 |
141 |
} |
698b6d088 SUNRPC: cleanup f... |
142 |
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
1da177e4c Linux-2.6.12-rc2 |
143 |
{ |
698b6d088 SUNRPC: cleanup f... |
144 |
struct rpc_program *program = args->program; |
1da177e4c Linux-2.6.12-rc2 |
145 146 |
struct rpc_version *version; struct rpc_clnt *clnt = NULL; |
6a19275ad [PATCH] RPC: [PAT... |
147 |
struct rpc_auth *auth; |
1da177e4c Linux-2.6.12-rc2 |
148 |
int err; |
06b8d2552 SUNRPC: Make sure... |
149 150 151 152 |
size_t len; /* sanity check the name before trying to print it */ err = -EINVAL; |
698b6d088 SUNRPC: cleanup f... |
153 |
len = strlen(args->servername); |
06b8d2552 SUNRPC: Make sure... |
154 155 156 |
if (len > RPC_MAXNETNAMELEN) goto out_no_rpciod; len++; |
1da177e4c Linux-2.6.12-rc2 |
157 |
|
46121cf7d SUNRPC: fix print... |
158 159 |
dprintk("RPC: creating %s client for %s (xprt %p) ", |
698b6d088 SUNRPC: cleanup f... |
160 |
program->name, args->servername, xprt); |
1da177e4c Linux-2.6.12-rc2 |
161 |
|
4ada539ed SUNRPC: Make crea... |
162 163 164 |
err = rpciod_up(); if (err) goto out_no_rpciod; |
1da177e4c Linux-2.6.12-rc2 |
165 166 |
err = -EINVAL; if (!xprt) |
712917d1c [PATCH] SUNRPC: f... |
167 |
goto out_no_xprt; |
698b6d088 SUNRPC: cleanup f... |
168 169 170 171 172 |
if (args->version >= program->nrvers) goto out_err; version = program->version[args->version]; if (version == NULL) |
1da177e4c Linux-2.6.12-rc2 |
173 174 175 |
goto out_err; err = -ENOMEM; |
0da974f4f [NET]: Conversion... |
176 |
clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
177 178 |
if (!clnt) goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
179 180 181 |
clnt->cl_parent = clnt; clnt->cl_server = clnt->cl_inline_name; |
1da177e4c Linux-2.6.12-rc2 |
182 183 |
if (len > sizeof(clnt->cl_inline_name)) { char *buf = kmalloc(len, GFP_KERNEL); |
698b6d088 SUNRPC: cleanup f... |
184 |
if (buf != NULL) |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 188 |
clnt->cl_server = buf; else len = sizeof(clnt->cl_inline_name); } |
698b6d088 SUNRPC: cleanup f... |
189 |
strlcpy(clnt->cl_server, args->servername, len); |
1da177e4c Linux-2.6.12-rc2 |
190 191 192 193 194 |
clnt->cl_xprt = xprt; clnt->cl_procinfo = version->procs; clnt->cl_maxproc = version->nrprocs; clnt->cl_protname = program->name; |
d5b337b48 nfsd: use nfs cli... |
195 |
clnt->cl_prog = args->prognumber ? : program->number; |
1da177e4c Linux-2.6.12-rc2 |
196 |
clnt->cl_vers = version->number; |
1da177e4c Linux-2.6.12-rc2 |
197 |
clnt->cl_stats = program->stats; |
11c556b3d SUNRPC: provide a... |
198 |
clnt->cl_metrics = rpc_alloc_iostats(clnt); |
23bf85ba4 SUNRPC: Handle th... |
199 200 201 |
err = -ENOMEM; if (clnt->cl_metrics == NULL) goto out_no_stats; |
3e32a5d99 SUNRPC: Give clon... |
202 |
clnt->cl_program = program; |
6529eba08 SUNRPC: Move rpc_... |
203 |
INIT_LIST_HEAD(&clnt->cl_tasks); |
4bef61ff7 SUNRPC: Add a per... |
204 |
spin_lock_init(&clnt->cl_lock); |
1da177e4c Linux-2.6.12-rc2 |
205 |
|
ec739ef03 SUNRPC: Create a ... |
206 |
if (!xprt_bound(clnt->cl_xprt)) |
1da177e4c Linux-2.6.12-rc2 |
207 |
clnt->cl_autobind = 1; |
ba7392bb3 SUNRPC: Add suppo... |
208 209 210 211 212 213 |
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 |
214 |
clnt->cl_rtt = &clnt->cl_rtt_default; |
ba7392bb3 SUNRPC: Add suppo... |
215 |
rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); |
608207e88 rpc: pass target ... |
216 217 218 219 220 221 |
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 |
222 |
|
006abe887 SUNRPC: Fix a rac... |
223 |
atomic_set(&clnt->cl_count, 1); |
34f52e359 SUNRPC: Convert r... |
224 |
|
1da177e4c Linux-2.6.12-rc2 |
225 226 227 |
err = rpc_setup_pipedir(clnt, program->pipe_dir_name); if (err < 0) goto out_no_path; |
698b6d088 SUNRPC: cleanup f... |
228 |
auth = rpcauth_create(args->authflavor, clnt); |
6a19275ad [PATCH] RPC: [PAT... |
229 |
if (IS_ERR(auth)) { |
1da177e4c Linux-2.6.12-rc2 |
230 231 |
printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u) ", |
698b6d088 SUNRPC: cleanup f... |
232 |
args->authflavor); |
6a19275ad [PATCH] RPC: [PAT... |
233 |
err = PTR_ERR(auth); |
1da177e4c Linux-2.6.12-rc2 |
234 235 236 237 |
goto out_no_auth; } /* save the nodename */ |
63ffc23d3 sunrpc: fix oops ... |
238 |
clnt->cl_nodelen = strlen(init_utsname()->nodename); |
1da177e4c Linux-2.6.12-rc2 |
239 240 |
if (clnt->cl_nodelen > UNX_MAXNODENAME) clnt->cl_nodelen = UNX_MAXNODENAME; |
63ffc23d3 sunrpc: fix oops ... |
241 |
memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen); |
6529eba08 SUNRPC: Move rpc_... |
242 |
rpc_register_client(clnt); |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 |
return clnt; out_no_auth: |
7d217caca SUNRPC: Replace r... |
246 247 |
if (!IS_ERR(clnt->cl_path.dentry)) { rpc_remove_client_dir(clnt->cl_path.dentry); |
542815482 SUNRPC: Fix a 'Bu... |
248 249 |
rpc_put_mount(); } |
1da177e4c Linux-2.6.12-rc2 |
250 |
out_no_path: |
608207e88 rpc: pass target ... |
251 252 |
kfree(clnt->cl_principal); out_no_principal: |
23bf85ba4 SUNRPC: Handle th... |
253 254 |
rpc_free_iostats(clnt->cl_metrics); out_no_stats: |
1da177e4c Linux-2.6.12-rc2 |
255 256 257 258 |
if (clnt->cl_server != clnt->cl_inline_name) kfree(clnt->cl_server); kfree(clnt); out_err: |
6b6ca86b7 SUNRPC: Add refco... |
259 |
xprt_put(xprt); |
712917d1c [PATCH] SUNRPC: f... |
260 |
out_no_xprt: |
4ada539ed SUNRPC: Make crea... |
261 262 |
rpciod_down(); out_no_rpciod: |
1da177e4c Linux-2.6.12-rc2 |
263 264 |
return ERR_PTR(err); } |
c2866763b SUNRPC: use socka... |
265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
/* * 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... |
279 |
struct xprt_create xprtargs = { |
9a23e332e sunrpc: Add net t... |
280 |
.net = args->net, |
4fa016eb2 NFS/SUNRPC: suppo... |
281 |
.ident = args->protocol, |
d3bc9a1de SUNRPC client: ad... |
282 |
.srcaddr = args->saddress, |
96802a095 SUNRPC: cleanup t... |
283 284 |
.dstaddr = args->address, .addrlen = args->addrsize, |
f300baba5 nfsd41: sunrpc: a... |
285 |
.bc_xprt = args->bc_xprt, |
96802a095 SUNRPC: cleanup t... |
286 |
}; |
510deb0d7 SUNRPC: rpc_creat... |
287 |
char servername[48]; |
c2866763b SUNRPC: use socka... |
288 |
|
c2866763b SUNRPC: use socka... |
289 |
/* |
43780b87f SUNRPC: Add a con... |
290 291 292 293 |
* If the caller chooses not to specify a hostname, whip * up a string representation of the passed-in address. */ if (args->servername == NULL) { |
176e21ee2 SUNRPC: Support f... |
294 295 |
struct sockaddr_un *sun = (struct sockaddr_un *)args->address; |
da09eb930 SUNRPC: Clean up ... |
296 297 298 299 |
struct sockaddr_in *sin = (struct sockaddr_in *)args->address; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)args->address; |
510deb0d7 SUNRPC: rpc_creat... |
300 301 |
servername[0] = '\0'; switch (args->address->sa_family) { |
176e21ee2 SUNRPC: Support f... |
302 303 304 305 |
case AF_LOCAL: snprintf(servername, sizeof(servername), "%s", sun->sun_path); break; |
da09eb930 SUNRPC: Clean up ... |
306 |
case AF_INET: |
21454aaad net: replace NIPQ... |
307 308 |
snprintf(servername, sizeof(servername), "%pI4", &sin->sin_addr.s_addr); |
510deb0d7 SUNRPC: rpc_creat... |
309 |
break; |
da09eb930 SUNRPC: Clean up ... |
310 |
case AF_INET6: |
5b095d989 net: replace %p6 ... |
311 |
snprintf(servername, sizeof(servername), "%pI6", |
da09eb930 SUNRPC: Clean up ... |
312 |
&sin6->sin6_addr); |
510deb0d7 SUNRPC: rpc_creat... |
313 |
break; |
510deb0d7 SUNRPC: rpc_creat... |
314 315 316 317 318 |
default: /* caller wants default server name, but * address family isn't recognized. */ return ERR_PTR(-EINVAL); } |
43780b87f SUNRPC: Add a con... |
319 320 |
args->servername = servername; } |
510deb0d7 SUNRPC: rpc_creat... |
321 322 323 |
xprt = xprt_create_transport(&xprtargs); if (IS_ERR(xprt)) return (struct rpc_clnt *)xprt; |
43780b87f SUNRPC: Add a con... |
324 |
/* |
c2866763b SUNRPC: use socka... |
325 326 327 328 329 330 331 332 |
* 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... |
333 |
clnt = rpc_new_client(args, xprt); |
c2866763b SUNRPC: use socka... |
334 335 336 337 |
if (IS_ERR(clnt)) return clnt; if (!(args->flags & RPC_CLNT_CREATE_NOPING)) { |
caabea8a5 SUNRPC: Use soft ... |
338 |
int err = rpc_ping(clnt); |
c2866763b SUNRPC: use socka... |
339 340 341 342 343 344 345 346 347 |
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... |
348 349 |
if (args->flags & RPC_CLNT_CREATE_AUTOBIND) clnt->cl_autobind = 1; |
43d78ef2b NFS: disconnect b... |
350 351 |
if (args->flags & RPC_CLNT_CREATE_DISCRTRY) clnt->cl_discrtry = 1; |
b6b6152c4 rpc: bring back c... |
352 353 |
if (!(args->flags & RPC_CLNT_CREATE_QUIET)) clnt->cl_chatty = 1; |
c2866763b SUNRPC: use socka... |
354 355 356 |
return clnt; } |
b86acd501 SUNRPC: export ne... |
357 |
EXPORT_SYMBOL_GPL(rpc_create); |
c2866763b SUNRPC: use socka... |
358 |
|
1da177e4c Linux-2.6.12-rc2 |
359 360 361 362 363 364 365 366 367 |
/* * This function clones the RPC client structure. It allows us to share the * same transport while varying parameters such as the authentication * flavour. */ struct rpc_clnt * rpc_clone_client(struct rpc_clnt *clnt) { struct rpc_clnt *new; |
3e32a5d99 SUNRPC: Give clon... |
368 |
int err = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
369 |
|
e69062b4f [SUNRPC]: Use k{m... |
370 |
new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
371 372 |
if (!new) goto out_no_clnt; |
d431a555f SUNRPC: Don't cre... |
373 374 375 376 377 |
new->cl_parent = clnt; /* Turn off autobind on clones */ new->cl_autobind = 0; INIT_LIST_HEAD(&new->cl_tasks); spin_lock_init(&new->cl_lock); |
ba7392bb3 SUNRPC: Add suppo... |
378 |
rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval); |
23bf85ba4 SUNRPC: Handle th... |
379 380 381 |
new->cl_metrics = rpc_alloc_iostats(clnt); if (new->cl_metrics == NULL) goto out_no_stats; |
608207e88 rpc: pass target ... |
382 383 384 385 386 |
if (clnt->cl_principal) { new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL); if (new->cl_principal == NULL) goto out_no_principal; } |
006abe887 SUNRPC: Fix a rac... |
387 |
atomic_set(&new->cl_count, 1); |
3e32a5d99 SUNRPC: Give clon... |
388 389 390 |
err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); if (err != 0) goto out_no_path; |
1da177e4c Linux-2.6.12-rc2 |
391 392 |
if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); |
d431a555f SUNRPC: Don't cre... |
393 |
xprt_get(clnt->cl_xprt); |
006abe887 SUNRPC: Fix a rac... |
394 |
atomic_inc(&clnt->cl_count); |
6529eba08 SUNRPC: Move rpc_... |
395 |
rpc_register_client(new); |
4ada539ed SUNRPC: Make crea... |
396 |
rpciod_up(); |
1da177e4c Linux-2.6.12-rc2 |
397 |
return new; |
3e32a5d99 SUNRPC: Give clon... |
398 |
out_no_path: |
608207e88 rpc: pass target ... |
399 400 |
kfree(new->cl_principal); out_no_principal: |
3e32a5d99 SUNRPC: Give clon... |
401 |
rpc_free_iostats(new->cl_metrics); |
23bf85ba4 SUNRPC: Handle th... |
402 403 |
out_no_stats: kfree(new); |
1da177e4c Linux-2.6.12-rc2 |
404 |
out_no_clnt: |
0dc47877a net: replace rema... |
405 406 |
dprintk("RPC: %s: returned error %d ", __func__, err); |
3e32a5d99 SUNRPC: Give clon... |
407 |
return ERR_PTR(err); |
1da177e4c Linux-2.6.12-rc2 |
408 |
} |
e8914c65f SUNRPC: Restrict ... |
409 |
EXPORT_SYMBOL_GPL(rpc_clone_client); |
1da177e4c Linux-2.6.12-rc2 |
410 411 |
/* |
58f9612c6 SUNRPC: Move rema... |
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
* 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 ... |
434 435 436 |
if (RPC_IS_QUEUED(rovr)) rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr); |
58f9612c6 SUNRPC: Move rema... |
437 438 439 440 441 442 443 |
} } spin_unlock(&clnt->cl_lock); } EXPORT_SYMBOL_GPL(rpc_killall_tasks); /* |
1da177e4c Linux-2.6.12-rc2 |
444 |
* Properly shut down an RPC client, terminating all outstanding |
90c5755ff SUNRPC: Kill rpc_... |
445 |
* requests. |
1da177e4c Linux-2.6.12-rc2 |
446 |
*/ |
4c402b409 SUNRPC: Remove rp... |
447 |
void rpc_shutdown_client(struct rpc_clnt *clnt) |
1da177e4c Linux-2.6.12-rc2 |
448 |
{ |
34f52e359 SUNRPC: Convert r... |
449 450 451 |
dprintk("RPC: shutting down %s client for %s ", clnt->cl_protname, clnt->cl_server); |
1da177e4c Linux-2.6.12-rc2 |
452 |
|
34f52e359 SUNRPC: Convert r... |
453 |
while (!list_empty(&clnt->cl_tasks)) { |
1da177e4c Linux-2.6.12-rc2 |
454 |
rpc_killall_tasks(clnt); |
532347e2b [PATCH] nfs: slee... |
455 |
wait_event_timeout(destroy_wait, |
34f52e359 SUNRPC: Convert r... |
456 |
list_empty(&clnt->cl_tasks), 1*HZ); |
1da177e4c Linux-2.6.12-rc2 |
457 |
} |
4c402b409 SUNRPC: Remove rp... |
458 |
rpc_release_client(clnt); |
1da177e4c Linux-2.6.12-rc2 |
459 |
} |
e8914c65f SUNRPC: Restrict ... |
460 |
EXPORT_SYMBOL_GPL(rpc_shutdown_client); |
1da177e4c Linux-2.6.12-rc2 |
461 462 |
/* |
34f52e359 SUNRPC: Convert r... |
463 |
* Free an RPC client |
1da177e4c Linux-2.6.12-rc2 |
464 |
*/ |
34f52e359 SUNRPC: Convert r... |
465 |
static void |
006abe887 SUNRPC: Fix a rac... |
466 |
rpc_free_client(struct rpc_clnt *clnt) |
1da177e4c Linux-2.6.12-rc2 |
467 |
{ |
46121cf7d SUNRPC: fix print... |
468 469 |
dprintk("RPC: destroying %s client for %s ", |
1da177e4c Linux-2.6.12-rc2 |
470 |
clnt->cl_protname, clnt->cl_server); |
7d217caca SUNRPC: Replace r... |
471 472 |
if (!IS_ERR(clnt->cl_path.dentry)) { rpc_remove_client_dir(clnt->cl_path.dentry); |
8f8e7a50f SUNRPC: Fix dentr... |
473 474 |
rpc_put_mount(); } |
3e32a5d99 SUNRPC: Give clon... |
475 |
if (clnt->cl_parent != clnt) { |
8ad7c892e SUNRPC: Make rpc_... |
476 |
rpc_release_client(clnt->cl_parent); |
3e32a5d99 SUNRPC: Give clon... |
477 478 |
goto out_free; } |
1da177e4c Linux-2.6.12-rc2 |
479 480 481 |
if (clnt->cl_server != clnt->cl_inline_name) kfree(clnt->cl_server); out_free: |
6529eba08 SUNRPC: Move rpc_... |
482 |
rpc_unregister_client(clnt); |
11c556b3d SUNRPC: provide a... |
483 |
rpc_free_iostats(clnt->cl_metrics); |
608207e88 rpc: pass target ... |
484 |
kfree(clnt->cl_principal); |
11c556b3d SUNRPC: provide a... |
485 |
clnt->cl_metrics = NULL; |
6b6ca86b7 SUNRPC: Add refco... |
486 |
xprt_put(clnt->cl_xprt); |
4ada539ed SUNRPC: Make crea... |
487 |
rpciod_down(); |
1da177e4c Linux-2.6.12-rc2 |
488 |
kfree(clnt); |
1da177e4c Linux-2.6.12-rc2 |
489 490 491 |
} /* |
1dd17ec69 SUNRPC: Allow rpc... |
492 493 494 |
* Free an RPC client */ static void |
006abe887 SUNRPC: Fix a rac... |
495 |
rpc_free_auth(struct rpc_clnt *clnt) |
1dd17ec69 SUNRPC: Allow rpc... |
496 |
{ |
1dd17ec69 SUNRPC: Allow rpc... |
497 |
if (clnt->cl_auth == NULL) { |
006abe887 SUNRPC: Fix a rac... |
498 |
rpc_free_client(clnt); |
1dd17ec69 SUNRPC: Allow rpc... |
499 500 501 502 503 504 505 506 |
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... |
507 |
atomic_inc(&clnt->cl_count); |
1dd17ec69 SUNRPC: Allow rpc... |
508 509 |
rpcauth_release(clnt->cl_auth); clnt->cl_auth = NULL; |
006abe887 SUNRPC: Fix a rac... |
510 511 |
if (atomic_dec_and_test(&clnt->cl_count)) rpc_free_client(clnt); |
1dd17ec69 SUNRPC: Allow rpc... |
512 513 514 |
} /* |
34f52e359 SUNRPC: Convert r... |
515 |
* Release reference to the RPC client |
1da177e4c Linux-2.6.12-rc2 |
516 517 518 519 |
*/ void rpc_release_client(struct rpc_clnt *clnt) { |
34f52e359 SUNRPC: Convert r... |
520 521 |
dprintk("RPC: rpc_release_client(%p) ", clnt); |
1da177e4c Linux-2.6.12-rc2 |
522 |
|
34f52e359 SUNRPC: Convert r... |
523 524 |
if (list_empty(&clnt->cl_tasks)) wake_up(&destroy_wait); |
006abe887 SUNRPC: Fix a rac... |
525 526 |
if (atomic_dec_and_test(&clnt->cl_count)) rpc_free_auth(clnt); |
34f52e359 SUNRPC: Convert r... |
527 |
} |
007e251f2 [PATCH] RPC: Allo... |
528 529 |
/** * rpc_bind_new_program - bind a new RPC program to an existing client |
65b6e42cd docbook: sunrpc f... |
530 531 532 |
* @old: old rpc_client * @program: rpc program to set * @vers: rpc program version |
007e251f2 [PATCH] RPC: Allo... |
533 534 535 536 537 538 539 |
* * 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, struct rpc_program *program, |
89eb21c35 SUNRPC: fix a sig... |
540 |
u32 vers) |
007e251f2 [PATCH] RPC: Allo... |
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 |
{ struct rpc_clnt *clnt; struct rpc_version *version; int err; BUG_ON(vers >= program->nrvers || !program->version[vers]); version = program->version[vers]; clnt = rpc_clone_client(old); if (IS_ERR(clnt)) goto out; clnt->cl_procinfo = version->procs; clnt->cl_maxproc = version->nrprocs; clnt->cl_protname = program->name; clnt->cl_prog = program->number; clnt->cl_vers = version->number; clnt->cl_stats = program->stats; |
caabea8a5 SUNRPC: Use soft ... |
557 |
err = rpc_ping(clnt); |
007e251f2 [PATCH] RPC: Allo... |
558 559 560 561 |
if (err != 0) { rpc_shutdown_client(clnt); clnt = ERR_PTR(err); } |
cca5172a7 [NET] SUNRPC: Fix... |
562 |
out: |
007e251f2 [PATCH] RPC: Allo... |
563 564 |
return clnt; } |
e8914c65f SUNRPC: Restrict ... |
565 |
EXPORT_SYMBOL_GPL(rpc_bind_new_program); |
007e251f2 [PATCH] RPC: Allo... |
566 |
|
58f9612c6 SUNRPC: Move rema... |
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 |
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... |
588 |
atomic_inc(&clnt->cl_count); |
58f9612c6 SUNRPC: Move rema... |
589 590 591 592 593 594 595 596 |
if (clnt->cl_softrtry) task->tk_flags |= RPC_TASK_SOFT; /* 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... |
597 598 599 600 601 602 |
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... |
603 604 605 606 607 608 609 |
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 ... |
610 611 |
if (msg->rpc_cred != NULL) task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred); |
58f9612c6 SUNRPC: Move rema... |
612 613 |
} } |
1da177e4c Linux-2.6.12-rc2 |
614 615 616 617 |
/* * Default callback for async RPC calls */ static void |
963d8fe53 RPC: Clean up RPC... |
618 |
rpc_default_callback(struct rpc_task *task, void *data) |
1da177e4c Linux-2.6.12-rc2 |
619 620 |
{ } |
963d8fe53 RPC: Clean up RPC... |
621 622 623 |
static const struct rpc_call_ops rpc_default_ops = { .rpc_call_done = rpc_default_callback, }; |
c970aa85e SUNRPC: Clean up ... |
624 625 626 627 628 |
/** * 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 ... |
629 |
{ |
19445b99b SUNRPC: Cleanup -... |
630 |
struct rpc_task *task; |
6e5b70e9d SUNRPC: clean up ... |
631 |
|
84115e1cd SUNRPC: Cleanup o... |
632 |
task = rpc_new_task(task_setup_data); |
19445b99b SUNRPC: Cleanup -... |
633 |
if (IS_ERR(task)) |
508592590 SUNRPC: Mask sign... |
634 |
goto out; |
6e5b70e9d SUNRPC: clean up ... |
635 |
|
58f9612c6 SUNRPC: Move rema... |
636 637 |
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... |
638 639 |
if (task->tk_action == NULL) rpc_call_start(task); |
6e5b70e9d SUNRPC: clean up ... |
640 641 |
atomic_inc(&task->tk_count); rpc_execute(task); |
6e5b70e9d SUNRPC: clean up ... |
642 |
out: |
19445b99b SUNRPC: Cleanup -... |
643 |
return task; |
6e5b70e9d SUNRPC: clean up ... |
644 |
} |
c970aa85e SUNRPC: Clean up ... |
645 |
EXPORT_SYMBOL_GPL(rpc_run_task); |
6e5b70e9d SUNRPC: clean up ... |
646 647 648 649 650 651 |
/** * 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 |
652 |
*/ |
cbc200592 SUNRPC: Declare a... |
653 |
int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags) |
1da177e4c Linux-2.6.12-rc2 |
654 655 |
{ struct rpc_task *task; |
84115e1cd SUNRPC: Cleanup o... |
656 657 658 659 660 661 |
struct rpc_task_setup task_setup_data = { .rpc_client = clnt, .rpc_message = msg, .callback_ops = &rpc_default_ops, .flags = flags, }; |
6e5b70e9d SUNRPC: clean up ... |
662 |
int status; |
1da177e4c Linux-2.6.12-rc2 |
663 |
|
1da177e4c Linux-2.6.12-rc2 |
664 |
BUG_ON(flags & RPC_TASK_ASYNC); |
c970aa85e SUNRPC: Clean up ... |
665 |
task = rpc_run_task(&task_setup_data); |
6e5b70e9d SUNRPC: clean up ... |
666 667 |
if (IS_ERR(task)) return PTR_ERR(task); |
e60859ac0 SUNRPC: rpc_execu... |
668 |
status = task->tk_status; |
bde8f00ce [PATCH] NFS: Fix ... |
669 |
rpc_put_task(task); |
1da177e4c Linux-2.6.12-rc2 |
670 671 |
return status; } |
e8914c65f SUNRPC: Restrict ... |
672 |
EXPORT_SYMBOL_GPL(rpc_call_sync); |
1da177e4c Linux-2.6.12-rc2 |
673 |
|
6e5b70e9d SUNRPC: clean up ... |
674 675 676 677 678 |
/** * 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... |
679 |
* @tk_ops: RPC call ops |
6e5b70e9d SUNRPC: clean up ... |
680 |
* @data: user call data |
1da177e4c Linux-2.6.12-rc2 |
681 682 |
*/ int |
cbc200592 SUNRPC: Declare a... |
683 |
rpc_call_async(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags, |
963d8fe53 RPC: Clean up RPC... |
684 |
const struct rpc_call_ops *tk_ops, void *data) |
1da177e4c Linux-2.6.12-rc2 |
685 686 |
{ struct rpc_task *task; |
84115e1cd SUNRPC: Cleanup o... |
687 688 689 690 691 692 693 |
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 |
694 |
|
c970aa85e SUNRPC: Clean up ... |
695 |
task = rpc_run_task(&task_setup_data); |
6e5b70e9d SUNRPC: clean up ... |
696 697 698 699 |
if (IS_ERR(task)) return PTR_ERR(task); rpc_put_task(task); return 0; |
1da177e4c Linux-2.6.12-rc2 |
700 |
} |
e8914c65f SUNRPC: Restrict ... |
701 |
EXPORT_SYMBOL_GPL(rpc_call_async); |
1da177e4c Linux-2.6.12-rc2 |
702 |
|
9e00abc3c SUNRPC: sunrpc sh... |
703 |
#if defined(CONFIG_SUNRPC_BACKCHANNEL) |
55ae1aabf nfs41: Add backch... |
704 705 706 |
/** * rpc_run_bc_task - Allocate a new RPC task for backchannel use, then run * rpc_execute against it |
7a73fdde3 net: fix htmldocs... |
707 708 |
* @req: RPC request * @tk_ops: RPC call ops |
55ae1aabf nfs41: Add backch... |
709 710 |
*/ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, |
7a73fdde3 net: fix htmldocs... |
711 |
const struct rpc_call_ops *tk_ops) |
55ae1aabf nfs41: Add backch... |
712 713 714 715 716 717 718 719 720 721 722 723 724 |
{ 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 -... |
725 |
if (IS_ERR(task)) { |
55ae1aabf nfs41: Add backch... |
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
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); BUG_ON(atomic_read(&task->tk_count) != 2); rpc_execute(task); out: dprintk("RPC: rpc_run_bc_task: task= %p ", task); return task; } |
9e00abc3c SUNRPC: sunrpc sh... |
748 |
#endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
55ae1aabf nfs41: Add backch... |
749 |
|
1da177e4c Linux-2.6.12-rc2 |
750 |
void |
77de2c590 SUNRPC: Add a hel... |
751 752 753 754 755 |
rpc_call_start(struct rpc_task *task) { task->tk_action = call_start; } EXPORT_SYMBOL_GPL(rpc_call_start); |
ed39440a2 SUNRPC: create AP... |
756 757 758 759 |
/** * rpc_peeraddr - extract remote peer address from clnt's xprt * @clnt: RPC client structure * @buf: target buffer |
65b6e42cd docbook: sunrpc f... |
760 |
* @bufsize: length of target buffer |
ed39440a2 SUNRPC: create AP... |
761 762 763 764 765 766 767 768 769 770 771 772 |
* * 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; struct rpc_xprt *xprt = clnt->cl_xprt; bytes = sizeof(xprt->addr); if (bytes > bufsize) bytes = bufsize; memcpy(buf, &clnt->cl_xprt->addr, bytes); |
c4efcb1d3 SUNRPC: Use "sock... |
773 |
return xprt->addrlen; |
ed39440a2 SUNRPC: create AP... |
774 |
} |
b86acd501 SUNRPC: export ne... |
775 |
EXPORT_SYMBOL_GPL(rpc_peeraddr); |
ed39440a2 SUNRPC: create AP... |
776 |
|
f425eba43 SUNRPC: Create AP... |
777 778 779 780 781 782 |
/** * rpc_peeraddr2str - return remote peer address in printable format * @clnt: RPC client structure * @format: address format * */ |
b454ae906 SUNRPC: fewer con... |
783 784 |
const char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format) |
f425eba43 SUNRPC: Create AP... |
785 786 |
{ struct rpc_xprt *xprt = clnt->cl_xprt; |
7559c7a28 SUNRPC: Make addr... |
787 788 789 790 791 |
if (xprt->address_strings[format] != NULL) return xprt->address_strings[format]; else return "unprintable"; |
f425eba43 SUNRPC: Create AP... |
792 |
} |
b86acd501 SUNRPC: export ne... |
793 |
EXPORT_SYMBOL_GPL(rpc_peeraddr2str); |
f425eba43 SUNRPC: Create AP... |
794 |
|
1da177e4c Linux-2.6.12-rc2 |
795 796 797 798 |
void rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize) { struct rpc_xprt *xprt = clnt->cl_xprt; |
470056c28 [PATCH] RPC: rati... |
799 800 |
if (xprt->ops->set_buffer_size) xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); |
1da177e4c Linux-2.6.12-rc2 |
801 |
} |
e8914c65f SUNRPC: Restrict ... |
802 |
EXPORT_SYMBOL_GPL(rpc_setbufsize); |
1da177e4c Linux-2.6.12-rc2 |
803 804 805 806 807 808 809 810 811 812 813 814 815 |
/* * Return size of largest payload RPC client can support, in bytes * * 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) { return clnt->cl_xprt->max_payload; } |
b86acd501 SUNRPC: export ne... |
816 |
EXPORT_SYMBOL_GPL(rpc_max_payload); |
1da177e4c Linux-2.6.12-rc2 |
817 |
|
35f5a422c SUNRPC: new inter... |
818 819 820 821 822 823 824 825 |
/** * rpc_force_rebind - force transport to check that remote port is unchanged * @clnt: client to rebind * */ void rpc_force_rebind(struct rpc_clnt *clnt) { if (clnt->cl_autobind) |
ec739ef03 SUNRPC: Create a ... |
826 |
xprt_clear_bound(clnt->cl_xprt); |
35f5a422c SUNRPC: new inter... |
827 |
} |
b86acd501 SUNRPC: export ne... |
828 |
EXPORT_SYMBOL_GPL(rpc_force_rebind); |
35f5a422c SUNRPC: new inter... |
829 |
|
1da177e4c Linux-2.6.12-rc2 |
830 |
/* |
aae2006e9 nfs41: sunrpc: Ex... |
831 832 833 |
* Restart an (async) RPC call from the call_prepare state. * Usually called from within the exit handler. */ |
f1f88fc7e SUNRPC: The funct... |
834 |
int |
aae2006e9 nfs41: sunrpc: Ex... |
835 836 837 |
rpc_restart_call_prepare(struct rpc_task *task) { if (RPC_ASSASSINATED(task)) |
f1f88fc7e SUNRPC: The funct... |
838 |
return 0; |
d00c5d438 NFS: Get rid of n... |
839 840 841 |
task->tk_action = call_start; if (task->tk_ops->rpc_call_prepare != NULL) task->tk_action = rpc_prepare_task; |
f1f88fc7e SUNRPC: The funct... |
842 |
return 1; |
aae2006e9 nfs41: sunrpc: Ex... |
843 844 845 846 |
} EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); /* |
1da177e4c Linux-2.6.12-rc2 |
847 848 849 |
* Restart an (async) RPC call. Usually called from within the * exit handler. */ |
f1f88fc7e SUNRPC: The funct... |
850 |
int |
1da177e4c Linux-2.6.12-rc2 |
851 852 853 |
rpc_restart_call(struct rpc_task *task) { if (RPC_ASSASSINATED(task)) |
f1f88fc7e SUNRPC: The funct... |
854 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
855 |
task->tk_action = call_start; |
f1f88fc7e SUNRPC: The funct... |
856 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
857 |
} |
e8914c65f SUNRPC: Restrict ... |
858 |
EXPORT_SYMBOL_GPL(rpc_restart_call); |
1da177e4c Linux-2.6.12-rc2 |
859 |
|
3748f1e44 SUNRPC: Add a fun... |
860 861 862 863 864 865 866 867 868 869 870 871 872 873 |
#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 |
874 875 876 877 878 879 880 881 882 883 |
/* * 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... |
884 885 |
dprintk("RPC: %5u call_start %s%d proc %s (%s) ", task->tk_pid, |
46121cf7d SUNRPC: fix print... |
886 |
clnt->cl_protname, clnt->cl_vers, |
3748f1e44 SUNRPC: Add a fun... |
887 |
rpc_proc_name(task), |
46121cf7d SUNRPC: fix print... |
888 |
(RPC_IS_ASYNC(task) ? "async" : "sync")); |
1da177e4c Linux-2.6.12-rc2 |
889 890 891 892 893 894 895 896 897 898 899 900 901 |
/* 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... |
902 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
903 |
|
1da177e4c Linux-2.6.12-rc2 |
904 905 906 907 908 909 910 911 912 913 914 915 |
task->tk_status = 0; task->tk_action = call_reserveresult; xprt_reserve(task); } /* * 1b. Grok the result of xprt_reserve() */ static void call_reserveresult(struct rpc_task *task) { int status = task->tk_status; |
46121cf7d SUNRPC: fix print... |
916 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
917 918 919 920 921 922 923 924 |
/* * 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... |
925 |
task->tk_action = call_refresh; |
1da177e4c Linux-2.6.12-rc2 |
926 927 928 929 930 |
return; } printk(KERN_ERR "%s: status=%d, but no request slot, exiting ", |
0dc47877a net: replace rema... |
931 |
__func__, status); |
1da177e4c Linux-2.6.12-rc2 |
932 933 934 935 936 937 938 939 940 941 942 |
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... |
943 |
__func__, status); |
1da177e4c Linux-2.6.12-rc2 |
944 945 946 947 948 949 950 951 952 953 954 955 |
xprt_release(task); } switch (status) { case -EAGAIN: /* woken up; retry */ task->tk_action = call_reserve; return; case -EIO: /* probably a shutdown */ break; default: printk(KERN_ERR "%s: unrecognized error %d, exiting ", |
0dc47877a net: replace rema... |
956 |
__func__, status); |
1da177e4c Linux-2.6.12-rc2 |
957 958 959 960 961 962 |
break; } rpc_exit(task, status); } /* |
55576244e SUNRPC: cleanup s... |
963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
* 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... |
987 |
task->tk_action = call_refresh; |
55576244e SUNRPC: cleanup s... |
988 |
switch (status) { |
5fc43978a SUNRPC: Fix an in... |
989 990 991 |
case 0: if (rpcauth_uptodatecred(task)) task->tk_action = call_allocate; |
55576244e SUNRPC: cleanup s... |
992 993 994 |
return; case -ETIMEDOUT: rpc_delay(task, 3*HZ); |
5fc43978a SUNRPC: Fix an in... |
995 996 997 998 999 1000 1001 1002 1003 |
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... |
1004 |
} |
5fc43978a SUNRPC: Fix an in... |
1005 1006 1007 1008 |
dprintk("RPC: %5u %s: refresh creds failed with error %d ", task->tk_pid, __func__, status); rpc_exit(task, status); |
55576244e SUNRPC: cleanup s... |
1009 1010 1011 1012 |
} /* * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc. |
021071483 SUNRPC: switchabl... |
1013 |
* (Note: buffer memory is freed in xprt_release). |
1da177e4c Linux-2.6.12-rc2 |
1014 1015 1016 1017 |
*/ static void call_allocate(struct rpc_task *task) { |
f2d47d02f Fix null derefere... |
1018 |
unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; |
021071483 SUNRPC: switchabl... |
1019 1020 |
struct rpc_rqst *req = task->tk_rqstp; struct rpc_xprt *xprt = task->tk_xprt; |
2bea90d43 SUNRPC: RPC buffe... |
1021 |
struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
1da177e4c Linux-2.6.12-rc2 |
1022 |
|
46121cf7d SUNRPC: fix print... |
1023 |
dprint_status(task); |
2bea90d43 SUNRPC: RPC buffe... |
1024 |
task->tk_status = 0; |
f2d47d02f Fix null derefere... |
1025 |
task->tk_action = call_bind; |
2bea90d43 SUNRPC: RPC buffe... |
1026 |
|
021071483 SUNRPC: switchabl... |
1027 |
if (req->rq_buffer) |
1da177e4c Linux-2.6.12-rc2 |
1028 |
return; |
2bea90d43 SUNRPC: RPC buffe... |
1029 1030 1031 1032 1033 |
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 |
1034 |
|
2bea90d43 SUNRPC: RPC buffe... |
1035 1036 1037 1038 1039 1040 1041 1042 1043 |
/* * 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... |
1044 1045 |
req->rq_buffer = xprt->ops->buf_alloc(task, req->rq_callsize + req->rq_rcvsize); |
2bea90d43 SUNRPC: RPC buffe... |
1046 |
if (req->rq_buffer != NULL) |
1da177e4c Linux-2.6.12-rc2 |
1047 |
return; |
46121cf7d SUNRPC: fix print... |
1048 1049 1050 |
dprintk("RPC: %5u rpc_buffer allocation failed ", task->tk_pid); |
1da177e4c Linux-2.6.12-rc2 |
1051 |
|
5afa9133c SUNRPC: Ensure th... |
1052 |
if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) { |
b6e9c713f SUNRPC: Don't cal... |
1053 |
task->tk_action = call_allocate; |
1da177e4c Linux-2.6.12-rc2 |
1054 1055 1056 1057 1058 1059 |
rpc_delay(task, HZ>>4); return; } rpc_exit(task, -ERESTARTSYS); } |
940e3318c [PATCH] SUNRPC: d... |
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 |
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... |
1070 |
task->tk_rqstp->rq_bytes_sent = 0; |
940e3318c [PATCH] SUNRPC: d... |
1071 |
} |
2bea90d43 SUNRPC: RPC buffe... |
1072 1073 1074 1075 1076 1077 1078 |
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... |
1079 |
buf->flags = 0; |
2bea90d43 SUNRPC: RPC buffe... |
1080 1081 1082 |
buf->len = 0; buf->buflen = len; } |
1da177e4c Linux-2.6.12-rc2 |
1083 1084 1085 1086 |
/* * 3. Encode arguments of an RPC call */ static void |
b0e1c57ea SUNRPC: Rename "c... |
1087 |
rpc_xdr_encode(struct rpc_task *task) |
1da177e4c Linux-2.6.12-rc2 |
1088 |
{ |
1da177e4c Linux-2.6.12-rc2 |
1089 |
struct rpc_rqst *req = task->tk_rqstp; |
9f06c719f SUNRPC: New xdr_s... |
1090 |
kxdreproc_t encode; |
d8ed029d6 [SUNRPC]: trivial... |
1091 |
__be32 *p; |
1da177e4c Linux-2.6.12-rc2 |
1092 |
|
46121cf7d SUNRPC: fix print... |
1093 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1094 |
|
2bea90d43 SUNRPC: RPC buffe... |
1095 1096 1097 1098 1099 1100 |
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 |
1101 |
|
b0e1c57ea SUNRPC: Rename "c... |
1102 1103 1104 1105 |
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 |
1106 1107 1108 |
rpc_exit(task, -EIO); return; } |
b0e1c57ea SUNRPC: Rename "c... |
1109 1110 |
encode = task->tk_msg.rpc_proc->p_encode; |
f3680312a SUNRPC: Retry wra... |
1111 1112 1113 1114 1115 |
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 |
1116 1117 1118 1119 1120 1121 1122 1123 |
} /* * 4. Get the server port number if not yet set */ static void call_bind(struct rpc_task *task) { |
ec739ef03 SUNRPC: Create a ... |
1124 |
struct rpc_xprt *xprt = task->tk_xprt; |
1da177e4c Linux-2.6.12-rc2 |
1125 |
|
46121cf7d SUNRPC: fix print... |
1126 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1127 |
|
da3518780 [PATCH] RPC: prop... |
1128 |
task->tk_action = call_connect; |
ec739ef03 SUNRPC: Create a ... |
1129 |
if (!xprt_bound(xprt)) { |
da3518780 [PATCH] RPC: prop... |
1130 |
task->tk_action = call_bind_status; |
ec739ef03 SUNRPC: Create a ... |
1131 |
task->tk_timeout = xprt->bind_timeout; |
bbf7c1dd2 SUNRPC: Introduce... |
1132 |
xprt->ops->rpcbind(task); |
1da177e4c Linux-2.6.12-rc2 |
1133 1134 1135 1136 |
} } /* |
da3518780 [PATCH] RPC: prop... |
1137 1138 1139 1140 1141 |
* 4a. Sort out bind result */ static void call_bind_status(struct rpc_task *task) { |
906462af4 SUNRPC: Split ano... |
1142 |
int status = -EIO; |
da3518780 [PATCH] RPC: prop... |
1143 1144 |
if (task->tk_status >= 0) { |
46121cf7d SUNRPC: fix print... |
1145 |
dprint_status(task); |
da3518780 [PATCH] RPC: prop... |
1146 1147 1148 1149 1150 1151 |
task->tk_status = 0; task->tk_action = call_connect; return; } switch (task->tk_status) { |
381ba74af SUNRPC: Ensure ou... |
1152 1153 1154 1155 |
case -ENOMEM: dprintk("RPC: %5u rpcbind out of memory ", task->tk_pid); rpc_delay(task, HZ >> 2); |
2429cbf6a SUNRPC: Add a new... |
1156 |
goto retry_timeout; |
da3518780 [PATCH] RPC: prop... |
1157 |
case -EACCES: |
46121cf7d SUNRPC: fix print... |
1158 1159 1160 |
dprintk("RPC: %5u remote rpcbind: RPC program/version " "unavailable ", task->tk_pid); |
b79dc8ced SUNRPC: RPC bind ... |
1161 1162 1163 1164 1165 |
/* 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... |
1166 1167 1168 |
if (task->tk_rebind_retry == 0) break; task->tk_rebind_retry--; |
ea635a517 SUNRPC: Retry rpc... |
1169 |
rpc_delay(task, 3*HZ); |
da45828e2 SUNRPC: Clean up ... |
1170 |
goto retry_timeout; |
da3518780 [PATCH] RPC: prop... |
1171 |
case -ETIMEDOUT: |
46121cf7d SUNRPC: fix print... |
1172 1173 |
dprintk("RPC: %5u rpcbind request timed out ", |
da3518780 [PATCH] RPC: prop... |
1174 |
task->tk_pid); |
da45828e2 SUNRPC: Clean up ... |
1175 |
goto retry_timeout; |
da3518780 [PATCH] RPC: prop... |
1176 |
case -EPFNOSUPPORT: |
906462af4 SUNRPC: Split ano... |
1177 |
/* server doesn't support any rpcbind version we know of */ |
012da158f SUNRPC: Use soft ... |
1178 1179 |
dprintk("RPC: %5u unrecognized remote rpcbind service ", |
da3518780 [PATCH] RPC: prop... |
1180 1181 1182 |
task->tk_pid); break; case -EPROTONOSUPPORT: |
00a6e7bbf SUNRPC: RPC clien... |
1183 1184 |
dprintk("RPC: %5u remote rpcbind version unavailable, retrying ", |
da3518780 [PATCH] RPC: prop... |
1185 |
task->tk_pid); |
00a6e7bbf SUNRPC: RPC clien... |
1186 1187 1188 |
task->tk_status = 0; task->tk_action = call_bind; return; |
012da158f SUNRPC: Use soft ... |
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 |
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... |
1205 |
default: |
46121cf7d SUNRPC: fix print... |
1206 1207 |
dprintk("RPC: %5u unrecognized rpcbind error (%d) ", |
da3518780 [PATCH] RPC: prop... |
1208 |
task->tk_pid, -task->tk_status); |
da3518780 [PATCH] RPC: prop... |
1209 1210 1211 1212 |
} rpc_exit(task, status); return; |
da45828e2 SUNRPC: Clean up ... |
1213 1214 |
retry_timeout: task->tk_action = call_timeout; |
da3518780 [PATCH] RPC: prop... |
1215 1216 1217 1218 |
} /* * 4b. Connect to the RPC server |
1da177e4c Linux-2.6.12-rc2 |
1219 1220 1221 1222 |
*/ static void call_connect(struct rpc_task *task) { |
da3518780 [PATCH] RPC: prop... |
1223 |
struct rpc_xprt *xprt = task->tk_xprt; |
1da177e4c Linux-2.6.12-rc2 |
1224 |
|
46121cf7d SUNRPC: fix print... |
1225 1226 |
dprintk("RPC: %5u call_connect xprt %p %s connected ", |
da3518780 [PATCH] RPC: prop... |
1227 1228 |
task->tk_pid, xprt, (xprt_connected(xprt) ? "is" : "is not")); |
1da177e4c Linux-2.6.12-rc2 |
1229 |
|
da3518780 [PATCH] RPC: prop... |
1230 1231 1232 1233 1234 1235 |
task->tk_action = call_transmit; if (!xprt_connected(xprt)) { task->tk_action = call_connect_status; if (task->tk_status < 0) return; xprt_connect(task); |
1da177e4c Linux-2.6.12-rc2 |
1236 |
} |
1da177e4c Linux-2.6.12-rc2 |
1237 1238 1239 |
} /* |
da3518780 [PATCH] RPC: prop... |
1240 |
* 4c. Sort out connect result |
1da177e4c Linux-2.6.12-rc2 |
1241 1242 1243 1244 1245 1246 |
*/ 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... |
1247 |
dprint_status(task); |
da3518780 [PATCH] RPC: prop... |
1248 |
|
1da177e4c Linux-2.6.12-rc2 |
1249 |
task->tk_status = 0; |
2a4919919 SUNRPC: Return EA... |
1250 |
if (status >= 0 || status == -EAGAIN) { |
1da177e4c Linux-2.6.12-rc2 |
1251 1252 1253 1254 |
clnt->cl_stats->netreconn++; task->tk_action = call_transmit; return; } |
1da177e4c Linux-2.6.12-rc2 |
1255 |
switch (status) { |
da45828e2 SUNRPC: Clean up ... |
1256 1257 1258 |
/* if soft mounted, test if we've timed out */ case -ETIMEDOUT: task->tk_action = call_timeout; |
2a4919919 SUNRPC: Return EA... |
1259 1260 1261 |
break; default: rpc_exit(task, -EIO); |
1da177e4c Linux-2.6.12-rc2 |
1262 1263 1264 1265 1266 1267 1268 1269 1270 |
} } /* * 5. Transmit the RPC request, and wait for reply */ static void call_transmit(struct rpc_task *task) { |
46121cf7d SUNRPC: fix print... |
1271 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1272 1273 1274 1275 1276 1277 1278 |
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 ... |
1279 |
task->tk_action = call_transmit_status; |
1da177e4c Linux-2.6.12-rc2 |
1280 |
/* Encode here so that rpcsec_gss can use correct sequence number. */ |
940e3318c [PATCH] SUNRPC: d... |
1281 |
if (rpc_task_need_encode(task)) { |
e0ab53dea RPC: Ensure that ... |
1282 |
BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); |
b0e1c57ea SUNRPC: Rename "c... |
1283 |
rpc_xdr_encode(task); |
5e5ce5be6 RPC: allow call_e... |
1284 |
/* Did the encode result in an error condition? */ |
8b39f2b41 SUNRPC: Ensure we... |
1285 1286 1287 1288 1289 1290 |
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 ... |
1291 |
return; |
8b39f2b41 SUNRPC: Ensure we... |
1292 |
} |
5e5ce5be6 RPC: allow call_e... |
1293 |
} |
1da177e4c Linux-2.6.12-rc2 |
1294 1295 1296 |
xprt_transmit(task); if (task->tk_status < 0) return; |
e0ab53dea RPC: Ensure that ... |
1297 1298 1299 1300 1301 |
/* * 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... |
1302 |
if (rpc_reply_expected(task)) |
e0ab53dea RPC: Ensure that ... |
1303 1304 |
return; task->tk_action = rpc_exit_task; |
fda139393 SUNRPC: Convert u... |
1305 |
rpc_wake_up_queued_task(&task->tk_xprt->pending, task); |
e0ab53dea RPC: Ensure that ... |
1306 1307 1308 1309 1310 1311 1312 1313 1314 |
} /* * 5a. Handle cleanup after a transmission */ static void call_transmit_status(struct rpc_task *task) { task->tk_action = call_status; |
206a134b4 SUNRPC: Check exp... |
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 |
/* * 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 ... |
1325 1326 1327 1328 |
switch (task->tk_status) { case -EAGAIN: break; default: |
206a134b4 SUNRPC: Check exp... |
1329 |
dprint_status(task); |
15f081ca8 SUNRPC: Avoid an ... |
1330 |
xprt_end_transmit(task); |
09a21c410 SUNRPC: Allow RPC... |
1331 1332 |
rpc_task_force_reencode(task); break; |
15f081ca8 SUNRPC: Avoid an ... |
1333 1334 1335 1336 1337 1338 1339 |
/* * 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 ... |
1340 1341 1342 |
case -EHOSTDOWN: case -EHOSTUNREACH: case -ENETUNREACH: |
09a21c410 SUNRPC: Allow RPC... |
1343 1344 1345 1346 1347 1348 1349 |
if (RPC_IS_SOFTCONN(task)) { xprt_end_transmit(task); rpc_exit(task, task->tk_status); break; } case -ECONNRESET: case -ENOTCONN: |
c8485e4d6 SUNRPC: Handle EC... |
1350 |
case -EPIPE: |
15f081ca8 SUNRPC: Avoid an ... |
1351 1352 |
rpc_task_force_reencode(task); } |
1da177e4c Linux-2.6.12-rc2 |
1353 |
} |
9e00abc3c SUNRPC: sunrpc sh... |
1354 |
#if defined(CONFIG_SUNRPC_BACKCHANNEL) |
55ae1aabf nfs41: Add backch... |
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 |
/* * 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; BUG_ON(task->tk_status != 0); 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); xprt_conditional_disconnect(task->tk_xprt, req->rq_connect_cookie); break; default: /* * We were unable to reply and will have to drop the * request. The server should reconnect and retransmit. */ BUG_ON(task->tk_status == -EAGAIN); 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... |
1421 |
#endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
55ae1aabf nfs41: Add backch... |
1422 |
|
1da177e4c Linux-2.6.12-rc2 |
1423 1424 1425 1426 1427 1428 1429 1430 1431 |
/* * 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_... |
1432 1433 |
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 |
1434 |
|
46121cf7d SUNRPC: fix print... |
1435 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1436 1437 1438 1439 1440 1441 1442 1443 1444 |
status = task->tk_status; if (status >= 0) { task->tk_action = call_decode; return; } task->tk_status = 0; switch(status) { |
76303992b SUNRPC: Handle EN... |
1445 1446 1447 1448 1449 1450 1451 1452 |
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 |
1453 1454 |
case -ETIMEDOUT: task->tk_action = call_timeout; |
241c39b9a RPC: Fix the TCP ... |
1455 |
if (task->tk_client->cl_discrtry) |
7c1d71cf5 SUNRPC: Don't dis... |
1456 1457 |
xprt_conditional_disconnect(task->tk_xprt, req->rq_connect_cookie); |
1da177e4c Linux-2.6.12-rc2 |
1458 |
break; |
c8485e4d6 SUNRPC: Handle EC... |
1459 |
case -ECONNRESET: |
1da177e4c Linux-2.6.12-rc2 |
1460 |
case -ECONNREFUSED: |
35f5a422c SUNRPC: new inter... |
1461 |
rpc_force_rebind(clnt); |
c8485e4d6 SUNRPC: Handle EC... |
1462 1463 1464 |
rpc_delay(task, 3*HZ); case -EPIPE: case -ENOTCONN: |
1da177e4c Linux-2.6.12-rc2 |
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 |
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... |
1475 1476 1477 |
if (clnt->cl_chatty) printk("%s: RPC call returned error %d ", |
1da177e4c Linux-2.6.12-rc2 |
1478 1479 |
clnt->cl_protname, -status); rpc_exit(task, status); |
1da177e4c Linux-2.6.12-rc2 |
1480 1481 1482 1483 |
} } /* |
e0ab53dea RPC: Ensure that ... |
1484 |
* 6a. Handle RPC timeout |
1da177e4c Linux-2.6.12-rc2 |
1485 1486 1487 1488 1489 1490 1491 1492 1493 |
* 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... |
1494 1495 |
dprintk("RPC: %5u call_timeout (minor) ", task->tk_pid); |
1da177e4c Linux-2.6.12-rc2 |
1496 1497 |
goto retry; } |
46121cf7d SUNRPC: fix print... |
1498 1499 |
dprintk("RPC: %5u call_timeout (major) ", task->tk_pid); |
ef759a2e5 SUNRPC: introduce... |
1500 |
task->tk_timeouts++; |
3a28becc3 SUNRPC: soft conn... |
1501 1502 1503 1504 |
if (RPC_IS_SOFTCONN(task)) { rpc_exit(task, -ETIMEDOUT); return; } |
1da177e4c Linux-2.6.12-rc2 |
1505 |
if (RPC_IS_SOFT(task)) { |
b6b6152c4 rpc: bring back c... |
1506 1507 1508 |
if (clnt->cl_chatty) printk(KERN_NOTICE "%s: server %s not responding, timed out ", |
1da177e4c Linux-2.6.12-rc2 |
1509 |
clnt->cl_protname, clnt->cl_server); |
7494d00c7 SUNRPC: Allow RPC... |
1510 1511 1512 1513 |
if (task->tk_flags & RPC_TASK_TIMEOUT) rpc_exit(task, -ETIMEDOUT); else rpc_exit(task, -EIO); |
1da177e4c Linux-2.6.12-rc2 |
1514 1515 |
return; } |
f518e35ae SUNRPC: get rid o... |
1516 |
if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { |
1da177e4c Linux-2.6.12-rc2 |
1517 |
task->tk_flags |= RPC_CALL_MAJORSEEN; |
b6b6152c4 rpc: bring back c... |
1518 1519 1520 |
if (clnt->cl_chatty) printk(KERN_NOTICE "%s: server %s not responding, still trying ", |
1da177e4c Linux-2.6.12-rc2 |
1521 1522 |
clnt->cl_protname, clnt->cl_server); } |
35f5a422c SUNRPC: new inter... |
1523 |
rpc_force_rebind(clnt); |
b48633bd0 SUNRPC: Invalidat... |
1524 1525 1526 1527 1528 |
/* * 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 |
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 |
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... |
1544 |
kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; |
d8ed029d6 [SUNRPC]: trivial... |
1545 |
__be32 *p; |
1da177e4c Linux-2.6.12-rc2 |
1546 |
|
726fd6ad5 sunrpc: use dprin... |
1547 |
dprint_status(task); |
1da177e4c Linux-2.6.12-rc2 |
1548 |
|
f518e35ae SUNRPC: get rid o... |
1549 |
if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
b6b6152c4 rpc: bring back c... |
1550 1551 1552 1553 |
if (clnt->cl_chatty) printk(KERN_NOTICE "%s: server %s OK ", clnt->cl_protname, clnt->cl_server); |
1da177e4c Linux-2.6.12-rc2 |
1554 1555 |
task->tk_flags &= ~RPC_CALL_MAJORSEEN; } |
43ac3f296 SUNRPC: Fix memor... |
1556 1557 |
/* * Ensure that we see all writes made by xprt_complete_rqst() |
dd2b63d04 nfs41: Rename rq_... |
1558 |
* before it changed req->rq_reply_bytes_recvd. |
43ac3f296 SUNRPC: Fix memor... |
1559 1560 |
*/ smp_rmb(); |
1da177e4c Linux-2.6.12-rc2 |
1561 1562 1563 1564 1565 |
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 ... |
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 |
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... |
1578 |
p = rpc_verify_header(task); |
abbcf28f2 SUNRPC: Yet more ... |
1579 1580 1581 1582 |
if (IS_ERR(p)) { if (p == ERR_PTR(-EAGAIN)) goto out_retry; return; |
1da177e4c Linux-2.6.12-rc2 |
1583 |
} |
abbcf28f2 SUNRPC: Yet more ... |
1584 |
task->tk_action = rpc_exit_task; |
1da177e4c Linux-2.6.12-rc2 |
1585 |
|
6d5fcb5a5 SUNRPC: Remove BK... |
1586 |
if (decode) { |
1da177e4c Linux-2.6.12-rc2 |
1587 1588 |
task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, task->tk_msg.rpc_resp); |
6d5fcb5a5 SUNRPC: Remove BK... |
1589 |
} |
46121cf7d SUNRPC: fix print... |
1590 1591 1592 |
dprintk("RPC: %5u call_decode result %d ", task->tk_pid, task->tk_status); |
1da177e4c Linux-2.6.12-rc2 |
1593 1594 |
return; out_retry: |
1da177e4c Linux-2.6.12-rc2 |
1595 |
task->tk_status = 0; |
b0e1c57ea SUNRPC: Rename "c... |
1596 |
/* Note: rpc_verify_header() may have freed the RPC slot */ |
24b74bf0c SUNRPC: Fix a bug... |
1597 |
if (task->tk_rqstp == req) { |
dd2b63d04 nfs41: Rename rq_... |
1598 |
req->rq_reply_bytes_recvd = req->rq_rcv_buf.len = 0; |
24b74bf0c SUNRPC: Fix a bug... |
1599 |
if (task->tk_client->cl_discrtry) |
7c1d71cf5 SUNRPC: Don't dis... |
1600 1601 |
xprt_conditional_disconnect(task->tk_xprt, req->rq_connect_cookie); |
24b74bf0c SUNRPC: Fix a bug... |
1602 |
} |
1da177e4c Linux-2.6.12-rc2 |
1603 |
} |
d8ed029d6 [SUNRPC]: trivial... |
1604 |
static __be32 * |
b0e1c57ea SUNRPC: Rename "c... |
1605 |
rpc_encode_header(struct rpc_task *task) |
1da177e4c Linux-2.6.12-rc2 |
1606 1607 |
{ struct rpc_clnt *clnt = task->tk_client; |
1da177e4c Linux-2.6.12-rc2 |
1608 |
struct rpc_rqst *req = task->tk_rqstp; |
d8ed029d6 [SUNRPC]: trivial... |
1609 |
__be32 *p = req->rq_svec[0].iov_base; |
1da177e4c Linux-2.6.12-rc2 |
1610 1611 |
/* FIXME: check buffer size? */ |
808012fbb [PATCH] RPC: skip... |
1612 1613 |
p = xprt_skip_transport_header(task->tk_xprt, p); |
1da177e4c Linux-2.6.12-rc2 |
1614 1615 1616 1617 1618 1619 |
*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... |
1620 1621 1622 |
p = rpcauth_marshcred(task, p); req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p); return p; |
1da177e4c Linux-2.6.12-rc2 |
1623 |
} |
d8ed029d6 [SUNRPC]: trivial... |
1624 |
static __be32 * |
b0e1c57ea SUNRPC: Rename "c... |
1625 |
rpc_verify_header(struct rpc_task *task) |
1da177e4c Linux-2.6.12-rc2 |
1626 1627 1628 |
{ struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; int len = task->tk_rqstp->rq_rcv_buf.len >> 2; |
d8ed029d6 [SUNRPC]: trivial... |
1629 1630 |
__be32 *p = iov->iov_base; u32 n; |
1da177e4c Linux-2.6.12-rc2 |
1631 |
int error = -EACCES; |
e8896495b NFS: Check length... |
1632 1633 1634 1635 1636 1637 |
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 ... |
1638 |
dprintk("RPC: %5u %s: XDR representation not a multiple of" |
0dc47877a net: replace rema... |
1639 1640 |
" 4 bytes: 0x%x ", task->tk_pid, __func__, |
8a702bbb7 SUNRPC: Suppress ... |
1641 |
task->tk_rqstp->rq_rcv_buf.len); |
e8896495b NFS: Check length... |
1642 1643 |
goto out_eio; } |
1da177e4c Linux-2.6.12-rc2 |
1644 1645 |
if ((len -= 3) < 0) goto out_overflow; |
1da177e4c Linux-2.6.12-rc2 |
1646 |
|
f4a2e418b nfs41: Process th... |
1647 |
p += 1; /* skip XID */ |
1da177e4c Linux-2.6.12-rc2 |
1648 |
if ((n = ntohl(*p++)) != RPC_REPLY) { |
8a702bbb7 SUNRPC: Suppress ... |
1649 1650 |
dprintk("RPC: %5u %s: not an RPC reply: %x ", |
f4a2e418b nfs41: Process th... |
1651 |
task->tk_pid, __func__, n); |
abbcf28f2 SUNRPC: Yet more ... |
1652 |
goto out_garbage; |
1da177e4c Linux-2.6.12-rc2 |
1653 |
} |
f4a2e418b nfs41: Process th... |
1654 |
|
1da177e4c Linux-2.6.12-rc2 |
1655 1656 1657 1658 |
if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { if (--len < 0) goto out_overflow; switch ((n = ntohl(*p++))) { |
89f0e4fea sunrpc: Reduce sw... |
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 |
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 |
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 |
} 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... |
1684 1685 |
dprintk("RPC: %5u %s: retry stale creds ", |
0dc47877a net: replace rema... |
1686 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
1687 |
rpcauth_invalcred(task); |
220bcc2af SUNRPC: Don't cal... |
1688 1689 |
/* Ensure we obtain a new XID! */ xprt_release(task); |
118df3d17 SUNRPC: After cal... |
1690 |
task->tk_action = call_reserve; |
abbcf28f2 SUNRPC: Yet more ... |
1691 |
goto out_retry; |
1da177e4c Linux-2.6.12-rc2 |
1692 1693 1694 1695 1696 1697 |
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... |
1698 1699 |
dprintk("RPC: %5u %s: retry garbled creds ", |
0dc47877a net: replace rema... |
1700 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
1701 |
task->tk_action = call_bind; |
abbcf28f2 SUNRPC: Yet more ... |
1702 |
goto out_retry; |
1da177e4c Linux-2.6.12-rc2 |
1703 |
case RPC_AUTH_TOOWEAK: |
b0e1c57ea SUNRPC: Rename "c... |
1704 |
printk(KERN_NOTICE "RPC: server %s requires stronger " |
1356b8c28 SUNRPC: more verb... |
1705 1706 |
"authentication. ", task->tk_client->cl_server); |
1da177e4c Linux-2.6.12-rc2 |
1707 1708 |
break; default: |
8a702bbb7 SUNRPC: Suppress ... |
1709 1710 |
dprintk("RPC: %5u %s: unknown auth error: %x ", |
0dc47877a net: replace rema... |
1711 |
task->tk_pid, __func__, n); |
1da177e4c Linux-2.6.12-rc2 |
1712 1713 |
error = -EIO; } |
46121cf7d SUNRPC: fix print... |
1714 1715 |
dprintk("RPC: %5u %s: call rejected %d ", |
0dc47877a net: replace rema... |
1716 |
task->tk_pid, __func__, n); |
1da177e4c Linux-2.6.12-rc2 |
1717 1718 1719 |
goto out_err; } if (!(p = rpcauth_checkverf(task, p))) { |
8a702bbb7 SUNRPC: Suppress ... |
1720 1721 |
dprintk("RPC: %5u %s: auth check failed ", |
0dc47877a net: replace rema... |
1722 |
task->tk_pid, __func__); |
abbcf28f2 SUNRPC: Yet more ... |
1723 |
goto out_garbage; /* bad verifier, retry */ |
1da177e4c Linux-2.6.12-rc2 |
1724 |
} |
d8ed029d6 [SUNRPC]: trivial... |
1725 |
len = p - (__be32 *)iov->iov_base - 1; |
1da177e4c Linux-2.6.12-rc2 |
1726 1727 1728 1729 1730 1731 |
if (len < 0) goto out_overflow; switch ((n = ntohl(*p++))) { case RPC_SUCCESS: return p; case RPC_PROG_UNAVAIL: |
46121cf7d SUNRPC: fix print... |
1732 1733 |
dprintk("RPC: %5u %s: program %u is unsupported by server %s ", |
0dc47877a net: replace rema... |
1734 |
task->tk_pid, __func__, |
1da177e4c Linux-2.6.12-rc2 |
1735 1736 |
(unsigned int)task->tk_client->cl_prog, task->tk_client->cl_server); |
cdf477068 [PATCH] RPC: Retu... |
1737 1738 |
error = -EPFNOSUPPORT; goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1739 |
case RPC_PROG_MISMATCH: |
46121cf7d SUNRPC: fix print... |
1740 |
dprintk("RPC: %5u %s: program %u, version %u unsupported by " |
0dc47877a net: replace rema... |
1741 1742 |
"server %s ", task->tk_pid, __func__, |
1da177e4c Linux-2.6.12-rc2 |
1743 1744 1745 |
(unsigned int)task->tk_client->cl_prog, (unsigned int)task->tk_client->cl_vers, task->tk_client->cl_server); |
cdf477068 [PATCH] RPC: Retu... |
1746 1747 |
error = -EPROTONOSUPPORT; goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1748 |
case RPC_PROC_UNAVAIL: |
3748f1e44 SUNRPC: Add a fun... |
1749 |
dprintk("RPC: %5u %s: proc %s unsupported by program %u, " |
46121cf7d SUNRPC: fix print... |
1750 1751 |
"version %u on server %s ", |
0dc47877a net: replace rema... |
1752 |
task->tk_pid, __func__, |
3748f1e44 SUNRPC: Add a fun... |
1753 |
rpc_proc_name(task), |
1da177e4c Linux-2.6.12-rc2 |
1754 1755 1756 |
task->tk_client->cl_prog, task->tk_client->cl_vers, task->tk_client->cl_server); |
cdf477068 [PATCH] RPC: Retu... |
1757 1758 |
error = -EOPNOTSUPP; goto out_err; |
1da177e4c Linux-2.6.12-rc2 |
1759 |
case RPC_GARBAGE_ARGS: |
46121cf7d SUNRPC: fix print... |
1760 1761 |
dprintk("RPC: %5u %s: server saw garbage ", |
0dc47877a net: replace rema... |
1762 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
1763 1764 |
break; /* retry */ default: |
8a702bbb7 SUNRPC: Suppress ... |
1765 1766 |
dprintk("RPC: %5u %s: server accept status: %x ", |
0dc47877a net: replace rema... |
1767 |
task->tk_pid, __func__, n); |
1da177e4c Linux-2.6.12-rc2 |
1768 1769 |
/* Also retry */ } |
abbcf28f2 SUNRPC: Yet more ... |
1770 |
out_garbage: |
1da177e4c Linux-2.6.12-rc2 |
1771 1772 1773 |
task->tk_client->cl_stats->rpcgarbage++; if (task->tk_garb_retry) { task->tk_garb_retry--; |
46121cf7d SUNRPC: fix print... |
1774 1775 |
dprintk("RPC: %5u %s: retrying ", |
0dc47877a net: replace rema... |
1776 |
task->tk_pid, __func__); |
1da177e4c Linux-2.6.12-rc2 |
1777 |
task->tk_action = call_bind; |
abbcf28f2 SUNRPC: Yet more ... |
1778 1779 |
out_retry: return ERR_PTR(-EAGAIN); |
1da177e4c Linux-2.6.12-rc2 |
1780 |
} |
1da177e4c Linux-2.6.12-rc2 |
1781 1782 1783 1784 |
out_eio: error = -EIO; out_err: rpc_exit(task, error); |
8a702bbb7 SUNRPC: Suppress ... |
1785 1786 |
dprintk("RPC: %5u %s: call failed with error %d ", task->tk_pid, |
0dc47877a net: replace rema... |
1787 |
__func__, error); |
abbcf28f2 SUNRPC: Yet more ... |
1788 |
return ERR_PTR(error); |
1da177e4c Linux-2.6.12-rc2 |
1789 |
out_overflow: |
8a702bbb7 SUNRPC: Suppress ... |
1790 1791 |
dprintk("RPC: %5u %s: server reply was truncated. ", task->tk_pid, |
0dc47877a net: replace rema... |
1792 |
__func__); |
abbcf28f2 SUNRPC: Yet more ... |
1793 |
goto out_garbage; |
1da177e4c Linux-2.6.12-rc2 |
1794 |
} |
5ee0ed7d3 [PATCH] RPC: Make... |
1795 |
|
9f06c719f SUNRPC: New xdr_s... |
1796 |
static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
5ee0ed7d3 [PATCH] RPC: Make... |
1797 |
{ |
5ee0ed7d3 [PATCH] RPC: Make... |
1798 |
} |
bf2695516 SUNRPC: New xdr_s... |
1799 |
static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
5ee0ed7d3 [PATCH] RPC: Make... |
1800 1801 1802 1803 1804 1805 1806 1807 |
{ return 0; } static struct rpc_procinfo rpcproc_null = { .p_encode = rpcproc_encode_null, .p_decode = rpcproc_decode_null, }; |
caabea8a5 SUNRPC: Use soft ... |
1808 |
static int rpc_ping(struct rpc_clnt *clnt) |
5ee0ed7d3 [PATCH] RPC: Make... |
1809 1810 1811 1812 1813 1814 |
{ struct rpc_message msg = { .rpc_proc = &rpcproc_null, }; int err; msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0); |
caabea8a5 SUNRPC: Use soft ... |
1815 |
err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN); |
5ee0ed7d3 [PATCH] RPC: Make... |
1816 1817 1818 |
put_rpccred(msg.rpc_cred); return err; } |
188fef11d SUNRPC: Move rpc_... |
1819 |
|
5e1550d6a SUNRPC: Add the h... |
1820 1821 1822 1823 1824 1825 |
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... |
1826 1827 1828 1829 1830 1831 |
struct rpc_task_setup task_setup_data = { .rpc_client = clnt, .rpc_message = &msg, .callback_ops = &rpc_default_ops, .flags = flags, }; |
c970aa85e SUNRPC: Clean up ... |
1832 |
return rpc_run_task(&task_setup_data); |
5e1550d6a SUNRPC: Add the h... |
1833 |
} |
e8914c65f SUNRPC: Restrict ... |
1834 |
EXPORT_SYMBOL_GPL(rpc_call_null); |
5e1550d6a SUNRPC: Add the h... |
1835 |
|
188fef11d SUNRPC: Move rpc_... |
1836 |
#ifdef RPC_DEBUG |
68a23ee94 SUNRPC: Don't dis... |
1837 1838 |
static void rpc_show_header(void) { |
cb3997b5a SUNRPC: Display s... |
1839 1840 1841 |
printk(KERN_INFO "-pid- flgs status -client- --rqstp- " "-timeout ---ops-- "); |
68a23ee94 SUNRPC: Don't dis... |
1842 |
} |
38e886e0c SUNRPC: Refactor ... |
1843 1844 1845 1846 |
static void rpc_show_task(const struct rpc_clnt *clnt, const struct rpc_task *task) { const char *rpc_waitq = "none"; |
38e886e0c SUNRPC: Refactor ... |
1847 1848 1849 |
if (RPC_IS_QUEUED(task)) rpc_waitq = rpc_qname(task->tk_waitqueue); |
b3bcedadf net/sunrpc/clnt.c... |
1850 1851 |
printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s ", |
cb3997b5a SUNRPC: Display s... |
1852 1853 1854 |
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... |
1855 |
task->tk_action, rpc_waitq); |
38e886e0c SUNRPC: Refactor ... |
1856 |
} |
188fef11d SUNRPC: Move rpc_... |
1857 1858 1859 |
void rpc_show_tasks(void) { struct rpc_clnt *clnt; |
38e886e0c SUNRPC: Refactor ... |
1860 |
struct rpc_task *task; |
68a23ee94 SUNRPC: Don't dis... |
1861 |
int header = 0; |
188fef11d SUNRPC: Move rpc_... |
1862 1863 |
spin_lock(&rpc_client_lock); |
188fef11d SUNRPC: Move rpc_... |
1864 |
list_for_each_entry(clnt, &all_clients, cl_clients) { |
188fef11d SUNRPC: Move rpc_... |
1865 |
spin_lock(&clnt->cl_lock); |
38e886e0c SUNRPC: Refactor ... |
1866 |
list_for_each_entry(task, &clnt->cl_tasks, tk_task) { |
68a23ee94 SUNRPC: Don't dis... |
1867 1868 1869 1870 |
if (!header) { rpc_show_header(); header++; } |
38e886e0c SUNRPC: Refactor ... |
1871 |
rpc_show_task(clnt, task); |
188fef11d SUNRPC: Move rpc_... |
1872 1873 1874 |
} spin_unlock(&clnt->cl_lock); } |
188fef11d SUNRPC: Move rpc_... |
1875 1876 1877 |
spin_unlock(&rpc_client_lock); } #endif |