diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 03:54:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 03:54:24 -0500 |
commit | 85004cc367abc000aa36c0d0e270ab609a68b0cb (patch) | |
tree | 5739aae778d67b6d119fe5c668313fc2823e9836 /net | |
parent | 149a051f82d2b3860fe32fa182dbc83a66274894 (diff) | |
parent | 3fbd67ad61f6d5a09ea717b56c50bc5c3d8042a8 (diff) |
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: (118 commits)
NFSv4: Iterate through all nfs_clients when the server recalls a delegation
NFSv4: Deal more correctly with duplicate delegations
NFS: Fix a potential race between umount and nfs_access_cache_shrinker()
NFS: Add an asynchronous delegreturn operation for use in nfs_clear_inode
nfs: convert NFS_*(inode) helpers to static inline
nfs: obliterate NFS_FLAGS macro
NFS: Address memory leaks in the NFS client mount option parser
nfs4: allow nfsv4 acls on non-regular-files
NFS: Optimise away the sigmask code in aio/dio reads and writes
SUNRPC: Don't bother changing the sigmask for asynchronous RPC calls
SUNRPC: rpcb_getport_sync() passes incorrect address size to rpc_create()
SUNRPC: Clean up block comment preceding rpcb_getport_sync()
SUNRPC: Use appropriate argument types in rpcb client
SUNRPC: rpcb_getport_sync() should use built-in hostname generator
SUNRPC: Clean up functions that free address_strings array
NFS: NFS version number is unsigned
NLM: Fix a bogus 'return' in nlmclnt_rpc_release
NLM: Introduce an arguments structure for nlmclnt_init()
NLM/NFS: Use cached nlm_host when calling nlmclnt_proc()
NFS: Invoke nlmclnt_init during NFS mount processing
...
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/auth.c | 13 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 13 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 188 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 59 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 119 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 106 | ||||
-rw-r--r-- | net/sunrpc/socklib.c | 2 | ||||
-rw-r--r-- | net/sunrpc/stats.c | 8 | ||||
-rw-r--r-- | net/sunrpc/sunrpc_syms.c | 66 | ||||
-rw-r--r-- | net/sunrpc/sysctl.c | 7 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 16 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 54 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/rpc_rdma.c | 8 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/transport.c | 27 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 8 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 226 |
16 files changed, 526 insertions, 394 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 1ea27559b1de..bcd9abdb031c 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -51,6 +51,7 @@ rpcauth_register(const struct rpc_authops *ops) | |||
51 | spin_unlock(&rpc_authflavor_lock); | 51 | spin_unlock(&rpc_authflavor_lock); |
52 | return ret; | 52 | return ret; |
53 | } | 53 | } |
54 | EXPORT_SYMBOL_GPL(rpcauth_register); | ||
54 | 55 | ||
55 | int | 56 | int |
56 | rpcauth_unregister(const struct rpc_authops *ops) | 57 | rpcauth_unregister(const struct rpc_authops *ops) |
@@ -68,6 +69,7 @@ rpcauth_unregister(const struct rpc_authops *ops) | |||
68 | spin_unlock(&rpc_authflavor_lock); | 69 | spin_unlock(&rpc_authflavor_lock); |
69 | return ret; | 70 | return ret; |
70 | } | 71 | } |
72 | EXPORT_SYMBOL_GPL(rpcauth_unregister); | ||
71 | 73 | ||
72 | struct rpc_auth * | 74 | struct rpc_auth * |
73 | rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) | 75 | rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) |
@@ -102,6 +104,7 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) | |||
102 | out: | 104 | out: |
103 | return auth; | 105 | return auth; |
104 | } | 106 | } |
107 | EXPORT_SYMBOL_GPL(rpcauth_create); | ||
105 | 108 | ||
106 | void | 109 | void |
107 | rpcauth_release(struct rpc_auth *auth) | 110 | rpcauth_release(struct rpc_auth *auth) |
@@ -151,6 +154,7 @@ rpcauth_init_credcache(struct rpc_auth *auth) | |||
151 | auth->au_credcache = new; | 154 | auth->au_credcache = new; |
152 | return 0; | 155 | return 0; |
153 | } | 156 | } |
157 | EXPORT_SYMBOL_GPL(rpcauth_init_credcache); | ||
154 | 158 | ||
155 | /* | 159 | /* |
156 | * Destroy a list of credentials | 160 | * Destroy a list of credentials |
@@ -213,6 +217,7 @@ rpcauth_destroy_credcache(struct rpc_auth *auth) | |||
213 | kfree(cache); | 217 | kfree(cache); |
214 | } | 218 | } |
215 | } | 219 | } |
220 | EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache); | ||
216 | 221 | ||
217 | /* | 222 | /* |
218 | * Remove stale credentials. Avoid sleeping inside the loop. | 223 | * Remove stale credentials. Avoid sleeping inside the loop. |
@@ -332,6 +337,7 @@ found: | |||
332 | out: | 337 | out: |
333 | return cred; | 338 | return cred; |
334 | } | 339 | } |
340 | EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache); | ||
335 | 341 | ||
336 | struct rpc_cred * | 342 | struct rpc_cred * |
337 | rpcauth_lookupcred(struct rpc_auth *auth, int flags) | 343 | rpcauth_lookupcred(struct rpc_auth *auth, int flags) |
@@ -350,6 +356,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags) | |||
350 | put_group_info(acred.group_info); | 356 | put_group_info(acred.group_info); |
351 | return ret; | 357 | return ret; |
352 | } | 358 | } |
359 | EXPORT_SYMBOL_GPL(rpcauth_lookupcred); | ||
353 | 360 | ||
354 | void | 361 | void |
355 | rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, | 362 | rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, |
@@ -366,7 +373,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, | |||
366 | #endif | 373 | #endif |
367 | cred->cr_uid = acred->uid; | 374 | cred->cr_uid = acred->uid; |
368 | } | 375 | } |
369 | EXPORT_SYMBOL(rpcauth_init_cred); | 376 | EXPORT_SYMBOL_GPL(rpcauth_init_cred); |
370 | 377 | ||
371 | struct rpc_cred * | 378 | struct rpc_cred * |
372 | rpcauth_bindcred(struct rpc_task *task) | 379 | rpcauth_bindcred(struct rpc_task *task) |
@@ -378,6 +385,7 @@ rpcauth_bindcred(struct rpc_task *task) | |||
378 | .group_info = current->group_info, | 385 | .group_info = current->group_info, |
379 | }; | 386 | }; |
380 | struct rpc_cred *ret; | 387 | struct rpc_cred *ret; |
388 | sigset_t oldset; | ||
381 | int flags = 0; | 389 | int flags = 0; |
382 | 390 | ||
383 | dprintk("RPC: %5u looking up %s cred\n", | 391 | dprintk("RPC: %5u looking up %s cred\n", |
@@ -385,7 +393,9 @@ rpcauth_bindcred(struct rpc_task *task) | |||
385 | get_group_info(acred.group_info); | 393 | get_group_info(acred.group_info); |
386 | if (task->tk_flags & RPC_TASK_ROOTCREDS) | 394 | if (task->tk_flags & RPC_TASK_ROOTCREDS) |
387 | flags |= RPCAUTH_LOOKUP_ROOTCREDS; | 395 | flags |= RPCAUTH_LOOKUP_ROOTCREDS; |
396 | rpc_clnt_sigmask(task->tk_client, &oldset); | ||
388 | ret = auth->au_ops->lookup_cred(auth, &acred, flags); | 397 | ret = auth->au_ops->lookup_cred(auth, &acred, flags); |
398 | rpc_clnt_sigunmask(task->tk_client, &oldset); | ||
389 | if (!IS_ERR(ret)) | 399 | if (!IS_ERR(ret)) |
390 | task->tk_msg.rpc_cred = ret; | 400 | task->tk_msg.rpc_cred = ret; |
391 | else | 401 | else |
@@ -435,6 +445,7 @@ need_lock: | |||
435 | out_destroy: | 445 | out_destroy: |
436 | cred->cr_ops->crdestroy(cred); | 446 | cred->cr_ops->crdestroy(cred); |
437 | } | 447 | } |
448 | EXPORT_SYMBOL_GPL(put_rpccred); | ||
438 | 449 | ||
439 | void | 450 | void |
440 | rpcauth_unbindcred(struct rpc_task *task) | 451 | rpcauth_unbindcred(struct rpc_task *task) |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 1f2d85e869c0..6dac38792288 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -472,16 +472,15 @@ gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, | |||
472 | char __user *dst, size_t buflen) | 472 | char __user *dst, size_t buflen) |
473 | { | 473 | { |
474 | char *data = (char *)msg->data + msg->copied; | 474 | char *data = (char *)msg->data + msg->copied; |
475 | ssize_t mlen = msg->len; | 475 | size_t mlen = min(msg->len, buflen); |
476 | ssize_t left; | 476 | unsigned long left; |
477 | 477 | ||
478 | if (mlen > buflen) | ||
479 | mlen = buflen; | ||
480 | left = copy_to_user(dst, data, mlen); | 478 | left = copy_to_user(dst, data, mlen); |
481 | if (left < 0) { | 479 | if (left == mlen) { |
482 | msg->errno = left; | 480 | msg->errno = -EFAULT; |
483 | return left; | 481 | return -EFAULT; |
484 | } | 482 | } |
483 | |||
485 | mlen -= left; | 484 | mlen -= left; |
486 | msg->copied += mlen; | 485 | msg->copied += mlen; |
487 | msg->errno = 0; | 486 | msg->errno = 0; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 76be83ee4b04..924916ceaa43 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
31 | #include <linux/utsname.h> | 31 | #include <linux/utsname.h> |
32 | #include <linux/workqueue.h> | 32 | #include <linux/workqueue.h> |
33 | #include <linux/in6.h> | ||
33 | 34 | ||
34 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
35 | #include <linux/sunrpc/rpc_pipe_fs.h> | 36 | #include <linux/sunrpc/rpc_pipe_fs.h> |
@@ -121,8 +122,9 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | |||
121 | } | 122 | } |
122 | } | 123 | } |
123 | 124 | ||
124 | static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, struct rpc_program *program, u32 vers, rpc_authflavor_t flavor) | 125 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
125 | { | 126 | { |
127 | struct rpc_program *program = args->program; | ||
126 | struct rpc_version *version; | 128 | struct rpc_version *version; |
127 | struct rpc_clnt *clnt = NULL; | 129 | struct rpc_clnt *clnt = NULL; |
128 | struct rpc_auth *auth; | 130 | struct rpc_auth *auth; |
@@ -131,13 +133,13 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
131 | 133 | ||
132 | /* sanity check the name before trying to print it */ | 134 | /* sanity check the name before trying to print it */ |
133 | err = -EINVAL; | 135 | err = -EINVAL; |
134 | len = strlen(servname); | 136 | len = strlen(args->servername); |
135 | if (len > RPC_MAXNETNAMELEN) | 137 | if (len > RPC_MAXNETNAMELEN) |
136 | goto out_no_rpciod; | 138 | goto out_no_rpciod; |
137 | len++; | 139 | len++; |
138 | 140 | ||
139 | dprintk("RPC: creating %s client for %s (xprt %p)\n", | 141 | dprintk("RPC: creating %s client for %s (xprt %p)\n", |
140 | program->name, servname, xprt); | 142 | program->name, args->servername, xprt); |
141 | 143 | ||
142 | err = rpciod_up(); | 144 | err = rpciod_up(); |
143 | if (err) | 145 | if (err) |
@@ -145,7 +147,11 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
145 | err = -EINVAL; | 147 | err = -EINVAL; |
146 | if (!xprt) | 148 | if (!xprt) |
147 | goto out_no_xprt; | 149 | goto out_no_xprt; |
148 | if (vers >= program->nrvers || !(version = program->version[vers])) | 150 | |
151 | if (args->version >= program->nrvers) | ||
152 | goto out_err; | ||
153 | version = program->version[args->version]; | ||
154 | if (version == NULL) | ||
149 | goto out_err; | 155 | goto out_err; |
150 | 156 | ||
151 | err = -ENOMEM; | 157 | err = -ENOMEM; |
@@ -157,12 +163,12 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
157 | clnt->cl_server = clnt->cl_inline_name; | 163 | clnt->cl_server = clnt->cl_inline_name; |
158 | if (len > sizeof(clnt->cl_inline_name)) { | 164 | if (len > sizeof(clnt->cl_inline_name)) { |
159 | char *buf = kmalloc(len, GFP_KERNEL); | 165 | char *buf = kmalloc(len, GFP_KERNEL); |
160 | if (buf != 0) | 166 | if (buf != NULL) |
161 | clnt->cl_server = buf; | 167 | clnt->cl_server = buf; |
162 | else | 168 | else |
163 | len = sizeof(clnt->cl_inline_name); | 169 | len = sizeof(clnt->cl_inline_name); |
164 | } | 170 | } |
165 | strlcpy(clnt->cl_server, servname, len); | 171 | strlcpy(clnt->cl_server, args->servername, len); |
166 | 172 | ||
167 | clnt->cl_xprt = xprt; | 173 | clnt->cl_xprt = xprt; |
168 | clnt->cl_procinfo = version->procs; | 174 | clnt->cl_procinfo = version->procs; |
@@ -182,8 +188,15 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
182 | if (!xprt_bound(clnt->cl_xprt)) | 188 | if (!xprt_bound(clnt->cl_xprt)) |
183 | clnt->cl_autobind = 1; | 189 | clnt->cl_autobind = 1; |
184 | 190 | ||
191 | clnt->cl_timeout = xprt->timeout; | ||
192 | if (args->timeout != NULL) { | ||
193 | memcpy(&clnt->cl_timeout_default, args->timeout, | ||
194 | sizeof(clnt->cl_timeout_default)); | ||
195 | clnt->cl_timeout = &clnt->cl_timeout_default; | ||
196 | } | ||
197 | |||
185 | clnt->cl_rtt = &clnt->cl_rtt_default; | 198 | clnt->cl_rtt = &clnt->cl_rtt_default; |
186 | rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval); | 199 | rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); |
187 | 200 | ||
188 | kref_init(&clnt->cl_kref); | 201 | kref_init(&clnt->cl_kref); |
189 | 202 | ||
@@ -191,10 +204,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
191 | if (err < 0) | 204 | if (err < 0) |
192 | goto out_no_path; | 205 | goto out_no_path; |
193 | 206 | ||
194 | auth = rpcauth_create(flavor, clnt); | 207 | auth = rpcauth_create(args->authflavor, clnt); |
195 | if (IS_ERR(auth)) { | 208 | if (IS_ERR(auth)) { |
196 | printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", | 209 | printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", |
197 | flavor); | 210 | args->authflavor); |
198 | err = PTR_ERR(auth); | 211 | err = PTR_ERR(auth); |
199 | goto out_no_auth; | 212 | goto out_no_auth; |
200 | } | 213 | } |
@@ -245,9 +258,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
245 | .srcaddr = args->saddress, | 258 | .srcaddr = args->saddress, |
246 | .dstaddr = args->address, | 259 | .dstaddr = args->address, |
247 | .addrlen = args->addrsize, | 260 | .addrlen = args->addrsize, |
248 | .timeout = args->timeout | ||
249 | }; | 261 | }; |
250 | char servername[20]; | 262 | char servername[48]; |
251 | 263 | ||
252 | xprt = xprt_create_transport(&xprtargs); | 264 | xprt = xprt_create_transport(&xprtargs); |
253 | if (IS_ERR(xprt)) | 265 | if (IS_ERR(xprt)) |
@@ -258,13 +270,34 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
258 | * up a string representation of the passed-in address. | 270 | * up a string representation of the passed-in address. |
259 | */ | 271 | */ |
260 | if (args->servername == NULL) { | 272 | if (args->servername == NULL) { |
261 | struct sockaddr_in *addr = | 273 | servername[0] = '\0'; |
262 | (struct sockaddr_in *) args->address; | 274 | switch (args->address->sa_family) { |
263 | snprintf(servername, sizeof(servername), NIPQUAD_FMT, | 275 | case AF_INET: { |
264 | NIPQUAD(addr->sin_addr.s_addr)); | 276 | struct sockaddr_in *sin = |
277 | (struct sockaddr_in *)args->address; | ||
278 | snprintf(servername, sizeof(servername), NIPQUAD_FMT, | ||
279 | NIPQUAD(sin->sin_addr.s_addr)); | ||
280 | break; | ||
281 | } | ||
282 | case AF_INET6: { | ||
283 | struct sockaddr_in6 *sin = | ||
284 | (struct sockaddr_in6 *)args->address; | ||
285 | snprintf(servername, sizeof(servername), NIP6_FMT, | ||
286 | NIP6(sin->sin6_addr)); | ||
287 | break; | ||
288 | } | ||
289 | default: | ||
290 | /* caller wants default server name, but | ||
291 | * address family isn't recognized. */ | ||
292 | return ERR_PTR(-EINVAL); | ||
293 | } | ||
265 | args->servername = servername; | 294 | args->servername = servername; |
266 | } | 295 | } |
267 | 296 | ||
297 | xprt = xprt_create_transport(&xprtargs); | ||
298 | if (IS_ERR(xprt)) | ||
299 | return (struct rpc_clnt *)xprt; | ||
300 | |||
268 | /* | 301 | /* |
269 | * By default, kernel RPC client connects from a reserved port. | 302 | * By default, kernel RPC client connects from a reserved port. |
270 | * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, | 303 | * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, |
@@ -275,8 +308,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
275 | if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) | 308 | if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) |
276 | xprt->resvport = 0; | 309 | xprt->resvport = 0; |
277 | 310 | ||
278 | clnt = rpc_new_client(xprt, args->servername, args->program, | 311 | clnt = rpc_new_client(args, xprt); |
279 | args->version, args->authflavor); | ||
280 | if (IS_ERR(clnt)) | 312 | if (IS_ERR(clnt)) |
281 | return clnt; | 313 | return clnt; |
282 | 314 | ||
@@ -322,7 +354,7 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
322 | new->cl_autobind = 0; | 354 | new->cl_autobind = 0; |
323 | INIT_LIST_HEAD(&new->cl_tasks); | 355 | INIT_LIST_HEAD(&new->cl_tasks); |
324 | spin_lock_init(&new->cl_lock); | 356 | spin_lock_init(&new->cl_lock); |
325 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); | 357 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval); |
326 | new->cl_metrics = rpc_alloc_iostats(clnt); | 358 | new->cl_metrics = rpc_alloc_iostats(clnt); |
327 | if (new->cl_metrics == NULL) | 359 | if (new->cl_metrics == NULL) |
328 | goto out_no_stats; | 360 | goto out_no_stats; |
@@ -345,6 +377,7 @@ out_no_clnt: | |||
345 | dprintk("RPC: %s: returned error %d\n", __FUNCTION__, err); | 377 | dprintk("RPC: %s: returned error %d\n", __FUNCTION__, err); |
346 | return ERR_PTR(err); | 378 | return ERR_PTR(err); |
347 | } | 379 | } |
380 | EXPORT_SYMBOL_GPL(rpc_clone_client); | ||
348 | 381 | ||
349 | /* | 382 | /* |
350 | * Properly shut down an RPC client, terminating all outstanding | 383 | * Properly shut down an RPC client, terminating all outstanding |
@@ -363,6 +396,7 @@ void rpc_shutdown_client(struct rpc_clnt *clnt) | |||
363 | 396 | ||
364 | rpc_release_client(clnt); | 397 | rpc_release_client(clnt); |
365 | } | 398 | } |
399 | EXPORT_SYMBOL_GPL(rpc_shutdown_client); | ||
366 | 400 | ||
367 | /* | 401 | /* |
368 | * Free an RPC client | 402 | * Free an RPC client |
@@ -467,6 +501,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, | |||
467 | out: | 501 | out: |
468 | return clnt; | 502 | return clnt; |
469 | } | 503 | } |
504 | EXPORT_SYMBOL_GPL(rpc_bind_new_program); | ||
470 | 505 | ||
471 | /* | 506 | /* |
472 | * Default callback for async RPC calls | 507 | * Default callback for async RPC calls |
@@ -498,12 +533,12 @@ static void rpc_save_sigmask(sigset_t *oldset, int intr) | |||
498 | sigprocmask(SIG_BLOCK, &sigmask, oldset); | 533 | sigprocmask(SIG_BLOCK, &sigmask, oldset); |
499 | } | 534 | } |
500 | 535 | ||
501 | static inline void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset) | 536 | static void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset) |
502 | { | 537 | { |
503 | rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task)); | 538 | rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task)); |
504 | } | 539 | } |
505 | 540 | ||
506 | static inline void rpc_restore_sigmask(sigset_t *oldset) | 541 | static void rpc_restore_sigmask(sigset_t *oldset) |
507 | { | 542 | { |
508 | sigprocmask(SIG_SETMASK, oldset, NULL); | 543 | sigprocmask(SIG_SETMASK, oldset, NULL); |
509 | } | 544 | } |
@@ -512,45 +547,49 @@ void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset) | |||
512 | { | 547 | { |
513 | rpc_save_sigmask(oldset, clnt->cl_intr); | 548 | rpc_save_sigmask(oldset, clnt->cl_intr); |
514 | } | 549 | } |
550 | EXPORT_SYMBOL_GPL(rpc_clnt_sigmask); | ||
515 | 551 | ||
516 | void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset) | 552 | void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset) |
517 | { | 553 | { |
518 | rpc_restore_sigmask(oldset); | 554 | rpc_restore_sigmask(oldset); |
519 | } | 555 | } |
556 | EXPORT_SYMBOL_GPL(rpc_clnt_sigunmask); | ||
520 | 557 | ||
521 | static | 558 | /** |
522 | struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt, | 559 | * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it |
523 | struct rpc_message *msg, | 560 | * @task_setup_data: pointer to task initialisation data |
524 | int flags, | 561 | */ |
525 | const struct rpc_call_ops *ops, | 562 | struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data) |
526 | void *data) | ||
527 | { | 563 | { |
528 | struct rpc_task *task, *ret; | 564 | struct rpc_task *task, *ret; |
529 | sigset_t oldset; | 565 | sigset_t oldset; |
530 | 566 | ||
531 | task = rpc_new_task(clnt, flags, ops, data); | 567 | task = rpc_new_task(task_setup_data); |
532 | if (task == NULL) { | 568 | if (task == NULL) { |
533 | rpc_release_calldata(ops, data); | 569 | rpc_release_calldata(task_setup_data->callback_ops, |
534 | return ERR_PTR(-ENOMEM); | 570 | task_setup_data->callback_data); |
571 | ret = ERR_PTR(-ENOMEM); | ||
572 | goto out; | ||
535 | } | 573 | } |
536 | 574 | ||
537 | /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */ | 575 | if (task->tk_status != 0) { |
538 | rpc_task_sigmask(task, &oldset); | 576 | ret = ERR_PTR(task->tk_status); |
539 | if (msg != NULL) { | 577 | rpc_put_task(task); |
540 | rpc_call_setup(task, msg, 0); | 578 | goto out; |
541 | if (task->tk_status != 0) { | ||
542 | ret = ERR_PTR(task->tk_status); | ||
543 | rpc_put_task(task); | ||
544 | goto out; | ||
545 | } | ||
546 | } | 579 | } |
547 | atomic_inc(&task->tk_count); | 580 | atomic_inc(&task->tk_count); |
548 | rpc_execute(task); | 581 | /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */ |
582 | if (!RPC_IS_ASYNC(task)) { | ||
583 | rpc_task_sigmask(task, &oldset); | ||
584 | rpc_execute(task); | ||
585 | rpc_restore_sigmask(&oldset); | ||
586 | } else | ||
587 | rpc_execute(task); | ||
549 | ret = task; | 588 | ret = task; |
550 | out: | 589 | out: |
551 | rpc_restore_sigmask(&oldset); | ||
552 | return ret; | 590 | return ret; |
553 | } | 591 | } |
592 | EXPORT_SYMBOL_GPL(rpc_run_task); | ||
554 | 593 | ||
555 | /** | 594 | /** |
556 | * rpc_call_sync - Perform a synchronous RPC call | 595 | * rpc_call_sync - Perform a synchronous RPC call |
@@ -561,17 +600,24 @@ out: | |||
561 | int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) | 600 | int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) |
562 | { | 601 | { |
563 | struct rpc_task *task; | 602 | struct rpc_task *task; |
603 | struct rpc_task_setup task_setup_data = { | ||
604 | .rpc_client = clnt, | ||
605 | .rpc_message = msg, | ||
606 | .callback_ops = &rpc_default_ops, | ||
607 | .flags = flags, | ||
608 | }; | ||
564 | int status; | 609 | int status; |
565 | 610 | ||
566 | BUG_ON(flags & RPC_TASK_ASYNC); | 611 | BUG_ON(flags & RPC_TASK_ASYNC); |
567 | 612 | ||
568 | task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL); | 613 | task = rpc_run_task(&task_setup_data); |
569 | if (IS_ERR(task)) | 614 | if (IS_ERR(task)) |
570 | return PTR_ERR(task); | 615 | return PTR_ERR(task); |
571 | status = task->tk_status; | 616 | status = task->tk_status; |
572 | rpc_put_task(task); | 617 | rpc_put_task(task); |
573 | return status; | 618 | return status; |
574 | } | 619 | } |
620 | EXPORT_SYMBOL_GPL(rpc_call_sync); | ||
575 | 621 | ||
576 | /** | 622 | /** |
577 | * rpc_call_async - Perform an asynchronous RPC call | 623 | * rpc_call_async - Perform an asynchronous RPC call |
@@ -586,45 +632,28 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, | |||
586 | const struct rpc_call_ops *tk_ops, void *data) | 632 | const struct rpc_call_ops *tk_ops, void *data) |
587 | { | 633 | { |
588 | struct rpc_task *task; | 634 | struct rpc_task *task; |
635 | struct rpc_task_setup task_setup_data = { | ||
636 | .rpc_client = clnt, | ||
637 | .rpc_message = msg, | ||
638 | .callback_ops = tk_ops, | ||
639 | .callback_data = data, | ||
640 | .flags = flags|RPC_TASK_ASYNC, | ||
641 | }; | ||
589 | 642 | ||
590 | task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data); | 643 | task = rpc_run_task(&task_setup_data); |
591 | if (IS_ERR(task)) | 644 | if (IS_ERR(task)) |
592 | return PTR_ERR(task); | 645 | return PTR_ERR(task); |
593 | rpc_put_task(task); | 646 | rpc_put_task(task); |
594 | return 0; | 647 | return 0; |
595 | } | 648 | } |
596 | 649 | EXPORT_SYMBOL_GPL(rpc_call_async); | |
597 | /** | ||
598 | * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it | ||
599 | * @clnt: pointer to RPC client | ||
600 | * @flags: RPC flags | ||
601 | * @ops: RPC call ops | ||
602 | * @data: user call data | ||
603 | */ | ||
604 | struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags, | ||
605 | const struct rpc_call_ops *tk_ops, | ||
606 | void *data) | ||
607 | { | ||
608 | return rpc_do_run_task(clnt, NULL, flags, tk_ops, data); | ||
609 | } | ||
610 | EXPORT_SYMBOL(rpc_run_task); | ||
611 | 650 | ||
612 | void | 651 | void |
613 | rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags) | 652 | rpc_call_start(struct rpc_task *task) |
614 | { | 653 | { |
615 | task->tk_msg = *msg; | 654 | task->tk_action = call_start; |
616 | task->tk_flags |= flags; | ||
617 | /* Bind the user cred */ | ||
618 | if (task->tk_msg.rpc_cred != NULL) | ||
619 | rpcauth_holdcred(task); | ||
620 | else | ||
621 | rpcauth_bindcred(task); | ||
622 | |||
623 | if (task->tk_status == 0) | ||
624 | task->tk_action = call_start; | ||
625 | else | ||
626 | task->tk_action = rpc_exit_task; | ||
627 | } | 655 | } |
656 | EXPORT_SYMBOL_GPL(rpc_call_start); | ||
628 | 657 | ||
629 | /** | 658 | /** |
630 | * rpc_peeraddr - extract remote peer address from clnt's xprt | 659 | * rpc_peeraddr - extract remote peer address from clnt's xprt |
@@ -653,7 +682,8 @@ EXPORT_SYMBOL_GPL(rpc_peeraddr); | |||
653 | * @format: address format | 682 | * @format: address format |
654 | * | 683 | * |
655 | */ | 684 | */ |
656 | char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format) | 685 | const char *rpc_peeraddr2str(struct rpc_clnt *clnt, |
686 | enum rpc_display_format_t format) | ||
657 | { | 687 | { |
658 | struct rpc_xprt *xprt = clnt->cl_xprt; | 688 | struct rpc_xprt *xprt = clnt->cl_xprt; |
659 | 689 | ||
@@ -671,6 +701,7 @@ rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize | |||
671 | if (xprt->ops->set_buffer_size) | 701 | if (xprt->ops->set_buffer_size) |
672 | xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); | 702 | xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); |
673 | } | 703 | } |
704 | EXPORT_SYMBOL_GPL(rpc_setbufsize); | ||
674 | 705 | ||
675 | /* | 706 | /* |
676 | * Return size of largest payload RPC client can support, in bytes | 707 | * Return size of largest payload RPC client can support, in bytes |
@@ -710,6 +741,7 @@ rpc_restart_call(struct rpc_task *task) | |||
710 | 741 | ||
711 | task->tk_action = call_start; | 742 | task->tk_action = call_start; |
712 | } | 743 | } |
744 | EXPORT_SYMBOL_GPL(rpc_restart_call); | ||
713 | 745 | ||
714 | /* | 746 | /* |
715 | * 0. Initial state | 747 | * 0. Initial state |
@@ -1137,7 +1169,7 @@ call_status(struct rpc_task *task) | |||
1137 | case -ETIMEDOUT: | 1169 | case -ETIMEDOUT: |
1138 | task->tk_action = call_timeout; | 1170 | task->tk_action = call_timeout; |
1139 | if (task->tk_client->cl_discrtry) | 1171 | if (task->tk_client->cl_discrtry) |
1140 | xprt_disconnect(task->tk_xprt); | 1172 | xprt_force_disconnect(task->tk_xprt); |
1141 | break; | 1173 | break; |
1142 | case -ECONNREFUSED: | 1174 | case -ECONNREFUSED: |
1143 | case -ENOTCONN: | 1175 | case -ENOTCONN: |
@@ -1260,7 +1292,7 @@ out_retry: | |||
1260 | req->rq_received = req->rq_private_buf.len = 0; | 1292 | req->rq_received = req->rq_private_buf.len = 0; |
1261 | task->tk_status = 0; | 1293 | task->tk_status = 0; |
1262 | if (task->tk_client->cl_discrtry) | 1294 | if (task->tk_client->cl_discrtry) |
1263 | xprt_disconnect(task->tk_xprt); | 1295 | xprt_force_disconnect(task->tk_xprt); |
1264 | } | 1296 | } |
1265 | 1297 | ||
1266 | /* | 1298 | /* |
@@ -1517,9 +1549,15 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int | |||
1517 | .rpc_proc = &rpcproc_null, | 1549 | .rpc_proc = &rpcproc_null, |
1518 | .rpc_cred = cred, | 1550 | .rpc_cred = cred, |
1519 | }; | 1551 | }; |
1520 | return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL); | 1552 | struct rpc_task_setup task_setup_data = { |
1553 | .rpc_client = clnt, | ||
1554 | .rpc_message = &msg, | ||
1555 | .callback_ops = &rpc_default_ops, | ||
1556 | .flags = flags, | ||
1557 | }; | ||
1558 | return rpc_run_task(&task_setup_data); | ||
1521 | } | 1559 | } |
1522 | EXPORT_SYMBOL(rpc_call_null); | 1560 | EXPORT_SYMBOL_GPL(rpc_call_null); |
1523 | 1561 | ||
1524 | #ifdef RPC_DEBUG | 1562 | #ifdef RPC_DEBUG |
1525 | void rpc_show_tasks(void) | 1563 | void rpc_show_tasks(void) |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index c59f3ca2b41b..7e197168a245 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -76,6 +76,16 @@ rpc_timeout_upcall_queue(struct work_struct *work) | |||
76 | rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT); | 76 | rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT); |
77 | } | 77 | } |
78 | 78 | ||
79 | /** | ||
80 | * rpc_queue_upcall | ||
81 | * @inode: inode of upcall pipe on which to queue given message | ||
82 | * @msg: message to queue | ||
83 | * | ||
84 | * Call with an @inode created by rpc_mkpipe() to queue an upcall. | ||
85 | * A userspace process may then later read the upcall by performing a | ||
86 | * read on an open file for this inode. It is up to the caller to | ||
87 | * initialize the fields of @msg (other than @msg->list) appropriately. | ||
88 | */ | ||
79 | int | 89 | int |
80 | rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | 90 | rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) |
81 | { | 91 | { |
@@ -103,6 +113,7 @@ out: | |||
103 | wake_up(&rpci->waitq); | 113 | wake_up(&rpci->waitq); |
104 | return res; | 114 | return res; |
105 | } | 115 | } |
116 | EXPORT_SYMBOL(rpc_queue_upcall); | ||
106 | 117 | ||
107 | static inline void | 118 | static inline void |
108 | rpc_inode_setowner(struct inode *inode, void *private) | 119 | rpc_inode_setowner(struct inode *inode, void *private) |
@@ -512,8 +523,8 @@ rpc_get_inode(struct super_block *sb, int mode) | |||
512 | /* | 523 | /* |
513 | * FIXME: This probably has races. | 524 | * FIXME: This probably has races. |
514 | */ | 525 | */ |
515 | static void | 526 | static void rpc_depopulate(struct dentry *parent, |
516 | rpc_depopulate(struct dentry *parent, int start, int eof) | 527 | unsigned long start, unsigned long eof) |
517 | { | 528 | { |
518 | struct inode *dir = parent->d_inode; | 529 | struct inode *dir = parent->d_inode; |
519 | struct list_head *pos, *next; | 530 | struct list_head *pos, *next; |
@@ -663,7 +674,16 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
663 | return dentry; | 674 | return dentry; |
664 | } | 675 | } |
665 | 676 | ||
666 | 677 | /** | |
678 | * rpc_mkdir - Create a new directory in rpc_pipefs | ||
679 | * @path: path from the rpc_pipefs root to the new directory | ||
680 | * @rpc_clnt: rpc client to associate with this directory | ||
681 | * | ||
682 | * This creates a directory at the given @path associated with | ||
683 | * @rpc_clnt, which will contain a file named "info" with some basic | ||
684 | * information about the client, together with any "pipes" that may | ||
685 | * later be created using rpc_mkpipe(). | ||
686 | */ | ||
667 | struct dentry * | 687 | struct dentry * |
668 | rpc_mkdir(char *path, struct rpc_clnt *rpc_client) | 688 | rpc_mkdir(char *path, struct rpc_clnt *rpc_client) |
669 | { | 689 | { |
@@ -699,6 +719,10 @@ err_dput: | |||
699 | goto out; | 719 | goto out; |
700 | } | 720 | } |
701 | 721 | ||
722 | /** | ||
723 | * rpc_rmdir - Remove a directory created with rpc_mkdir() | ||
724 | * @dentry: directory to remove | ||
725 | */ | ||
702 | int | 726 | int |
703 | rpc_rmdir(struct dentry *dentry) | 727 | rpc_rmdir(struct dentry *dentry) |
704 | { | 728 | { |
@@ -717,6 +741,25 @@ rpc_rmdir(struct dentry *dentry) | |||
717 | return error; | 741 | return error; |
718 | } | 742 | } |
719 | 743 | ||
744 | /** | ||
745 | * rpc_mkpipe - make an rpc_pipefs file for kernel<->userspace communication | ||
746 | * @parent: dentry of directory to create new "pipe" in | ||
747 | * @name: name of pipe | ||
748 | * @private: private data to associate with the pipe, for the caller's use | ||
749 | * @ops: operations defining the behavior of the pipe: upcall, downcall, | ||
750 | * release_pipe, and destroy_msg. | ||
751 | * | ||
752 | * Data is made available for userspace to read by calls to | ||
753 | * rpc_queue_upcall(). The actual reads will result in calls to | ||
754 | * @ops->upcall, which will be called with the file pointer, | ||
755 | * message, and userspace buffer to copy to. | ||
756 | * | ||
757 | * Writes can come at any time, and do not necessarily have to be | ||
758 | * responses to upcalls. They will result in calls to @msg->downcall. | ||
759 | * | ||
760 | * The @private argument passed here will be available to all these methods | ||
761 | * from the file pointer, via RPC_I(file->f_dentry->d_inode)->private. | ||
762 | */ | ||
720 | struct dentry * | 763 | struct dentry * |
721 | rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pipe_ops *ops, int flags) | 764 | rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pipe_ops *ops, int flags) |
722 | { | 765 | { |
@@ -763,7 +806,16 @@ err_dput: | |||
763 | -ENOMEM); | 806 | -ENOMEM); |
764 | goto out; | 807 | goto out; |
765 | } | 808 | } |
809 | EXPORT_SYMBOL(rpc_mkpipe); | ||
766 | 810 | ||
811 | /** | ||
812 | * rpc_unlink - remove a pipe | ||
813 | * @dentry: dentry for the pipe, as returned from rpc_mkpipe | ||
814 | * | ||
815 | * After this call, lookups will no longer find the pipe, and any | ||
816 | * attempts to read or write using preexisting opens of the pipe will | ||
817 | * return -EPIPE. | ||
818 | */ | ||
767 | int | 819 | int |
768 | rpc_unlink(struct dentry *dentry) | 820 | rpc_unlink(struct dentry *dentry) |
769 | { | 821 | { |
@@ -785,6 +837,7 @@ rpc_unlink(struct dentry *dentry) | |||
785 | dput(parent); | 837 | dput(parent); |
786 | return error; | 838 | return error; |
787 | } | 839 | } |
840 | EXPORT_SYMBOL(rpc_unlink); | ||
788 | 841 | ||
789 | /* | 842 | /* |
790 | * populate the filesystem | 843 | * populate the filesystem |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index a05493aedb68..fa5b8f202d5b 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -55,45 +55,6 @@ enum { | |||
55 | #define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT | 55 | #define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * r_addr | ||
59 | * | ||
60 | * Quoting RFC 3530, section 2.2: | ||
61 | * | ||
62 | * For TCP over IPv4 and for UDP over IPv4, the format of r_addr is the | ||
63 | * US-ASCII string: | ||
64 | * | ||
65 | * h1.h2.h3.h4.p1.p2 | ||
66 | * | ||
67 | * The prefix, "h1.h2.h3.h4", is the standard textual form for | ||
68 | * representing an IPv4 address, which is always four octets long. | ||
69 | * Assuming big-endian ordering, h1, h2, h3, and h4, are respectively, | ||
70 | * the first through fourth octets each converted to ASCII-decimal. | ||
71 | * Assuming big-endian ordering, p1 and p2 are, respectively, the first | ||
72 | * and second octets each converted to ASCII-decimal. For example, if a | ||
73 | * host, in big-endian order, has an address of 0x0A010307 and there is | ||
74 | * a service listening on, in big endian order, port 0x020F (decimal | ||
75 | * 527), then the complete universal address is "10.1.3.7.2.15". | ||
76 | * | ||
77 | * ... | ||
78 | * | ||
79 | * For TCP over IPv6 and for UDP over IPv6, the format of r_addr is the | ||
80 | * US-ASCII string: | ||
81 | * | ||
82 | * x1:x2:x3:x4:x5:x6:x7:x8.p1.p2 | ||
83 | * | ||
84 | * The suffix "p1.p2" is the service port, and is computed the same way | ||
85 | * as with universal addresses for TCP and UDP over IPv4. The prefix, | ||
86 | * "x1:x2:x3:x4:x5:x6:x7:x8", is the standard textual form for | ||
87 | * representing an IPv6 address as defined in Section 2.2 of [RFC2373]. | ||
88 | * Additionally, the two alternative forms specified in Section 2.2 of | ||
89 | * [RFC2373] are also acceptable. | ||
90 | * | ||
91 | * XXX: Currently this implementation does not explicitly convert the | ||
92 | * stored address to US-ASCII on non-ASCII systems. | ||
93 | */ | ||
94 | #define RPCB_MAXADDRLEN (128u) | ||
95 | |||
96 | /* | ||
97 | * r_owner | 58 | * r_owner |
98 | * | 59 | * |
99 | * The "owner" is allowed to unset a service in the rpcbind database. | 60 | * The "owner" is allowed to unset a service in the rpcbind database. |
@@ -112,9 +73,9 @@ struct rpcbind_args { | |||
112 | u32 r_vers; | 73 | u32 r_vers; |
113 | u32 r_prot; | 74 | u32 r_prot; |
114 | unsigned short r_port; | 75 | unsigned short r_port; |
115 | char * r_netid; | 76 | const char * r_netid; |
116 | char r_addr[RPCB_MAXADDRLEN]; | 77 | const char * r_addr; |
117 | char * r_owner; | 78 | const char * r_owner; |
118 | }; | 79 | }; |
119 | 80 | ||
120 | static struct rpc_procinfo rpcb_procedures2[]; | 81 | static struct rpc_procinfo rpcb_procedures2[]; |
@@ -128,19 +89,6 @@ struct rpcb_info { | |||
128 | static struct rpcb_info rpcb_next_version[]; | 89 | static struct rpcb_info rpcb_next_version[]; |
129 | static struct rpcb_info rpcb_next_version6[]; | 90 | static struct rpcb_info rpcb_next_version6[]; |
130 | 91 | ||
131 | static void rpcb_getport_prepare(struct rpc_task *task, void *calldata) | ||
132 | { | ||
133 | struct rpcbind_args *map = calldata; | ||
134 | struct rpc_xprt *xprt = map->r_xprt; | ||
135 | struct rpc_message msg = { | ||
136 | .rpc_proc = rpcb_next_version[xprt->bind_index].rpc_proc, | ||
137 | .rpc_argp = map, | ||
138 | .rpc_resp = &map->r_port, | ||
139 | }; | ||
140 | |||
141 | rpc_call_setup(task, &msg, 0); | ||
142 | } | ||
143 | |||
144 | static void rpcb_map_release(void *data) | 92 | static void rpcb_map_release(void *data) |
145 | { | 93 | { |
146 | struct rpcbind_args *map = data; | 94 | struct rpcbind_args *map = data; |
@@ -150,7 +98,6 @@ static void rpcb_map_release(void *data) | |||
150 | } | 98 | } |
151 | 99 | ||
152 | static const struct rpc_call_ops rpcb_getport_ops = { | 100 | static const struct rpc_call_ops rpcb_getport_ops = { |
153 | .rpc_call_prepare = rpcb_getport_prepare, | ||
154 | .rpc_call_done = rpcb_getport_done, | 101 | .rpc_call_done = rpcb_getport_done, |
155 | .rpc_release = rpcb_map_release, | 102 | .rpc_release = rpcb_map_release, |
156 | }; | 103 | }; |
@@ -162,12 +109,13 @@ static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status) | |||
162 | } | 109 | } |
163 | 110 | ||
164 | static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | 111 | static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, |
165 | int proto, int version, int privileged) | 112 | size_t salen, int proto, u32 version, |
113 | int privileged) | ||
166 | { | 114 | { |
167 | struct rpc_create_args args = { | 115 | struct rpc_create_args args = { |
168 | .protocol = proto, | 116 | .protocol = proto, |
169 | .address = srvaddr, | 117 | .address = srvaddr, |
170 | .addrsize = sizeof(struct sockaddr_in), | 118 | .addrsize = salen, |
171 | .servername = hostname, | 119 | .servername = hostname, |
172 | .program = &rpcb_program, | 120 | .program = &rpcb_program, |
173 | .version = version, | 121 | .version = version, |
@@ -230,7 +178,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) | |||
230 | prog, vers, prot, port); | 178 | prog, vers, prot, port); |
231 | 179 | ||
232 | rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin, | 180 | rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin, |
233 | XPRT_TRANSPORT_UDP, 2, 1); | 181 | sizeof(sin), XPRT_TRANSPORT_UDP, 2, 1); |
234 | if (IS_ERR(rpcb_clnt)) | 182 | if (IS_ERR(rpcb_clnt)) |
235 | return PTR_ERR(rpcb_clnt); | 183 | return PTR_ERR(rpcb_clnt); |
236 | 184 | ||
@@ -252,13 +200,15 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) | |||
252 | * @vers: RPC version number to bind | 200 | * @vers: RPC version number to bind |
253 | * @prot: transport protocol to use to make this request | 201 | * @prot: transport protocol to use to make this request |
254 | * | 202 | * |
203 | * Return value is the requested advertised port number, | ||
204 | * or a negative errno value. | ||
205 | * | ||
255 | * Called from outside the RPC client in a synchronous task context. | 206 | * Called from outside the RPC client in a synchronous task context. |
256 | * Uses default timeout parameters specified by underlying transport. | 207 | * Uses default timeout parameters specified by underlying transport. |
257 | * | 208 | * |
258 | * XXX: Needs to support IPv6, and rpcbind versions 3 and 4 | 209 | * XXX: Needs to support IPv6 |
259 | */ | 210 | */ |
260 | int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog, | 211 | int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) |
261 | __u32 vers, int prot) | ||
262 | { | 212 | { |
263 | struct rpcbind_args map = { | 213 | struct rpcbind_args map = { |
264 | .r_prog = prog, | 214 | .r_prog = prog, |
@@ -272,14 +222,13 @@ int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog, | |||
272 | .rpc_resp = &map.r_port, | 222 | .rpc_resp = &map.r_port, |
273 | }; | 223 | }; |
274 | struct rpc_clnt *rpcb_clnt; | 224 | struct rpc_clnt *rpcb_clnt; |
275 | char hostname[40]; | ||
276 | int status; | 225 | int status; |
277 | 226 | ||
278 | dprintk("RPC: %s(" NIPQUAD_FMT ", %u, %u, %d)\n", | 227 | dprintk("RPC: %s(" NIPQUAD_FMT ", %u, %u, %d)\n", |
279 | __FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); | 228 | __FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); |
280 | 229 | ||
281 | sprintf(hostname, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr)); | 230 | rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, |
282 | rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0); | 231 | sizeof(*sin), prot, 2, 0); |
283 | if (IS_ERR(rpcb_clnt)) | 232 | if (IS_ERR(rpcb_clnt)) |
284 | return PTR_ERR(rpcb_clnt); | 233 | return PTR_ERR(rpcb_clnt); |
285 | 234 | ||
@@ -295,6 +244,24 @@ int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog, | |||
295 | } | 244 | } |
296 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); | 245 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); |
297 | 246 | ||
247 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version) | ||
248 | { | ||
249 | struct rpc_message msg = { | ||
250 | .rpc_proc = rpcb_next_version[version].rpc_proc, | ||
251 | .rpc_argp = map, | ||
252 | .rpc_resp = &map->r_port, | ||
253 | }; | ||
254 | struct rpc_task_setup task_setup_data = { | ||
255 | .rpc_client = rpcb_clnt, | ||
256 | .rpc_message = &msg, | ||
257 | .callback_ops = &rpcb_getport_ops, | ||
258 | .callback_data = map, | ||
259 | .flags = RPC_TASK_ASYNC, | ||
260 | }; | ||
261 | |||
262 | return rpc_run_task(&task_setup_data); | ||
263 | } | ||
264 | |||
298 | /** | 265 | /** |
299 | * rpcb_getport_async - obtain the port for a given RPC service on a given host | 266 | * rpcb_getport_async - obtain the port for a given RPC service on a given host |
300 | * @task: task that is waiting for portmapper request | 267 | * @task: task that is waiting for portmapper request |
@@ -305,12 +272,14 @@ EXPORT_SYMBOL_GPL(rpcb_getport_sync); | |||
305 | void rpcb_getport_async(struct rpc_task *task) | 272 | void rpcb_getport_async(struct rpc_task *task) |
306 | { | 273 | { |
307 | struct rpc_clnt *clnt = task->tk_client; | 274 | struct rpc_clnt *clnt = task->tk_client; |
308 | int bind_version; | 275 | u32 bind_version; |
309 | struct rpc_xprt *xprt = task->tk_xprt; | 276 | struct rpc_xprt *xprt = task->tk_xprt; |
310 | struct rpc_clnt *rpcb_clnt; | 277 | struct rpc_clnt *rpcb_clnt; |
311 | static struct rpcbind_args *map; | 278 | static struct rpcbind_args *map; |
312 | struct rpc_task *child; | 279 | struct rpc_task *child; |
313 | struct sockaddr addr; | 280 | struct sockaddr_storage addr; |
281 | struct sockaddr *sap = (struct sockaddr *)&addr; | ||
282 | size_t salen; | ||
314 | int status; | 283 | int status; |
315 | struct rpcb_info *info; | 284 | struct rpcb_info *info; |
316 | 285 | ||
@@ -340,10 +309,10 @@ void rpcb_getport_async(struct rpc_task *task) | |||
340 | goto bailout_nofree; | 309 | goto bailout_nofree; |
341 | } | 310 | } |
342 | 311 | ||
343 | rpc_peeraddr(clnt, (void *)&addr, sizeof(addr)); | 312 | salen = rpc_peeraddr(clnt, sap, sizeof(addr)); |
344 | 313 | ||
345 | /* Don't ever use rpcbind v2 for AF_INET6 requests */ | 314 | /* Don't ever use rpcbind v2 for AF_INET6 requests */ |
346 | switch (addr.sa_family) { | 315 | switch (sap->sa_family) { |
347 | case AF_INET: | 316 | case AF_INET: |
348 | info = rpcb_next_version; | 317 | info = rpcb_next_version; |
349 | break; | 318 | break; |
@@ -368,7 +337,7 @@ void rpcb_getport_async(struct rpc_task *task) | |||
368 | dprintk("RPC: %5u %s: trying rpcbind version %u\n", | 337 | dprintk("RPC: %5u %s: trying rpcbind version %u\n", |
369 | task->tk_pid, __FUNCTION__, bind_version); | 338 | task->tk_pid, __FUNCTION__, bind_version); |
370 | 339 | ||
371 | rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, | 340 | rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot, |
372 | bind_version, 0); | 341 | bind_version, 0); |
373 | if (IS_ERR(rpcb_clnt)) { | 342 | if (IS_ERR(rpcb_clnt)) { |
374 | status = PTR_ERR(rpcb_clnt); | 343 | status = PTR_ERR(rpcb_clnt); |
@@ -390,12 +359,10 @@ void rpcb_getport_async(struct rpc_task *task) | |||
390 | map->r_port = 0; | 359 | map->r_port = 0; |
391 | map->r_xprt = xprt_get(xprt); | 360 | map->r_xprt = xprt_get(xprt); |
392 | map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); | 361 | map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); |
393 | memcpy(map->r_addr, | 362 | map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); |
394 | rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR), | ||
395 | sizeof(map->r_addr)); | ||
396 | map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ | 363 | map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ |
397 | 364 | ||
398 | child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); | 365 | child = rpcb_call_async(rpcb_clnt, map, xprt->bind_index); |
399 | rpc_release_client(rpcb_clnt); | 366 | rpc_release_client(rpcb_clnt); |
400 | if (IS_ERR(child)) { | 367 | if (IS_ERR(child)) { |
401 | status = -EIO; | 368 | status = -EIO; |
@@ -518,7 +485,7 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p, | |||
518 | * Simple sanity check. The smallest possible universal | 485 | * Simple sanity check. The smallest possible universal |
519 | * address is an IPv4 address string containing 11 bytes. | 486 | * address is an IPv4 address string containing 11 bytes. |
520 | */ | 487 | */ |
521 | if (addr_len < 11 || addr_len > RPCB_MAXADDRLEN) | 488 | if (addr_len < 11 || addr_len > RPCBIND_MAXUADDRLEN) |
522 | goto out_err; | 489 | goto out_err; |
523 | 490 | ||
524 | /* | 491 | /* |
@@ -569,7 +536,7 @@ out_err: | |||
569 | #define RPCB_boolean_sz (1u) | 536 | #define RPCB_boolean_sz (1u) |
570 | 537 | ||
571 | #define RPCB_netid_sz (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN)) | 538 | #define RPCB_netid_sz (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN)) |
572 | #define RPCB_addr_sz (1+XDR_QUADLEN(RPCB_MAXADDRLEN)) | 539 | #define RPCB_addr_sz (1+XDR_QUADLEN(RPCBIND_MAXUADDRLEN)) |
573 | #define RPCB_ownerstring_sz (1+XDR_QUADLEN(RPCB_MAXOWNERLEN)) | 540 | #define RPCB_ownerstring_sz (1+XDR_QUADLEN(RPCB_MAXOWNERLEN)) |
574 | 541 | ||
575 | #define RPCB_mappingargs_sz RPCB_program_sz+RPCB_version_sz+ \ | 542 | #define RPCB_mappingargs_sz RPCB_program_sz+RPCB_version_sz+ \ |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index eed5dd9819cd..40ce6f6672d6 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -45,7 +45,7 @@ static void rpc_release_task(struct rpc_task *task); | |||
45 | /* | 45 | /* |
46 | * RPC tasks sit here while waiting for conditions to improve. | 46 | * RPC tasks sit here while waiting for conditions to improve. |
47 | */ | 47 | */ |
48 | static RPC_WAITQ(delay_queue, "delayq"); | 48 | static struct rpc_wait_queue delay_queue; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * rpciod-related stuff | 51 | * rpciod-related stuff |
@@ -135,7 +135,7 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct r | |||
135 | if (unlikely(task->tk_priority > queue->maxpriority)) | 135 | if (unlikely(task->tk_priority > queue->maxpriority)) |
136 | q = &queue->tasks[queue->maxpriority]; | 136 | q = &queue->tasks[queue->maxpriority]; |
137 | list_for_each_entry(t, q, u.tk_wait.list) { | 137 | list_for_each_entry(t, q, u.tk_wait.list) { |
138 | if (t->tk_cookie == task->tk_cookie) { | 138 | if (t->tk_owner == task->tk_owner) { |
139 | list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links); | 139 | list_add_tail(&task->u.tk_wait.list, &t->u.tk_wait.links); |
140 | return; | 140 | return; |
141 | } | 141 | } |
@@ -208,26 +208,26 @@ static inline void rpc_set_waitqueue_priority(struct rpc_wait_queue *queue, int | |||
208 | queue->count = 1 << (priority * 2); | 208 | queue->count = 1 << (priority * 2); |
209 | } | 209 | } |
210 | 210 | ||
211 | static inline void rpc_set_waitqueue_cookie(struct rpc_wait_queue *queue, unsigned long cookie) | 211 | static inline void rpc_set_waitqueue_owner(struct rpc_wait_queue *queue, pid_t pid) |
212 | { | 212 | { |
213 | queue->cookie = cookie; | 213 | queue->owner = pid; |
214 | queue->nr = RPC_BATCH_COUNT; | 214 | queue->nr = RPC_BATCH_COUNT; |
215 | } | 215 | } |
216 | 216 | ||
217 | static inline void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue) | 217 | static inline void rpc_reset_waitqueue_priority(struct rpc_wait_queue *queue) |
218 | { | 218 | { |
219 | rpc_set_waitqueue_priority(queue, queue->maxpriority); | 219 | rpc_set_waitqueue_priority(queue, queue->maxpriority); |
220 | rpc_set_waitqueue_cookie(queue, 0); | 220 | rpc_set_waitqueue_owner(queue, 0); |
221 | } | 221 | } |
222 | 222 | ||
223 | static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname, int maxprio) | 223 | static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname, unsigned char nr_queues) |
224 | { | 224 | { |
225 | int i; | 225 | int i; |
226 | 226 | ||
227 | spin_lock_init(&queue->lock); | 227 | spin_lock_init(&queue->lock); |
228 | for (i = 0; i < ARRAY_SIZE(queue->tasks); i++) | 228 | for (i = 0; i < ARRAY_SIZE(queue->tasks); i++) |
229 | INIT_LIST_HEAD(&queue->tasks[i]); | 229 | INIT_LIST_HEAD(&queue->tasks[i]); |
230 | queue->maxpriority = maxprio; | 230 | queue->maxpriority = nr_queues - 1; |
231 | rpc_reset_waitqueue_priority(queue); | 231 | rpc_reset_waitqueue_priority(queue); |
232 | #ifdef RPC_DEBUG | 232 | #ifdef RPC_DEBUG |
233 | queue->name = qname; | 233 | queue->name = qname; |
@@ -236,14 +236,14 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c | |||
236 | 236 | ||
237 | void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname) | 237 | void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname) |
238 | { | 238 | { |
239 | __rpc_init_priority_wait_queue(queue, qname, RPC_PRIORITY_HIGH); | 239 | __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY); |
240 | } | 240 | } |
241 | 241 | ||
242 | void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) | 242 | void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) |
243 | { | 243 | { |
244 | __rpc_init_priority_wait_queue(queue, qname, 0); | 244 | __rpc_init_priority_wait_queue(queue, qname, 1); |
245 | } | 245 | } |
246 | EXPORT_SYMBOL(rpc_init_wait_queue); | 246 | EXPORT_SYMBOL_GPL(rpc_init_wait_queue); |
247 | 247 | ||
248 | static int rpc_wait_bit_interruptible(void *word) | 248 | static int rpc_wait_bit_interruptible(void *word) |
249 | { | 249 | { |
@@ -303,7 +303,7 @@ int __rpc_wait_for_completion_task(struct rpc_task *task, int (*action)(void *)) | |||
303 | return wait_on_bit(&task->tk_runstate, RPC_TASK_ACTIVE, | 303 | return wait_on_bit(&task->tk_runstate, RPC_TASK_ACTIVE, |
304 | action, TASK_INTERRUPTIBLE); | 304 | action, TASK_INTERRUPTIBLE); |
305 | } | 305 | } |
306 | EXPORT_SYMBOL(__rpc_wait_for_completion_task); | 306 | EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); |
307 | 307 | ||
308 | /* | 308 | /* |
309 | * Make an RPC task runnable. | 309 | * Make an RPC task runnable. |
@@ -373,6 +373,7 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
373 | __rpc_sleep_on(q, task, action, timer); | 373 | __rpc_sleep_on(q, task, action, timer); |
374 | spin_unlock_bh(&q->lock); | 374 | spin_unlock_bh(&q->lock); |
375 | } | 375 | } |
376 | EXPORT_SYMBOL_GPL(rpc_sleep_on); | ||
376 | 377 | ||
377 | /** | 378 | /** |
378 | * __rpc_do_wake_up_task - wake up a single rpc_task | 379 | * __rpc_do_wake_up_task - wake up a single rpc_task |
@@ -444,6 +445,7 @@ void rpc_wake_up_task(struct rpc_task *task) | |||
444 | } | 445 | } |
445 | rcu_read_unlock_bh(); | 446 | rcu_read_unlock_bh(); |
446 | } | 447 | } |
448 | EXPORT_SYMBOL_GPL(rpc_wake_up_task); | ||
447 | 449 | ||
448 | /* | 450 | /* |
449 | * Wake up the next task on a priority queue. | 451 | * Wake up the next task on a priority queue. |
@@ -454,12 +456,12 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu | |||
454 | struct rpc_task *task; | 456 | struct rpc_task *task; |
455 | 457 | ||
456 | /* | 458 | /* |
457 | * Service a batch of tasks from a single cookie. | 459 | * Service a batch of tasks from a single owner. |
458 | */ | 460 | */ |
459 | q = &queue->tasks[queue->priority]; | 461 | q = &queue->tasks[queue->priority]; |
460 | if (!list_empty(q)) { | 462 | if (!list_empty(q)) { |
461 | task = list_entry(q->next, struct rpc_task, u.tk_wait.list); | 463 | task = list_entry(q->next, struct rpc_task, u.tk_wait.list); |
462 | if (queue->cookie == task->tk_cookie) { | 464 | if (queue->owner == task->tk_owner) { |
463 | if (--queue->nr) | 465 | if (--queue->nr) |
464 | goto out; | 466 | goto out; |
465 | list_move_tail(&task->u.tk_wait.list, q); | 467 | list_move_tail(&task->u.tk_wait.list, q); |
@@ -468,7 +470,7 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu | |||
468 | * Check if we need to switch queues. | 470 | * Check if we need to switch queues. |
469 | */ | 471 | */ |
470 | if (--queue->count) | 472 | if (--queue->count) |
471 | goto new_cookie; | 473 | goto new_owner; |
472 | } | 474 | } |
473 | 475 | ||
474 | /* | 476 | /* |
@@ -490,8 +492,8 @@ static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queu | |||
490 | 492 | ||
491 | new_queue: | 493 | new_queue: |
492 | rpc_set_waitqueue_priority(queue, (unsigned int)(q - &queue->tasks[0])); | 494 | rpc_set_waitqueue_priority(queue, (unsigned int)(q - &queue->tasks[0])); |
493 | new_cookie: | 495 | new_owner: |
494 | rpc_set_waitqueue_cookie(queue, task->tk_cookie); | 496 | rpc_set_waitqueue_owner(queue, task->tk_owner); |
495 | out: | 497 | out: |
496 | __rpc_wake_up_task(task); | 498 | __rpc_wake_up_task(task); |
497 | return task; | 499 | return task; |
@@ -519,6 +521,7 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue) | |||
519 | 521 | ||
520 | return task; | 522 | return task; |
521 | } | 523 | } |
524 | EXPORT_SYMBOL_GPL(rpc_wake_up_next); | ||
522 | 525 | ||
523 | /** | 526 | /** |
524 | * rpc_wake_up - wake up all rpc_tasks | 527 | * rpc_wake_up - wake up all rpc_tasks |
@@ -544,6 +547,7 @@ void rpc_wake_up(struct rpc_wait_queue *queue) | |||
544 | spin_unlock(&queue->lock); | 547 | spin_unlock(&queue->lock); |
545 | rcu_read_unlock_bh(); | 548 | rcu_read_unlock_bh(); |
546 | } | 549 | } |
550 | EXPORT_SYMBOL_GPL(rpc_wake_up); | ||
547 | 551 | ||
548 | /** | 552 | /** |
549 | * rpc_wake_up_status - wake up all rpc_tasks and set their status value. | 553 | * rpc_wake_up_status - wake up all rpc_tasks and set their status value. |
@@ -572,6 +576,7 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) | |||
572 | spin_unlock(&queue->lock); | 576 | spin_unlock(&queue->lock); |
573 | rcu_read_unlock_bh(); | 577 | rcu_read_unlock_bh(); |
574 | } | 578 | } |
579 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); | ||
575 | 580 | ||
576 | static void __rpc_atrun(struct rpc_task *task) | 581 | static void __rpc_atrun(struct rpc_task *task) |
577 | { | 582 | { |
@@ -586,6 +591,7 @@ void rpc_delay(struct rpc_task *task, unsigned long delay) | |||
586 | task->tk_timeout = delay; | 591 | task->tk_timeout = delay; |
587 | rpc_sleep_on(&delay_queue, task, NULL, __rpc_atrun); | 592 | rpc_sleep_on(&delay_queue, task, NULL, __rpc_atrun); |
588 | } | 593 | } |
594 | EXPORT_SYMBOL_GPL(rpc_delay); | ||
589 | 595 | ||
590 | /* | 596 | /* |
591 | * Helper to call task->tk_ops->rpc_call_prepare | 597 | * Helper to call task->tk_ops->rpc_call_prepare |
@@ -614,7 +620,7 @@ void rpc_exit_task(struct rpc_task *task) | |||
614 | } | 620 | } |
615 | } | 621 | } |
616 | } | 622 | } |
617 | EXPORT_SYMBOL(rpc_exit_task); | 623 | EXPORT_SYMBOL_GPL(rpc_exit_task); |
618 | 624 | ||
619 | void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) | 625 | void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) |
620 | { | 626 | { |
@@ -808,39 +814,49 @@ EXPORT_SYMBOL_GPL(rpc_free); | |||
808 | /* | 814 | /* |
809 | * Creation and deletion of RPC task structures | 815 | * Creation and deletion of RPC task structures |
810 | */ | 816 | */ |
811 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) | 817 | static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data) |
812 | { | 818 | { |
813 | memset(task, 0, sizeof(*task)); | 819 | memset(task, 0, sizeof(*task)); |
814 | setup_timer(&task->tk_timer, (void (*)(unsigned long))rpc_run_timer, | 820 | setup_timer(&task->tk_timer, (void (*)(unsigned long))rpc_run_timer, |
815 | (unsigned long)task); | 821 | (unsigned long)task); |
816 | atomic_set(&task->tk_count, 1); | 822 | atomic_set(&task->tk_count, 1); |
817 | task->tk_client = clnt; | 823 | task->tk_flags = task_setup_data->flags; |
818 | task->tk_flags = flags; | 824 | task->tk_ops = task_setup_data->callback_ops; |
819 | task->tk_ops = tk_ops; | 825 | task->tk_calldata = task_setup_data->callback_data; |
820 | if (tk_ops->rpc_call_prepare != NULL) | ||
821 | task->tk_action = rpc_prepare_task; | ||
822 | task->tk_calldata = calldata; | ||
823 | INIT_LIST_HEAD(&task->tk_task); | 826 | INIT_LIST_HEAD(&task->tk_task); |
824 | 827 | ||
825 | /* Initialize retry counters */ | 828 | /* Initialize retry counters */ |
826 | task->tk_garb_retry = 2; | 829 | task->tk_garb_retry = 2; |
827 | task->tk_cred_retry = 2; | 830 | task->tk_cred_retry = 2; |
828 | 831 | ||
829 | task->tk_priority = RPC_PRIORITY_NORMAL; | 832 | task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW; |
830 | task->tk_cookie = (unsigned long)current; | 833 | task->tk_owner = current->tgid; |
831 | 834 | ||
832 | /* Initialize workqueue for async tasks */ | 835 | /* Initialize workqueue for async tasks */ |
833 | task->tk_workqueue = rpciod_workqueue; | 836 | task->tk_workqueue = rpciod_workqueue; |
834 | 837 | ||
835 | if (clnt) { | 838 | task->tk_client = task_setup_data->rpc_client; |
836 | kref_get(&clnt->cl_kref); | 839 | if (task->tk_client != NULL) { |
837 | if (clnt->cl_softrtry) | 840 | kref_get(&task->tk_client->cl_kref); |
841 | if (task->tk_client->cl_softrtry) | ||
838 | task->tk_flags |= RPC_TASK_SOFT; | 842 | task->tk_flags |= RPC_TASK_SOFT; |
839 | if (!clnt->cl_intr) | 843 | if (!task->tk_client->cl_intr) |
840 | task->tk_flags |= RPC_TASK_NOINTR; | 844 | task->tk_flags |= RPC_TASK_NOINTR; |
841 | } | 845 | } |
842 | 846 | ||
843 | BUG_ON(task->tk_ops == NULL); | 847 | if (task->tk_ops->rpc_call_prepare != NULL) |
848 | task->tk_action = rpc_prepare_task; | ||
849 | |||
850 | if (task_setup_data->rpc_message != NULL) { | ||
851 | memcpy(&task->tk_msg, task_setup_data->rpc_message, sizeof(task->tk_msg)); | ||
852 | /* Bind the user cred */ | ||
853 | if (task->tk_msg.rpc_cred != NULL) | ||
854 | rpcauth_holdcred(task); | ||
855 | else | ||
856 | rpcauth_bindcred(task); | ||
857 | if (task->tk_action == NULL) | ||
858 | rpc_call_start(task); | ||
859 | } | ||
844 | 860 | ||
845 | /* starting timestamp */ | 861 | /* starting timestamp */ |
846 | task->tk_start = jiffies; | 862 | task->tk_start = jiffies; |
@@ -865,18 +881,22 @@ static void rpc_free_task(struct rcu_head *rcu) | |||
865 | /* | 881 | /* |
866 | * Create a new task for the specified client. | 882 | * Create a new task for the specified client. |
867 | */ | 883 | */ |
868 | struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) | 884 | struct rpc_task *rpc_new_task(const struct rpc_task_setup *setup_data) |
869 | { | 885 | { |
870 | struct rpc_task *task; | 886 | struct rpc_task *task = setup_data->task; |
871 | 887 | unsigned short flags = 0; | |
872 | task = rpc_alloc_task(); | 888 | |
873 | if (!task) | 889 | if (task == NULL) { |
874 | goto out; | 890 | task = rpc_alloc_task(); |
891 | if (task == NULL) | ||
892 | goto out; | ||
893 | flags = RPC_TASK_DYNAMIC; | ||
894 | } | ||
875 | 895 | ||
876 | rpc_init_task(task, clnt, flags, tk_ops, calldata); | 896 | rpc_init_task(task, setup_data); |
877 | 897 | ||
898 | task->tk_flags |= flags; | ||
878 | dprintk("RPC: allocated task %p\n", task); | 899 | dprintk("RPC: allocated task %p\n", task); |
879 | task->tk_flags |= RPC_TASK_DYNAMIC; | ||
880 | out: | 900 | out: |
881 | return task; | 901 | return task; |
882 | } | 902 | } |
@@ -902,7 +922,7 @@ void rpc_put_task(struct rpc_task *task) | |||
902 | call_rcu_bh(&task->u.tk_rcu, rpc_free_task); | 922 | call_rcu_bh(&task->u.tk_rcu, rpc_free_task); |
903 | rpc_release_calldata(tk_ops, calldata); | 923 | rpc_release_calldata(tk_ops, calldata); |
904 | } | 924 | } |
905 | EXPORT_SYMBOL(rpc_put_task); | 925 | EXPORT_SYMBOL_GPL(rpc_put_task); |
906 | 926 | ||
907 | static void rpc_release_task(struct rpc_task *task) | 927 | static void rpc_release_task(struct rpc_task *task) |
908 | { | 928 | { |
@@ -959,6 +979,7 @@ void rpc_killall_tasks(struct rpc_clnt *clnt) | |||
959 | } | 979 | } |
960 | spin_unlock(&clnt->cl_lock); | 980 | spin_unlock(&clnt->cl_lock); |
961 | } | 981 | } |
982 | EXPORT_SYMBOL_GPL(rpc_killall_tasks); | ||
962 | 983 | ||
963 | int rpciod_up(void) | 984 | int rpciod_up(void) |
964 | { | 985 | { |
@@ -1038,6 +1059,11 @@ rpc_init_mempool(void) | |||
1038 | goto err_nomem; | 1059 | goto err_nomem; |
1039 | if (!rpciod_start()) | 1060 | if (!rpciod_start()) |
1040 | goto err_nomem; | 1061 | goto err_nomem; |
1062 | /* | ||
1063 | * The following is not strictly a mempool initialisation, | ||
1064 | * but there is no harm in doing it here | ||
1065 | */ | ||
1066 | rpc_init_wait_queue(&delay_queue, "delayq"); | ||
1041 | return 0; | 1067 | return 0; |
1042 | err_nomem: | 1068 | err_nomem: |
1043 | rpc_destroy_mempool(); | 1069 | rpc_destroy_mempool(); |
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c index 97ac45f034d6..a661a3acb37e 100644 --- a/net/sunrpc/socklib.c +++ b/net/sunrpc/socklib.c | |||
@@ -72,7 +72,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct | |||
72 | struct page **ppage = xdr->pages; | 72 | struct page **ppage = xdr->pages; |
73 | unsigned int len, pglen = xdr->page_len; | 73 | unsigned int len, pglen = xdr->page_len; |
74 | ssize_t copied = 0; | 74 | ssize_t copied = 0; |
75 | int ret; | 75 | size_t ret; |
76 | 76 | ||
77 | len = xdr->head[0].iov_len; | 77 | len = xdr->head[0].iov_len; |
78 | if (base < len) { | 78 | if (base < len) { |
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 4d4f3738b688..74df2d358e61 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c | |||
@@ -118,7 +118,7 @@ struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) | |||
118 | new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); | 118 | new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); |
119 | return new; | 119 | return new; |
120 | } | 120 | } |
121 | EXPORT_SYMBOL(rpc_alloc_iostats); | 121 | EXPORT_SYMBOL_GPL(rpc_alloc_iostats); |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * rpc_free_iostats - release an rpc_iostats structure | 124 | * rpc_free_iostats - release an rpc_iostats structure |
@@ -129,7 +129,7 @@ void rpc_free_iostats(struct rpc_iostats *stats) | |||
129 | { | 129 | { |
130 | kfree(stats); | 130 | kfree(stats); |
131 | } | 131 | } |
132 | EXPORT_SYMBOL(rpc_free_iostats); | 132 | EXPORT_SYMBOL_GPL(rpc_free_iostats); |
133 | 133 | ||
134 | /** | 134 | /** |
135 | * rpc_count_iostats - tally up per-task stats | 135 | * rpc_count_iostats - tally up per-task stats |
@@ -215,7 +215,7 @@ void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) | |||
215 | metrics->om_execute * MILLISECS_PER_JIFFY); | 215 | metrics->om_execute * MILLISECS_PER_JIFFY); |
216 | } | 216 | } |
217 | } | 217 | } |
218 | EXPORT_SYMBOL(rpc_print_iostats); | 218 | EXPORT_SYMBOL_GPL(rpc_print_iostats); |
219 | 219 | ||
220 | /* | 220 | /* |
221 | * Register/unregister RPC proc files | 221 | * Register/unregister RPC proc files |
@@ -241,12 +241,14 @@ rpc_proc_register(struct rpc_stat *statp) | |||
241 | { | 241 | { |
242 | return do_register(statp->program->name, statp, &rpc_proc_fops); | 242 | return do_register(statp->program->name, statp, &rpc_proc_fops); |
243 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(rpc_proc_register); | ||
244 | 245 | ||
245 | void | 246 | void |
246 | rpc_proc_unregister(const char *name) | 247 | rpc_proc_unregister(const char *name) |
247 | { | 248 | { |
248 | remove_proc_entry(name, proc_net_rpc); | 249 | remove_proc_entry(name, proc_net_rpc); |
249 | } | 250 | } |
251 | EXPORT_SYMBOL_GPL(rpc_proc_unregister); | ||
250 | 252 | ||
251 | struct proc_dir_entry * | 253 | struct proc_dir_entry * |
252 | svc_proc_register(struct svc_stat *statp, const struct file_operations *fops) | 254 | svc_proc_register(struct svc_stat *statp, const struct file_operations *fops) |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 33d89e842c85..1a7e309d008b 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -22,45 +22,6 @@ | |||
22 | #include <linux/sunrpc/rpc_pipe_fs.h> | 22 | #include <linux/sunrpc/rpc_pipe_fs.h> |
23 | #include <linux/sunrpc/xprtsock.h> | 23 | #include <linux/sunrpc/xprtsock.h> |
24 | 24 | ||
25 | /* RPC scheduler */ | ||
26 | EXPORT_SYMBOL(rpc_execute); | ||
27 | EXPORT_SYMBOL(rpc_init_task); | ||
28 | EXPORT_SYMBOL(rpc_sleep_on); | ||
29 | EXPORT_SYMBOL(rpc_wake_up_next); | ||
30 | EXPORT_SYMBOL(rpc_wake_up_task); | ||
31 | EXPORT_SYMBOL(rpc_wake_up_status); | ||
32 | |||
33 | /* RPC client functions */ | ||
34 | EXPORT_SYMBOL(rpc_clone_client); | ||
35 | EXPORT_SYMBOL(rpc_bind_new_program); | ||
36 | EXPORT_SYMBOL(rpc_shutdown_client); | ||
37 | EXPORT_SYMBOL(rpc_killall_tasks); | ||
38 | EXPORT_SYMBOL(rpc_call_sync); | ||
39 | EXPORT_SYMBOL(rpc_call_async); | ||
40 | EXPORT_SYMBOL(rpc_call_setup); | ||
41 | EXPORT_SYMBOL(rpc_clnt_sigmask); | ||
42 | EXPORT_SYMBOL(rpc_clnt_sigunmask); | ||
43 | EXPORT_SYMBOL(rpc_delay); | ||
44 | EXPORT_SYMBOL(rpc_restart_call); | ||
45 | EXPORT_SYMBOL(rpc_setbufsize); | ||
46 | EXPORT_SYMBOL(rpc_unlink); | ||
47 | EXPORT_SYMBOL(rpc_wake_up); | ||
48 | EXPORT_SYMBOL(rpc_queue_upcall); | ||
49 | EXPORT_SYMBOL(rpc_mkpipe); | ||
50 | |||
51 | /* Client transport */ | ||
52 | EXPORT_SYMBOL(xprt_set_timeout); | ||
53 | |||
54 | /* Client credential cache */ | ||
55 | EXPORT_SYMBOL(rpcauth_register); | ||
56 | EXPORT_SYMBOL(rpcauth_unregister); | ||
57 | EXPORT_SYMBOL(rpcauth_create); | ||
58 | EXPORT_SYMBOL(rpcauth_lookupcred); | ||
59 | EXPORT_SYMBOL(rpcauth_lookup_credcache); | ||
60 | EXPORT_SYMBOL(rpcauth_destroy_credcache); | ||
61 | EXPORT_SYMBOL(rpcauth_init_credcache); | ||
62 | EXPORT_SYMBOL(put_rpccred); | ||
63 | |||
64 | /* RPC server stuff */ | 25 | /* RPC server stuff */ |
65 | EXPORT_SYMBOL(svc_create); | 26 | EXPORT_SYMBOL(svc_create); |
66 | EXPORT_SYMBOL(svc_create_thread); | 27 | EXPORT_SYMBOL(svc_create_thread); |
@@ -81,8 +42,6 @@ EXPORT_SYMBOL(svc_set_client); | |||
81 | 42 | ||
82 | /* RPC statistics */ | 43 | /* RPC statistics */ |
83 | #ifdef CONFIG_PROC_FS | 44 | #ifdef CONFIG_PROC_FS |
84 | EXPORT_SYMBOL(rpc_proc_register); | ||
85 | EXPORT_SYMBOL(rpc_proc_unregister); | ||
86 | EXPORT_SYMBOL(svc_proc_register); | 45 | EXPORT_SYMBOL(svc_proc_register); |
87 | EXPORT_SYMBOL(svc_proc_unregister); | 46 | EXPORT_SYMBOL(svc_proc_unregister); |
88 | EXPORT_SYMBOL(svc_seq_show); | 47 | EXPORT_SYMBOL(svc_seq_show); |
@@ -105,31 +64,6 @@ EXPORT_SYMBOL(qword_get); | |||
105 | EXPORT_SYMBOL(svcauth_unix_purge); | 64 | EXPORT_SYMBOL(svcauth_unix_purge); |
106 | EXPORT_SYMBOL(unix_domain_find); | 65 | EXPORT_SYMBOL(unix_domain_find); |
107 | 66 | ||
108 | /* Generic XDR */ | ||
109 | EXPORT_SYMBOL(xdr_encode_string); | ||
110 | EXPORT_SYMBOL(xdr_decode_string_inplace); | ||
111 | EXPORT_SYMBOL(xdr_decode_netobj); | ||
112 | EXPORT_SYMBOL(xdr_encode_netobj); | ||
113 | EXPORT_SYMBOL(xdr_encode_pages); | ||
114 | EXPORT_SYMBOL(xdr_inline_pages); | ||
115 | EXPORT_SYMBOL(xdr_shift_buf); | ||
116 | EXPORT_SYMBOL(xdr_encode_word); | ||
117 | EXPORT_SYMBOL(xdr_decode_word); | ||
118 | EXPORT_SYMBOL(xdr_encode_array2); | ||
119 | EXPORT_SYMBOL(xdr_decode_array2); | ||
120 | EXPORT_SYMBOL(xdr_buf_from_iov); | ||
121 | EXPORT_SYMBOL(xdr_buf_subsegment); | ||
122 | EXPORT_SYMBOL(xdr_buf_read_netobj); | ||
123 | EXPORT_SYMBOL(read_bytes_from_xdr_buf); | ||
124 | |||
125 | /* Debugging symbols */ | ||
126 | #ifdef RPC_DEBUG | ||
127 | EXPORT_SYMBOL(rpc_debug); | ||
128 | EXPORT_SYMBOL(nfs_debug); | ||
129 | EXPORT_SYMBOL(nfsd_debug); | ||
130 | EXPORT_SYMBOL(nlm_debug); | ||
131 | #endif | ||
132 | |||
133 | extern struct cache_detail ip_map_cache, unix_gid_cache; | 67 | extern struct cache_detail ip_map_cache, unix_gid_cache; |
134 | 68 | ||
135 | static int __init | 69 | static int __init |
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c index 2be714e9b382..bada7de0c2fc 100644 --- a/net/sunrpc/sysctl.c +++ b/net/sunrpc/sysctl.c | |||
@@ -23,9 +23,16 @@ | |||
23 | * Declare the debug flags here | 23 | * Declare the debug flags here |
24 | */ | 24 | */ |
25 | unsigned int rpc_debug; | 25 | unsigned int rpc_debug; |
26 | EXPORT_SYMBOL_GPL(rpc_debug); | ||
27 | |||
26 | unsigned int nfs_debug; | 28 | unsigned int nfs_debug; |
29 | EXPORT_SYMBOL_GPL(nfs_debug); | ||
30 | |||
27 | unsigned int nfsd_debug; | 31 | unsigned int nfsd_debug; |
32 | EXPORT_SYMBOL_GPL(nfsd_debug); | ||
33 | |||
28 | unsigned int nlm_debug; | 34 | unsigned int nlm_debug; |
35 | EXPORT_SYMBOL_GPL(nlm_debug); | ||
29 | 36 | ||
30 | #ifdef RPC_DEBUG | 37 | #ifdef RPC_DEBUG |
31 | 38 | ||
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index fdc5e6d7562b..54264062ea69 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -28,6 +28,7 @@ xdr_encode_netobj(__be32 *p, const struct xdr_netobj *obj) | |||
28 | memcpy(p, obj->data, obj->len); | 28 | memcpy(p, obj->data, obj->len); |
29 | return p + XDR_QUADLEN(obj->len); | 29 | return p + XDR_QUADLEN(obj->len); |
30 | } | 30 | } |
31 | EXPORT_SYMBOL(xdr_encode_netobj); | ||
31 | 32 | ||
32 | __be32 * | 33 | __be32 * |
33 | xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj) | 34 | xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj) |
@@ -40,6 +41,7 @@ xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj) | |||
40 | obj->data = (u8 *) p; | 41 | obj->data = (u8 *) p; |
41 | return p + XDR_QUADLEN(len); | 42 | return p + XDR_QUADLEN(len); |
42 | } | 43 | } |
44 | EXPORT_SYMBOL(xdr_decode_netobj); | ||
43 | 45 | ||
44 | /** | 46 | /** |
45 | * xdr_encode_opaque_fixed - Encode fixed length opaque data | 47 | * xdr_encode_opaque_fixed - Encode fixed length opaque data |
@@ -91,6 +93,7 @@ xdr_encode_string(__be32 *p, const char *string) | |||
91 | { | 93 | { |
92 | return xdr_encode_array(p, string, strlen(string)); | 94 | return xdr_encode_array(p, string, strlen(string)); |
93 | } | 95 | } |
96 | EXPORT_SYMBOL(xdr_encode_string); | ||
94 | 97 | ||
95 | __be32 * | 98 | __be32 * |
96 | xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen) | 99 | xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen) |
@@ -103,6 +106,7 @@ xdr_decode_string_inplace(__be32 *p, char **sp, int *lenp, int maxlen) | |||
103 | *sp = (char *) p; | 106 | *sp = (char *) p; |
104 | return p + XDR_QUADLEN(len); | 107 | return p + XDR_QUADLEN(len); |
105 | } | 108 | } |
109 | EXPORT_SYMBOL(xdr_decode_string_inplace); | ||
106 | 110 | ||
107 | void | 111 | void |
108 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | 112 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, |
@@ -130,6 +134,7 @@ xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | |||
130 | xdr->buflen += len; | 134 | xdr->buflen += len; |
131 | xdr->len += len; | 135 | xdr->len += len; |
132 | } | 136 | } |
137 | EXPORT_SYMBOL(xdr_encode_pages); | ||
133 | 138 | ||
134 | void | 139 | void |
135 | xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, | 140 | xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, |
@@ -151,7 +156,7 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, | |||
151 | 156 | ||
152 | xdr->buflen += len; | 157 | xdr->buflen += len; |
153 | } | 158 | } |
154 | 159 | EXPORT_SYMBOL(xdr_inline_pages); | |
155 | 160 | ||
156 | /* | 161 | /* |
157 | * Helper routines for doing 'memmove' like operations on a struct xdr_buf | 162 | * Helper routines for doing 'memmove' like operations on a struct xdr_buf |
@@ -418,6 +423,7 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len) | |||
418 | { | 423 | { |
419 | xdr_shrink_bufhead(buf, len); | 424 | xdr_shrink_bufhead(buf, len); |
420 | } | 425 | } |
426 | EXPORT_SYMBOL(xdr_shift_buf); | ||
421 | 427 | ||
422 | /** | 428 | /** |
423 | * xdr_init_encode - Initialize a struct xdr_stream for sending data. | 429 | * xdr_init_encode - Initialize a struct xdr_stream for sending data. |
@@ -639,6 +645,7 @@ xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf) | |||
639 | buf->page_len = 0; | 645 | buf->page_len = 0; |
640 | buf->buflen = buf->len = iov->iov_len; | 646 | buf->buflen = buf->len = iov->iov_len; |
641 | } | 647 | } |
648 | EXPORT_SYMBOL(xdr_buf_from_iov); | ||
642 | 649 | ||
643 | /* Sets subbuf to the portion of buf of length len beginning base bytes | 650 | /* Sets subbuf to the portion of buf of length len beginning base bytes |
644 | * from the start of buf. Returns -1 if base of length are out of bounds. */ | 651 | * from the start of buf. Returns -1 if base of length are out of bounds. */ |
@@ -687,6 +694,7 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | |||
687 | return -1; | 694 | return -1; |
688 | return 0; | 695 | return 0; |
689 | } | 696 | } |
697 | EXPORT_SYMBOL(xdr_buf_subsegment); | ||
690 | 698 | ||
691 | static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) | 699 | static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) |
692 | { | 700 | { |
@@ -717,6 +725,7 @@ int read_bytes_from_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, u | |||
717 | __read_bytes_from_xdr_buf(&subbuf, obj, len); | 725 | __read_bytes_from_xdr_buf(&subbuf, obj, len); |
718 | return 0; | 726 | return 0; |
719 | } | 727 | } |
728 | EXPORT_SYMBOL(read_bytes_from_xdr_buf); | ||
720 | 729 | ||
721 | static void __write_bytes_to_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) | 730 | static void __write_bytes_to_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) |
722 | { | 731 | { |
@@ -760,6 +769,7 @@ xdr_decode_word(struct xdr_buf *buf, unsigned int base, u32 *obj) | |||
760 | *obj = ntohl(raw); | 769 | *obj = ntohl(raw); |
761 | return 0; | 770 | return 0; |
762 | } | 771 | } |
772 | EXPORT_SYMBOL(xdr_decode_word); | ||
763 | 773 | ||
764 | int | 774 | int |
765 | xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) | 775 | xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) |
@@ -768,6 +778,7 @@ xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) | |||
768 | 778 | ||
769 | return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj)); | 779 | return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj)); |
770 | } | 780 | } |
781 | EXPORT_SYMBOL(xdr_encode_word); | ||
771 | 782 | ||
772 | /* If the netobj starting offset bytes from the start of xdr_buf is contained | 783 | /* If the netobj starting offset bytes from the start of xdr_buf is contained |
773 | * entirely in the head or the tail, set object to point to it; otherwise | 784 | * entirely in the head or the tail, set object to point to it; otherwise |
@@ -805,6 +816,7 @@ int xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, unsigned in | |||
805 | __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len); | 816 | __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len); |
806 | return 0; | 817 | return 0; |
807 | } | 818 | } |
819 | EXPORT_SYMBOL(xdr_buf_read_netobj); | ||
808 | 820 | ||
809 | /* Returns 0 on success, or else a negative error code. */ | 821 | /* Returns 0 on success, or else a negative error code. */ |
810 | static int | 822 | static int |
@@ -1010,6 +1022,7 @@ xdr_decode_array2(struct xdr_buf *buf, unsigned int base, | |||
1010 | 1022 | ||
1011 | return xdr_xcode_array2(buf, base, desc, 0); | 1023 | return xdr_xcode_array2(buf, base, desc, 0); |
1012 | } | 1024 | } |
1025 | EXPORT_SYMBOL(xdr_decode_array2); | ||
1013 | 1026 | ||
1014 | int | 1027 | int |
1015 | xdr_encode_array2(struct xdr_buf *buf, unsigned int base, | 1028 | xdr_encode_array2(struct xdr_buf *buf, unsigned int base, |
@@ -1021,6 +1034,7 @@ xdr_encode_array2(struct xdr_buf *buf, unsigned int base, | |||
1021 | 1034 | ||
1022 | return xdr_xcode_array2(buf, base, desc, 1); | 1035 | return xdr_xcode_array2(buf, base, desc, 1); |
1023 | } | 1036 | } |
1037 | EXPORT_SYMBOL(xdr_encode_array2); | ||
1024 | 1038 | ||
1025 | int | 1039 | int |
1026 | xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | 1040 | xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index fb92f51405c5..cfcade906a56 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -501,9 +501,10 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_def); | |||
501 | void xprt_set_retrans_timeout_rtt(struct rpc_task *task) | 501 | void xprt_set_retrans_timeout_rtt(struct rpc_task *task) |
502 | { | 502 | { |
503 | int timer = task->tk_msg.rpc_proc->p_timer; | 503 | int timer = task->tk_msg.rpc_proc->p_timer; |
504 | struct rpc_rtt *rtt = task->tk_client->cl_rtt; | 504 | struct rpc_clnt *clnt = task->tk_client; |
505 | struct rpc_rtt *rtt = clnt->cl_rtt; | ||
505 | struct rpc_rqst *req = task->tk_rqstp; | 506 | struct rpc_rqst *req = task->tk_rqstp; |
506 | unsigned long max_timeout = req->rq_xprt->timeout.to_maxval; | 507 | unsigned long max_timeout = clnt->cl_timeout->to_maxval; |
507 | 508 | ||
508 | task->tk_timeout = rpc_calc_rto(rtt, timer); | 509 | task->tk_timeout = rpc_calc_rto(rtt, timer); |
509 | task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries; | 510 | task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries; |
@@ -514,7 +515,7 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_rtt); | |||
514 | 515 | ||
515 | static void xprt_reset_majortimeo(struct rpc_rqst *req) | 516 | static void xprt_reset_majortimeo(struct rpc_rqst *req) |
516 | { | 517 | { |
517 | struct rpc_timeout *to = &req->rq_xprt->timeout; | 518 | const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout; |
518 | 519 | ||
519 | req->rq_majortimeo = req->rq_timeout; | 520 | req->rq_majortimeo = req->rq_timeout; |
520 | if (to->to_exponential) | 521 | if (to->to_exponential) |
@@ -534,7 +535,7 @@ static void xprt_reset_majortimeo(struct rpc_rqst *req) | |||
534 | int xprt_adjust_timeout(struct rpc_rqst *req) | 535 | int xprt_adjust_timeout(struct rpc_rqst *req) |
535 | { | 536 | { |
536 | struct rpc_xprt *xprt = req->rq_xprt; | 537 | struct rpc_xprt *xprt = req->rq_xprt; |
537 | struct rpc_timeout *to = &xprt->timeout; | 538 | const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout; |
538 | int status = 0; | 539 | int status = 0; |
539 | 540 | ||
540 | if (time_before(jiffies, req->rq_majortimeo)) { | 541 | if (time_before(jiffies, req->rq_majortimeo)) { |
@@ -568,17 +569,17 @@ static void xprt_autoclose(struct work_struct *work) | |||
568 | struct rpc_xprt *xprt = | 569 | struct rpc_xprt *xprt = |
569 | container_of(work, struct rpc_xprt, task_cleanup); | 570 | container_of(work, struct rpc_xprt, task_cleanup); |
570 | 571 | ||
571 | xprt_disconnect(xprt); | ||
572 | xprt->ops->close(xprt); | 572 | xprt->ops->close(xprt); |
573 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
573 | xprt_release_write(xprt, NULL); | 574 | xprt_release_write(xprt, NULL); |
574 | } | 575 | } |
575 | 576 | ||
576 | /** | 577 | /** |
577 | * xprt_disconnect - mark a transport as disconnected | 578 | * xprt_disconnect_done - mark a transport as disconnected |
578 | * @xprt: transport to flag for disconnect | 579 | * @xprt: transport to flag for disconnect |
579 | * | 580 | * |
580 | */ | 581 | */ |
581 | void xprt_disconnect(struct rpc_xprt *xprt) | 582 | void xprt_disconnect_done(struct rpc_xprt *xprt) |
582 | { | 583 | { |
583 | dprintk("RPC: disconnected transport %p\n", xprt); | 584 | dprintk("RPC: disconnected transport %p\n", xprt); |
584 | spin_lock_bh(&xprt->transport_lock); | 585 | spin_lock_bh(&xprt->transport_lock); |
@@ -586,7 +587,26 @@ void xprt_disconnect(struct rpc_xprt *xprt) | |||
586 | xprt_wake_pending_tasks(xprt, -ENOTCONN); | 587 | xprt_wake_pending_tasks(xprt, -ENOTCONN); |
587 | spin_unlock_bh(&xprt->transport_lock); | 588 | spin_unlock_bh(&xprt->transport_lock); |
588 | } | 589 | } |
589 | EXPORT_SYMBOL_GPL(xprt_disconnect); | 590 | EXPORT_SYMBOL_GPL(xprt_disconnect_done); |
591 | |||
592 | /** | ||
593 | * xprt_force_disconnect - force a transport to disconnect | ||
594 | * @xprt: transport to disconnect | ||
595 | * | ||
596 | */ | ||
597 | void xprt_force_disconnect(struct rpc_xprt *xprt) | ||
598 | { | ||
599 | /* Don't race with the test_bit() in xprt_clear_locked() */ | ||
600 | spin_lock_bh(&xprt->transport_lock); | ||
601 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
602 | /* Try to schedule an autoclose RPC call */ | ||
603 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | ||
604 | queue_work(rpciod_workqueue, &xprt->task_cleanup); | ||
605 | else if (xprt->snd_task != NULL) | ||
606 | rpc_wake_up_task(xprt->snd_task); | ||
607 | spin_unlock_bh(&xprt->transport_lock); | ||
608 | } | ||
609 | EXPORT_SYMBOL_GPL(xprt_force_disconnect); | ||
590 | 610 | ||
591 | static void | 611 | static void |
592 | xprt_init_autodisconnect(unsigned long data) | 612 | xprt_init_autodisconnect(unsigned long data) |
@@ -909,7 +929,7 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) | |||
909 | { | 929 | { |
910 | struct rpc_rqst *req = task->tk_rqstp; | 930 | struct rpc_rqst *req = task->tk_rqstp; |
911 | 931 | ||
912 | req->rq_timeout = xprt->timeout.to_initval; | 932 | req->rq_timeout = task->tk_client->cl_timeout->to_initval; |
913 | req->rq_task = task; | 933 | req->rq_task = task; |
914 | req->rq_xprt = xprt; | 934 | req->rq_xprt = xprt; |
915 | req->rq_buffer = NULL; | 935 | req->rq_buffer = NULL; |
@@ -959,22 +979,6 @@ void xprt_release(struct rpc_task *task) | |||
959 | } | 979 | } |
960 | 980 | ||
961 | /** | 981 | /** |
962 | * xprt_set_timeout - set constant RPC timeout | ||
963 | * @to: RPC timeout parameters to set up | ||
964 | * @retr: number of retries | ||
965 | * @incr: amount of increase after each retry | ||
966 | * | ||
967 | */ | ||
968 | void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr) | ||
969 | { | ||
970 | to->to_initval = | ||
971 | to->to_increment = incr; | ||
972 | to->to_maxval = to->to_initval + (incr * retr); | ||
973 | to->to_retries = retr; | ||
974 | to->to_exponential = 0; | ||
975 | } | ||
976 | |||
977 | /** | ||
978 | * xprt_create_transport - create an RPC transport | 982 | * xprt_create_transport - create an RPC transport |
979 | * @args: rpc transport creation arguments | 983 | * @args: rpc transport creation arguments |
980 | * | 984 | * |
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 1aa1580cda6d..e55427f73dfe 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -83,7 +83,7 @@ static const char transfertypes[][12] = { | |||
83 | */ | 83 | */ |
84 | 84 | ||
85 | static int | 85 | static int |
86 | rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, | 86 | rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos, |
87 | enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg, int nsegs) | 87 | enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg, int nsegs) |
88 | { | 88 | { |
89 | int len, n = 0, p; | 89 | int len, n = 0, p; |
@@ -169,7 +169,7 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target, | |||
169 | struct rpcrdma_req *req = rpcr_to_rdmar(rqst); | 169 | struct rpcrdma_req *req = rpcr_to_rdmar(rqst); |
170 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_task->tk_xprt); | 170 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_task->tk_xprt); |
171 | int nsegs, nchunks = 0; | 171 | int nsegs, nchunks = 0; |
172 | int pos; | 172 | unsigned int pos; |
173 | struct rpcrdma_mr_seg *seg = req->rl_segments; | 173 | struct rpcrdma_mr_seg *seg = req->rl_segments; |
174 | struct rpcrdma_read_chunk *cur_rchunk = NULL; | 174 | struct rpcrdma_read_chunk *cur_rchunk = NULL; |
175 | struct rpcrdma_write_array *warray = NULL; | 175 | struct rpcrdma_write_array *warray = NULL; |
@@ -213,7 +213,7 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target, | |||
213 | (__be32 *)&cur_rchunk->rc_target.rs_offset, | 213 | (__be32 *)&cur_rchunk->rc_target.rs_offset, |
214 | seg->mr_base); | 214 | seg->mr_base); |
215 | dprintk("RPC: %s: read chunk " | 215 | dprintk("RPC: %s: read chunk " |
216 | "elem %d@0x%llx:0x%x pos %d (%s)\n", __func__, | 216 | "elem %d@0x%llx:0x%x pos %u (%s)\n", __func__, |
217 | seg->mr_len, (unsigned long long)seg->mr_base, | 217 | seg->mr_len, (unsigned long long)seg->mr_base, |
218 | seg->mr_rkey, pos, n < nsegs ? "more" : "last"); | 218 | seg->mr_rkey, pos, n < nsegs ? "more" : "last"); |
219 | cur_rchunk++; | 219 | cur_rchunk++; |
@@ -552,7 +552,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst) | |||
552 | * RDMA'd by server. See map at rpcrdma_create_chunks()! :-) | 552 | * RDMA'd by server. See map at rpcrdma_create_chunks()! :-) |
553 | */ | 553 | */ |
554 | static int | 554 | static int |
555 | rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, __be32 **iptrp) | 555 | rpcrdma_count_chunks(struct rpcrdma_rep *rep, unsigned int max, int wrchunk, __be32 **iptrp) |
556 | { | 556 | { |
557 | unsigned int i, total_len; | 557 | unsigned int i, total_len; |
558 | struct rpcrdma_write_chunk *cur_wchunk; | 558 | struct rpcrdma_write_chunk *cur_wchunk; |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 6f2112dd9f78..02c522c17de5 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
@@ -212,12 +212,16 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt) | |||
212 | static void | 212 | static void |
213 | xprt_rdma_free_addresses(struct rpc_xprt *xprt) | 213 | xprt_rdma_free_addresses(struct rpc_xprt *xprt) |
214 | { | 214 | { |
215 | kfree(xprt->address_strings[RPC_DISPLAY_ADDR]); | 215 | unsigned int i; |
216 | kfree(xprt->address_strings[RPC_DISPLAY_PORT]); | 216 | |
217 | kfree(xprt->address_strings[RPC_DISPLAY_ALL]); | 217 | for (i = 0; i < RPC_DISPLAY_MAX; i++) |
218 | kfree(xprt->address_strings[RPC_DISPLAY_HEX_ADDR]); | 218 | switch (i) { |
219 | kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]); | 219 | case RPC_DISPLAY_PROTO: |
220 | kfree(xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR]); | 220 | case RPC_DISPLAY_NETID: |
221 | continue; | ||
222 | default: | ||
223 | kfree(xprt->address_strings[i]); | ||
224 | } | ||
221 | } | 225 | } |
222 | 226 | ||
223 | static void | 227 | static void |
@@ -289,6 +293,11 @@ xprt_rdma_destroy(struct rpc_xprt *xprt) | |||
289 | module_put(THIS_MODULE); | 293 | module_put(THIS_MODULE); |
290 | } | 294 | } |
291 | 295 | ||
296 | static const struct rpc_timeout xprt_rdma_default_timeout = { | ||
297 | .to_initval = 60 * HZ, | ||
298 | .to_maxval = 60 * HZ, | ||
299 | }; | ||
300 | |||
292 | /** | 301 | /** |
293 | * xprt_setup_rdma - Set up transport to use RDMA | 302 | * xprt_setup_rdma - Set up transport to use RDMA |
294 | * | 303 | * |
@@ -327,7 +336,7 @@ xprt_setup_rdma(struct xprt_create *args) | |||
327 | } | 336 | } |
328 | 337 | ||
329 | /* 60 second timeout, no retries */ | 338 | /* 60 second timeout, no retries */ |
330 | xprt_set_timeout(&xprt->timeout, 0, 60UL * HZ); | 339 | xprt->timeout = &xprt_rdma_default_timeout; |
331 | xprt->bind_timeout = (60U * HZ); | 340 | xprt->bind_timeout = (60U * HZ); |
332 | xprt->connect_timeout = (60U * HZ); | 341 | xprt->connect_timeout = (60U * HZ); |
333 | xprt->reestablish_timeout = (5U * HZ); | 342 | xprt->reestablish_timeout = (5U * HZ); |
@@ -449,7 +458,7 @@ xprt_rdma_close(struct rpc_xprt *xprt) | |||
449 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); | 458 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); |
450 | 459 | ||
451 | dprintk("RPC: %s: closing\n", __func__); | 460 | dprintk("RPC: %s: closing\n", __func__); |
452 | xprt_disconnect(xprt); | 461 | xprt_disconnect_done(xprt); |
453 | (void) rpcrdma_ep_disconnect(&r_xprt->rx_ep, &r_xprt->rx_ia); | 462 | (void) rpcrdma_ep_disconnect(&r_xprt->rx_ep, &r_xprt->rx_ia); |
454 | } | 463 | } |
455 | 464 | ||
@@ -682,7 +691,7 @@ xprt_rdma_send_request(struct rpc_task *task) | |||
682 | } | 691 | } |
683 | 692 | ||
684 | if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) { | 693 | if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) { |
685 | xprt_disconnect(xprt); | 694 | xprt_disconnect_done(xprt); |
686 | return -ENOTCONN; /* implies disconnect */ | 695 | return -ENOTCONN; /* implies disconnect */ |
687 | } | 696 | } |
688 | 697 | ||
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 44b0fb942e8d..ffbf22a1d2ca 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -522,7 +522,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia, | |||
522 | struct rpcrdma_create_data_internal *cdata) | 522 | struct rpcrdma_create_data_internal *cdata) |
523 | { | 523 | { |
524 | struct ib_device_attr devattr; | 524 | struct ib_device_attr devattr; |
525 | int rc; | 525 | int rc, err; |
526 | 526 | ||
527 | rc = ib_query_device(ia->ri_id->device, &devattr); | 527 | rc = ib_query_device(ia->ri_id->device, &devattr); |
528 | if (rc) { | 528 | if (rc) { |
@@ -648,8 +648,10 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia, | |||
648 | return 0; | 648 | return 0; |
649 | 649 | ||
650 | out2: | 650 | out2: |
651 | if (ib_destroy_cq(ep->rep_cq)) | 651 | err = ib_destroy_cq(ep->rep_cq); |
652 | ; | 652 | if (err) |
653 | dprintk("RPC: %s: ib_destroy_cq returned %i\n", | ||
654 | __func__, err); | ||
653 | out1: | 655 | out1: |
654 | return rc; | 656 | return rc; |
655 | } | 657 | } |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 6fa52f44de0f..30e7ac243a90 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -280,7 +280,9 @@ static inline struct sockaddr_in6 *xs_addr_in6(struct rpc_xprt *xprt) | |||
280 | return (struct sockaddr_in6 *) &xprt->addr; | 280 | return (struct sockaddr_in6 *) &xprt->addr; |
281 | } | 281 | } |
282 | 282 | ||
283 | static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt) | 283 | static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt, |
284 | const char *protocol, | ||
285 | const char *netid) | ||
284 | { | 286 | { |
285 | struct sockaddr_in *addr = xs_addr_in(xprt); | 287 | struct sockaddr_in *addr = xs_addr_in(xprt); |
286 | char *buf; | 288 | char *buf; |
@@ -299,21 +301,14 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt) | |||
299 | } | 301 | } |
300 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; | 302 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; |
301 | 303 | ||
302 | buf = kzalloc(8, GFP_KERNEL); | 304 | xprt->address_strings[RPC_DISPLAY_PROTO] = protocol; |
303 | if (buf) { | ||
304 | if (xprt->prot == IPPROTO_UDP) | ||
305 | snprintf(buf, 8, "udp"); | ||
306 | else | ||
307 | snprintf(buf, 8, "tcp"); | ||
308 | } | ||
309 | xprt->address_strings[RPC_DISPLAY_PROTO] = buf; | ||
310 | 305 | ||
311 | buf = kzalloc(48, GFP_KERNEL); | 306 | buf = kzalloc(48, GFP_KERNEL); |
312 | if (buf) { | 307 | if (buf) { |
313 | snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s", | 308 | snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s", |
314 | NIPQUAD(addr->sin_addr.s_addr), | 309 | NIPQUAD(addr->sin_addr.s_addr), |
315 | ntohs(addr->sin_port), | 310 | ntohs(addr->sin_port), |
316 | xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | 311 | protocol); |
317 | } | 312 | } |
318 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; | 313 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; |
319 | 314 | ||
@@ -340,12 +335,12 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt) | |||
340 | } | 335 | } |
341 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | 336 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; |
342 | 337 | ||
343 | xprt->address_strings[RPC_DISPLAY_NETID] = | 338 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; |
344 | kstrdup(xprt->prot == IPPROTO_UDP ? | ||
345 | RPCBIND_NETID_UDP : RPCBIND_NETID_TCP, GFP_KERNEL); | ||
346 | } | 339 | } |
347 | 340 | ||
348 | static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt) | 341 | static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt, |
342 | const char *protocol, | ||
343 | const char *netid) | ||
349 | { | 344 | { |
350 | struct sockaddr_in6 *addr = xs_addr_in6(xprt); | 345 | struct sockaddr_in6 *addr = xs_addr_in6(xprt); |
351 | char *buf; | 346 | char *buf; |
@@ -364,21 +359,14 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt) | |||
364 | } | 359 | } |
365 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; | 360 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; |
366 | 361 | ||
367 | buf = kzalloc(8, GFP_KERNEL); | 362 | xprt->address_strings[RPC_DISPLAY_PROTO] = protocol; |
368 | if (buf) { | ||
369 | if (xprt->prot == IPPROTO_UDP) | ||
370 | snprintf(buf, 8, "udp"); | ||
371 | else | ||
372 | snprintf(buf, 8, "tcp"); | ||
373 | } | ||
374 | xprt->address_strings[RPC_DISPLAY_PROTO] = buf; | ||
375 | 363 | ||
376 | buf = kzalloc(64, GFP_KERNEL); | 364 | buf = kzalloc(64, GFP_KERNEL); |
377 | if (buf) { | 365 | if (buf) { |
378 | snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s", | 366 | snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s", |
379 | NIP6(addr->sin6_addr), | 367 | NIP6(addr->sin6_addr), |
380 | ntohs(addr->sin6_port), | 368 | ntohs(addr->sin6_port), |
381 | xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | 369 | protocol); |
382 | } | 370 | } |
383 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; | 371 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; |
384 | 372 | ||
@@ -405,17 +393,21 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt) | |||
405 | } | 393 | } |
406 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | 394 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; |
407 | 395 | ||
408 | xprt->address_strings[RPC_DISPLAY_NETID] = | 396 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; |
409 | kstrdup(xprt->prot == IPPROTO_UDP ? | ||
410 | RPCBIND_NETID_UDP6 : RPCBIND_NETID_TCP6, GFP_KERNEL); | ||
411 | } | 397 | } |
412 | 398 | ||
413 | static void xs_free_peer_addresses(struct rpc_xprt *xprt) | 399 | static void xs_free_peer_addresses(struct rpc_xprt *xprt) |
414 | { | 400 | { |
415 | int i; | 401 | unsigned int i; |
416 | 402 | ||
417 | for (i = 0; i < RPC_DISPLAY_MAX; i++) | 403 | for (i = 0; i < RPC_DISPLAY_MAX; i++) |
418 | kfree(xprt->address_strings[i]); | 404 | switch (i) { |
405 | case RPC_DISPLAY_PROTO: | ||
406 | case RPC_DISPLAY_NETID: | ||
407 | continue; | ||
408 | default: | ||
409 | kfree(xprt->address_strings[i]); | ||
410 | } | ||
419 | } | 411 | } |
420 | 412 | ||
421 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) | 413 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) |
@@ -614,6 +606,22 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
614 | return status; | 606 | return status; |
615 | } | 607 | } |
616 | 608 | ||
609 | /** | ||
610 | * xs_tcp_shutdown - gracefully shut down a TCP socket | ||
611 | * @xprt: transport | ||
612 | * | ||
613 | * Initiates a graceful shutdown of the TCP socket by calling the | ||
614 | * equivalent of shutdown(SHUT_WR); | ||
615 | */ | ||
616 | static void xs_tcp_shutdown(struct rpc_xprt *xprt) | ||
617 | { | ||
618 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
619 | struct socket *sock = transport->sock; | ||
620 | |||
621 | if (sock != NULL) | ||
622 | kernel_sock_shutdown(sock, SHUT_WR); | ||
623 | } | ||
624 | |||
617 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) | 625 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) |
618 | { | 626 | { |
619 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | 627 | u32 reclen = buf->len - sizeof(rpc_fraghdr); |
@@ -691,7 +699,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
691 | default: | 699 | default: |
692 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | 700 | dprintk("RPC: sendmsg returned unrecognized error %d\n", |
693 | -status); | 701 | -status); |
694 | xprt_disconnect(xprt); | 702 | xs_tcp_shutdown(xprt); |
695 | break; | 703 | break; |
696 | } | 704 | } |
697 | 705 | ||
@@ -759,7 +767,9 @@ static void xs_close(struct rpc_xprt *xprt) | |||
759 | clear_close_wait: | 767 | clear_close_wait: |
760 | smp_mb__before_clear_bit(); | 768 | smp_mb__before_clear_bit(); |
761 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | 769 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); |
770 | clear_bit(XPRT_CLOSING, &xprt->state); | ||
762 | smp_mb__after_clear_bit(); | 771 | smp_mb__after_clear_bit(); |
772 | xprt_disconnect_done(xprt); | ||
763 | } | 773 | } |
764 | 774 | ||
765 | /** | 775 | /** |
@@ -775,7 +785,6 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
775 | 785 | ||
776 | cancel_rearming_delayed_work(&transport->connect_worker); | 786 | cancel_rearming_delayed_work(&transport->connect_worker); |
777 | 787 | ||
778 | xprt_disconnect(xprt); | ||
779 | xs_close(xprt); | 788 | xs_close(xprt); |
780 | xs_free_peer_addresses(xprt); | 789 | xs_free_peer_addresses(xprt); |
781 | kfree(xprt->slot); | 790 | kfree(xprt->slot); |
@@ -886,7 +895,7 @@ static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_rea | |||
886 | /* Sanity check of the record length */ | 895 | /* Sanity check of the record length */ |
887 | if (unlikely(transport->tcp_reclen < 4)) { | 896 | if (unlikely(transport->tcp_reclen < 4)) { |
888 | dprintk("RPC: invalid TCP record fragment length\n"); | 897 | dprintk("RPC: invalid TCP record fragment length\n"); |
889 | xprt_disconnect(xprt); | 898 | xprt_force_disconnect(xprt); |
890 | return; | 899 | return; |
891 | } | 900 | } |
892 | dprintk("RPC: reading TCP record fragment of length %d\n", | 901 | dprintk("RPC: reading TCP record fragment of length %d\n", |
@@ -1113,21 +1122,44 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1113 | transport->tcp_flags = | 1122 | transport->tcp_flags = |
1114 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; | 1123 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; |
1115 | 1124 | ||
1116 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
1117 | xprt_wake_pending_tasks(xprt, 0); | 1125 | xprt_wake_pending_tasks(xprt, 0); |
1118 | } | 1126 | } |
1119 | spin_unlock_bh(&xprt->transport_lock); | 1127 | spin_unlock_bh(&xprt->transport_lock); |
1120 | break; | 1128 | break; |
1121 | case TCP_SYN_SENT: | 1129 | case TCP_FIN_WAIT1: |
1122 | case TCP_SYN_RECV: | 1130 | /* The client initiated a shutdown of the socket */ |
1131 | xprt->reestablish_timeout = 0; | ||
1132 | set_bit(XPRT_CLOSING, &xprt->state); | ||
1133 | smp_mb__before_clear_bit(); | ||
1134 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
1135 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
1136 | smp_mb__after_clear_bit(); | ||
1123 | break; | 1137 | break; |
1124 | case TCP_CLOSE_WAIT: | 1138 | case TCP_CLOSE_WAIT: |
1125 | /* Try to schedule an autoclose RPC calls */ | 1139 | /* The server initiated a shutdown of the socket */ |
1126 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | 1140 | set_bit(XPRT_CLOSING, &xprt->state); |
1127 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | 1141 | xprt_force_disconnect(xprt); |
1128 | queue_work(rpciod_workqueue, &xprt->task_cleanup); | 1142 | case TCP_SYN_SENT: |
1129 | default: | 1143 | case TCP_CLOSING: |
1130 | xprt_disconnect(xprt); | 1144 | /* |
1145 | * If the server closed down the connection, make sure that | ||
1146 | * we back off before reconnecting | ||
1147 | */ | ||
1148 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | ||
1149 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
1150 | break; | ||
1151 | case TCP_LAST_ACK: | ||
1152 | smp_mb__before_clear_bit(); | ||
1153 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
1154 | smp_mb__after_clear_bit(); | ||
1155 | break; | ||
1156 | case TCP_CLOSE: | ||
1157 | smp_mb__before_clear_bit(); | ||
1158 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
1159 | clear_bit(XPRT_CLOSING, &xprt->state); | ||
1160 | smp_mb__after_clear_bit(); | ||
1161 | /* Mark transport as closed and wake up all pending tasks */ | ||
1162 | xprt_disconnect_done(xprt); | ||
1131 | } | 1163 | } |
1132 | out: | 1164 | out: |
1133 | read_unlock(&sk->sk_callback_lock); | 1165 | read_unlock(&sk->sk_callback_lock); |
@@ -1279,34 +1311,53 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | |||
1279 | } | 1311 | } |
1280 | } | 1312 | } |
1281 | 1313 | ||
1314 | static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket *sock) | ||
1315 | { | ||
1316 | unsigned short port = transport->port; | ||
1317 | |||
1318 | if (port == 0 && transport->xprt.resvport) | ||
1319 | port = xs_get_random_port(); | ||
1320 | return port; | ||
1321 | } | ||
1322 | |||
1323 | static unsigned short xs_next_srcport(struct sock_xprt *transport, struct socket *sock, unsigned short port) | ||
1324 | { | ||
1325 | if (transport->port != 0) | ||
1326 | transport->port = 0; | ||
1327 | if (!transport->xprt.resvport) | ||
1328 | return 0; | ||
1329 | if (port <= xprt_min_resvport || port > xprt_max_resvport) | ||
1330 | return xprt_max_resvport; | ||
1331 | return --port; | ||
1332 | } | ||
1333 | |||
1282 | static int xs_bind4(struct sock_xprt *transport, struct socket *sock) | 1334 | static int xs_bind4(struct sock_xprt *transport, struct socket *sock) |
1283 | { | 1335 | { |
1284 | struct sockaddr_in myaddr = { | 1336 | struct sockaddr_in myaddr = { |
1285 | .sin_family = AF_INET, | 1337 | .sin_family = AF_INET, |
1286 | }; | 1338 | }; |
1287 | struct sockaddr_in *sa; | 1339 | struct sockaddr_in *sa; |
1288 | int err; | 1340 | int err, nloop = 0; |
1289 | unsigned short port = transport->port; | 1341 | unsigned short port = xs_get_srcport(transport, sock); |
1342 | unsigned short last; | ||
1290 | 1343 | ||
1291 | if (!transport->xprt.resvport) | ||
1292 | port = 0; | ||
1293 | sa = (struct sockaddr_in *)&transport->addr; | 1344 | sa = (struct sockaddr_in *)&transport->addr; |
1294 | myaddr.sin_addr = sa->sin_addr; | 1345 | myaddr.sin_addr = sa->sin_addr; |
1295 | do { | 1346 | do { |
1296 | myaddr.sin_port = htons(port); | 1347 | myaddr.sin_port = htons(port); |
1297 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1348 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, |
1298 | sizeof(myaddr)); | 1349 | sizeof(myaddr)); |
1299 | if (!transport->xprt.resvport) | 1350 | if (port == 0) |
1300 | break; | 1351 | break; |
1301 | if (err == 0) { | 1352 | if (err == 0) { |
1302 | transport->port = port; | 1353 | transport->port = port; |
1303 | break; | 1354 | break; |
1304 | } | 1355 | } |
1305 | if (port <= xprt_min_resvport) | 1356 | last = port; |
1306 | port = xprt_max_resvport; | 1357 | port = xs_next_srcport(transport, sock, port); |
1307 | else | 1358 | if (port > last) |
1308 | port--; | 1359 | nloop++; |
1309 | } while (err == -EADDRINUSE && port != transport->port); | 1360 | } while (err == -EADDRINUSE && nloop != 2); |
1310 | dprintk("RPC: %s "NIPQUAD_FMT":%u: %s (%d)\n", | 1361 | dprintk("RPC: %s "NIPQUAD_FMT":%u: %s (%d)\n", |
1311 | __FUNCTION__, NIPQUAD(myaddr.sin_addr), | 1362 | __FUNCTION__, NIPQUAD(myaddr.sin_addr), |
1312 | port, err ? "failed" : "ok", err); | 1363 | port, err ? "failed" : "ok", err); |
@@ -1319,28 +1370,27 @@ static int xs_bind6(struct sock_xprt *transport, struct socket *sock) | |||
1319 | .sin6_family = AF_INET6, | 1370 | .sin6_family = AF_INET6, |
1320 | }; | 1371 | }; |
1321 | struct sockaddr_in6 *sa; | 1372 | struct sockaddr_in6 *sa; |
1322 | int err; | 1373 | int err, nloop = 0; |
1323 | unsigned short port = transport->port; | 1374 | unsigned short port = xs_get_srcport(transport, sock); |
1375 | unsigned short last; | ||
1324 | 1376 | ||
1325 | if (!transport->xprt.resvport) | ||
1326 | port = 0; | ||
1327 | sa = (struct sockaddr_in6 *)&transport->addr; | 1377 | sa = (struct sockaddr_in6 *)&transport->addr; |
1328 | myaddr.sin6_addr = sa->sin6_addr; | 1378 | myaddr.sin6_addr = sa->sin6_addr; |
1329 | do { | 1379 | do { |
1330 | myaddr.sin6_port = htons(port); | 1380 | myaddr.sin6_port = htons(port); |
1331 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1381 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, |
1332 | sizeof(myaddr)); | 1382 | sizeof(myaddr)); |
1333 | if (!transport->xprt.resvport) | 1383 | if (port == 0) |
1334 | break; | 1384 | break; |
1335 | if (err == 0) { | 1385 | if (err == 0) { |
1336 | transport->port = port; | 1386 | transport->port = port; |
1337 | break; | 1387 | break; |
1338 | } | 1388 | } |
1339 | if (port <= xprt_min_resvport) | 1389 | last = port; |
1340 | port = xprt_max_resvport; | 1390 | port = xs_next_srcport(transport, sock, port); |
1341 | else | 1391 | if (port > last) |
1342 | port--; | 1392 | nloop++; |
1343 | } while (err == -EADDRINUSE && port != transport->port); | 1393 | } while (err == -EADDRINUSE && nloop != 2); |
1344 | dprintk("RPC: xs_bind6 "NIP6_FMT":%u: %s (%d)\n", | 1394 | dprintk("RPC: xs_bind6 "NIP6_FMT":%u: %s (%d)\n", |
1345 | NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err); | 1395 | NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err); |
1346 | return err; | 1396 | return err; |
@@ -1602,8 +1652,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work) | |||
1602 | break; | 1652 | break; |
1603 | default: | 1653 | default: |
1604 | /* get rid of existing socket, and retry */ | 1654 | /* get rid of existing socket, and retry */ |
1605 | xs_close(xprt); | 1655 | xs_tcp_shutdown(xprt); |
1606 | break; | ||
1607 | } | 1656 | } |
1608 | } | 1657 | } |
1609 | out: | 1658 | out: |
@@ -1662,8 +1711,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work) | |||
1662 | break; | 1711 | break; |
1663 | default: | 1712 | default: |
1664 | /* get rid of existing socket, and retry */ | 1713 | /* get rid of existing socket, and retry */ |
1665 | xs_close(xprt); | 1714 | xs_tcp_shutdown(xprt); |
1666 | break; | ||
1667 | } | 1715 | } |
1668 | } | 1716 | } |
1669 | out: | 1717 | out: |
@@ -1710,6 +1758,19 @@ static void xs_connect(struct rpc_task *task) | |||
1710 | } | 1758 | } |
1711 | } | 1759 | } |
1712 | 1760 | ||
1761 | static void xs_tcp_connect(struct rpc_task *task) | ||
1762 | { | ||
1763 | struct rpc_xprt *xprt = task->tk_xprt; | ||
1764 | |||
1765 | /* Initiate graceful shutdown of the socket if not already done */ | ||
1766 | if (test_bit(XPRT_CONNECTED, &xprt->state)) | ||
1767 | xs_tcp_shutdown(xprt); | ||
1768 | /* Exit if we need to wait for socket shutdown to complete */ | ||
1769 | if (test_bit(XPRT_CLOSING, &xprt->state)) | ||
1770 | return; | ||
1771 | xs_connect(task); | ||
1772 | } | ||
1773 | |||
1713 | /** | 1774 | /** |
1714 | * xs_udp_print_stats - display UDP socket-specifc stats | 1775 | * xs_udp_print_stats - display UDP socket-specifc stats |
1715 | * @xprt: rpc_xprt struct containing statistics | 1776 | * @xprt: rpc_xprt struct containing statistics |
@@ -1780,12 +1841,12 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
1780 | .release_xprt = xs_tcp_release_xprt, | 1841 | .release_xprt = xs_tcp_release_xprt, |
1781 | .rpcbind = rpcb_getport_async, | 1842 | .rpcbind = rpcb_getport_async, |
1782 | .set_port = xs_set_port, | 1843 | .set_port = xs_set_port, |
1783 | .connect = xs_connect, | 1844 | .connect = xs_tcp_connect, |
1784 | .buf_alloc = rpc_malloc, | 1845 | .buf_alloc = rpc_malloc, |
1785 | .buf_free = rpc_free, | 1846 | .buf_free = rpc_free, |
1786 | .send_request = xs_tcp_send_request, | 1847 | .send_request = xs_tcp_send_request, |
1787 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | 1848 | .set_retrans_timeout = xprt_set_retrans_timeout_def, |
1788 | .close = xs_close, | 1849 | .close = xs_tcp_shutdown, |
1789 | .destroy = xs_destroy, | 1850 | .destroy = xs_destroy, |
1790 | .print_stats = xs_tcp_print_stats, | 1851 | .print_stats = xs_tcp_print_stats, |
1791 | }; | 1852 | }; |
@@ -1822,11 +1883,17 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
1822 | xprt->addrlen = args->addrlen; | 1883 | xprt->addrlen = args->addrlen; |
1823 | if (args->srcaddr) | 1884 | if (args->srcaddr) |
1824 | memcpy(&new->addr, args->srcaddr, args->addrlen); | 1885 | memcpy(&new->addr, args->srcaddr, args->addrlen); |
1825 | new->port = xs_get_random_port(); | ||
1826 | 1886 | ||
1827 | return xprt; | 1887 | return xprt; |
1828 | } | 1888 | } |
1829 | 1889 | ||
1890 | static const struct rpc_timeout xs_udp_default_timeout = { | ||
1891 | .to_initval = 5 * HZ, | ||
1892 | .to_maxval = 30 * HZ, | ||
1893 | .to_increment = 5 * HZ, | ||
1894 | .to_retries = 5, | ||
1895 | }; | ||
1896 | |||
1830 | /** | 1897 | /** |
1831 | * xs_setup_udp - Set up transport to use a UDP socket | 1898 | * xs_setup_udp - Set up transport to use a UDP socket |
1832 | * @args: rpc transport creation arguments | 1899 | * @args: rpc transport creation arguments |
@@ -1855,10 +1922,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1855 | 1922 | ||
1856 | xprt->ops = &xs_udp_ops; | 1923 | xprt->ops = &xs_udp_ops; |
1857 | 1924 | ||
1858 | if (args->timeout) | 1925 | xprt->timeout = &xs_udp_default_timeout; |
1859 | xprt->timeout = *args->timeout; | ||
1860 | else | ||
1861 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); | ||
1862 | 1926 | ||
1863 | switch (addr->sa_family) { | 1927 | switch (addr->sa_family) { |
1864 | case AF_INET: | 1928 | case AF_INET: |
@@ -1867,7 +1931,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1867 | 1931 | ||
1868 | INIT_DELAYED_WORK(&transport->connect_worker, | 1932 | INIT_DELAYED_WORK(&transport->connect_worker, |
1869 | xs_udp_connect_worker4); | 1933 | xs_udp_connect_worker4); |
1870 | xs_format_ipv4_peer_addresses(xprt); | 1934 | xs_format_ipv4_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP); |
1871 | break; | 1935 | break; |
1872 | case AF_INET6: | 1936 | case AF_INET6: |
1873 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) | 1937 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) |
@@ -1875,7 +1939,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1875 | 1939 | ||
1876 | INIT_DELAYED_WORK(&transport->connect_worker, | 1940 | INIT_DELAYED_WORK(&transport->connect_worker, |
1877 | xs_udp_connect_worker6); | 1941 | xs_udp_connect_worker6); |
1878 | xs_format_ipv6_peer_addresses(xprt); | 1942 | xs_format_ipv6_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6); |
1879 | break; | 1943 | break; |
1880 | default: | 1944 | default: |
1881 | kfree(xprt); | 1945 | kfree(xprt); |
@@ -1893,6 +1957,12 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1893 | return ERR_PTR(-EINVAL); | 1957 | return ERR_PTR(-EINVAL); |
1894 | } | 1958 | } |
1895 | 1959 | ||
1960 | static const struct rpc_timeout xs_tcp_default_timeout = { | ||
1961 | .to_initval = 60 * HZ, | ||
1962 | .to_maxval = 60 * HZ, | ||
1963 | .to_retries = 2, | ||
1964 | }; | ||
1965 | |||
1896 | /** | 1966 | /** |
1897 | * xs_setup_tcp - Set up transport to use a TCP socket | 1967 | * xs_setup_tcp - Set up transport to use a TCP socket |
1898 | * @args: rpc transport creation arguments | 1968 | * @args: rpc transport creation arguments |
@@ -1919,11 +1989,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
1919 | xprt->idle_timeout = XS_IDLE_DISC_TO; | 1989 | xprt->idle_timeout = XS_IDLE_DISC_TO; |
1920 | 1990 | ||
1921 | xprt->ops = &xs_tcp_ops; | 1991 | xprt->ops = &xs_tcp_ops; |
1922 | 1992 | xprt->timeout = &xs_tcp_default_timeout; | |
1923 | if (args->timeout) | ||
1924 | xprt->timeout = *args->timeout; | ||
1925 | else | ||
1926 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); | ||
1927 | 1993 | ||
1928 | switch (addr->sa_family) { | 1994 | switch (addr->sa_family) { |
1929 | case AF_INET: | 1995 | case AF_INET: |
@@ -1931,14 +1997,14 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
1931 | xprt_set_bound(xprt); | 1997 | xprt_set_bound(xprt); |
1932 | 1998 | ||
1933 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); | 1999 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); |
1934 | xs_format_ipv4_peer_addresses(xprt); | 2000 | xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP); |
1935 | break; | 2001 | break; |
1936 | case AF_INET6: | 2002 | case AF_INET6: |
1937 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) | 2003 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) |
1938 | xprt_set_bound(xprt); | 2004 | xprt_set_bound(xprt); |
1939 | 2005 | ||
1940 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6); | 2006 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6); |
1941 | xs_format_ipv6_peer_addresses(xprt); | 2007 | xs_format_ipv6_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6); |
1942 | break; | 2008 | break; |
1943 | default: | 2009 | default: |
1944 | kfree(xprt); | 2010 | kfree(xprt); |