aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/addr.c10
-rw-r--r--net/sunrpc/auth.c45
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c6
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seqnum.c4
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c4
-rw-r--r--net/sunrpc/cache.c5
-rw-r--r--net/sunrpc/clnt.c54
-rw-r--r--net/sunrpc/rpcb_clnt.c104
-rw-r--r--net/sunrpc/sched.c15
-rw-r--r--net/sunrpc/sunrpc_syms.c3
-rw-r--r--net/sunrpc/svc.c5
-rw-r--r--net/sunrpc/svc_xprt.c8
-rw-r--r--net/sunrpc/svcauth.c4
-rw-r--r--net/sunrpc/svcauth_unix.c7
-rw-r--r--net/sunrpc/svcsock.c8
-rw-r--r--net/sunrpc/sysctl.c15
-rw-r--r--net/sunrpc/xprt.c4
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma.c40
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c7
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c2
-rw-r--r--net/sunrpc/xprtrdma/transport.c32
-rw-r--r--net/sunrpc/xprtrdma/verbs.c4
-rw-r--r--net/sunrpc/xprtsock.c30
23 files changed, 245 insertions, 171 deletions
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
index c7450c8f0a7c..6dcdd2517819 100644
--- a/net/sunrpc/addr.c
+++ b/net/sunrpc/addr.c
@@ -55,16 +55,8 @@ static size_t rpc_ntop6_noscopeid(const struct sockaddr *sap,
55 55
56 /* 56 /*
57 * RFC 4291, Section 2.2.1 57 * RFC 4291, Section 2.2.1
58 *
59 * To keep the result as short as possible, especially
60 * since we don't shorthand, we don't want leading zeros
61 * in each halfword, so avoid %pI6.
62 */ 58 */
63 return snprintf(buf, buflen, "%x:%x:%x:%x:%x:%x:%x:%x", 59 return snprintf(buf, buflen, "%pI6c", addr);
64 ntohs(addr->s6_addr16[0]), ntohs(addr->s6_addr16[1]),
65 ntohs(addr->s6_addr16[2]), ntohs(addr->s6_addr16[3]),
66 ntohs(addr->s6_addr16[4]), ntohs(addr->s6_addr16[5]),
67 ntohs(addr->s6_addr16[6]), ntohs(addr->s6_addr16[7]));
68} 60}
69 61
70static size_t rpc_ntop6(const struct sockaddr *sap, 62static size_t rpc_ntop6(const struct sockaddr *sap,
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 54a4e042f104..f394fc190a49 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -123,16 +123,19 @@ rpcauth_unhash_cred_locked(struct rpc_cred *cred)
123 clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); 123 clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
124} 124}
125 125
126static void 126static int
127rpcauth_unhash_cred(struct rpc_cred *cred) 127rpcauth_unhash_cred(struct rpc_cred *cred)
128{ 128{
129 spinlock_t *cache_lock; 129 spinlock_t *cache_lock;
130 int ret;
130 131
131 cache_lock = &cred->cr_auth->au_credcache->lock; 132 cache_lock = &cred->cr_auth->au_credcache->lock;
132 spin_lock(cache_lock); 133 spin_lock(cache_lock);
133 if (atomic_read(&cred->cr_count) == 0) 134 ret = atomic_read(&cred->cr_count) == 0;
135 if (ret)
134 rpcauth_unhash_cred_locked(cred); 136 rpcauth_unhash_cred_locked(cred);
135 spin_unlock(cache_lock); 137 spin_unlock(cache_lock);
138 return ret;
136} 139}
137 140
138/* 141/*
@@ -332,9 +335,9 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
332 list_add_tail(&new->cr_lru, &free); 335 list_add_tail(&new->cr_lru, &free);
333 spin_unlock(&cache->lock); 336 spin_unlock(&cache->lock);
334found: 337found:
335 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) 338 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
336 && cred->cr_ops->cr_init != NULL 339 cred->cr_ops->cr_init != NULL &&
337 && !(flags & RPCAUTH_LOOKUP_NEW)) { 340 !(flags & RPCAUTH_LOOKUP_NEW)) {
338 int res = cred->cr_ops->cr_init(auth, cred); 341 int res = cred->cr_ops->cr_init(auth, cred);
339 if (res < 0) { 342 if (res < 0) {
340 put_rpccred(cred); 343 put_rpccred(cred);
@@ -446,31 +449,35 @@ void
446put_rpccred(struct rpc_cred *cred) 449put_rpccred(struct rpc_cred *cred)
447{ 450{
448 /* Fast path for unhashed credentials */ 451 /* Fast path for unhashed credentials */
449 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) 452 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) == 0) {
450 goto need_lock; 453 if (atomic_dec_and_test(&cred->cr_count))
451 454 cred->cr_ops->crdestroy(cred);
452 if (!atomic_dec_and_test(&cred->cr_count))
453 return; 455 return;
454 goto out_destroy; 456 }
455need_lock: 457
456 if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock)) 458 if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock))
457 return; 459 return;
458 if (!list_empty(&cred->cr_lru)) { 460 if (!list_empty(&cred->cr_lru)) {
459 number_cred_unused--; 461 number_cred_unused--;
460 list_del_init(&cred->cr_lru); 462 list_del_init(&cred->cr_lru);
461 } 463 }
462 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
463 rpcauth_unhash_cred(cred);
464 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { 464 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) {
465 cred->cr_expire = jiffies; 465 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) {
466 list_add_tail(&cred->cr_lru, &cred_unused); 466 cred->cr_expire = jiffies;
467 number_cred_unused++; 467 list_add_tail(&cred->cr_lru, &cred_unused);
468 spin_unlock(&rpc_credcache_lock); 468 number_cred_unused++;
469 return; 469 goto out_nodestroy;
470 }
471 if (!rpcauth_unhash_cred(cred)) {
472 /* We were hashed and someone looked us up... */
473 goto out_nodestroy;
474 }
470 } 475 }
471 spin_unlock(&rpc_credcache_lock); 476 spin_unlock(&rpc_credcache_lock);
472out_destroy:
473 cred->cr_ops->crdestroy(cred); 477 cred->cr_ops->crdestroy(cred);
478 return;
479out_nodestroy:
480 spin_unlock(&rpc_credcache_lock);
474} 481}
475EXPORT_SYMBOL_GPL(put_rpccred); 482EXPORT_SYMBOL_GPL(put_rpccred);
476 483
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index fc6a43ccd950..3c3c50f38a1c 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -304,7 +304,7 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid)
304 * to that upcall instead of adding the new upcall. 304 * to that upcall instead of adding the new upcall.
305 */ 305 */
306static inline struct gss_upcall_msg * 306static inline struct gss_upcall_msg *
307gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) 307gss_add_msg(struct gss_upcall_msg *gss_msg)
308{ 308{
309 struct rpc_inode *rpci = gss_msg->inode; 309 struct rpc_inode *rpci = gss_msg->inode;
310 struct inode *inode = &rpci->vfs_inode; 310 struct inode *inode = &rpci->vfs_inode;
@@ -445,7 +445,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr
445 gss_new = gss_alloc_msg(gss_auth, uid, clnt, gss_cred->gc_machine_cred); 445 gss_new = gss_alloc_msg(gss_auth, uid, clnt, gss_cred->gc_machine_cred);
446 if (IS_ERR(gss_new)) 446 if (IS_ERR(gss_new))
447 return gss_new; 447 return gss_new;
448 gss_msg = gss_add_msg(gss_auth, gss_new); 448 gss_msg = gss_add_msg(gss_new);
449 if (gss_msg == gss_new) { 449 if (gss_msg == gss_new) {
450 struct inode *inode = &gss_new->inode->vfs_inode; 450 struct inode *inode = &gss_new->inode->vfs_inode;
451 int res = rpc_queue_upcall(inode, &gss_new->msg); 451 int res = rpc_queue_upcall(inode, &gss_new->msg);
@@ -485,7 +485,7 @@ gss_refresh_upcall(struct rpc_task *task)
485 dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, 485 dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
486 cred->cr_uid); 486 cred->cr_uid);
487 gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); 487 gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
488 if (IS_ERR(gss_msg) == -EAGAIN) { 488 if (PTR_ERR(gss_msg) == -EAGAIN) {
489 /* XXX: warning on the first, under the assumption we 489 /* XXX: warning on the first, under the assumption we
490 * shouldn't normally hit this case on a refresh. */ 490 * shouldn't normally hit this case on a refresh. */
491 warn_gssd(); 491 warn_gssd();
diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
index f160be6c1a46..17562b4c35f6 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
@@ -75,8 +75,8 @@ krb5_get_seq_num(struct crypto_blkcipher *key,
75 if ((code = krb5_decrypt(key, cksum, buf, plain, 8))) 75 if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
76 return code; 76 return code;
77 77
78 if ((plain[4] != plain[5]) || (plain[4] != plain[6]) 78 if ((plain[4] != plain[5]) || (plain[4] != plain[6]) ||
79 || (plain[4] != plain[7])) 79 (plain[4] != plain[7]))
80 return (s32)KG_BAD_SEQ; 80 return (s32)KG_BAD_SEQ;
81 81
82 *direction = plain[4]; 82 *direction = plain[4];
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index f6c51e562a02..e34bc531fcb9 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -105,8 +105,8 @@ static int rsi_match(struct cache_head *a, struct cache_head *b)
105{ 105{
106 struct rsi *item = container_of(a, struct rsi, h); 106 struct rsi *item = container_of(a, struct rsi, h);
107 struct rsi *tmp = container_of(b, struct rsi, h); 107 struct rsi *tmp = container_of(b, struct rsi, h);
108 return netobj_equal(&item->in_handle, &tmp->in_handle) 108 return netobj_equal(&item->in_handle, &tmp->in_handle) &&
109 && netobj_equal(&item->in_token, &tmp->in_token); 109 netobj_equal(&item->in_token, &tmp->in_token);
110} 110}
111 111
112static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len) 112static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len)
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index d6eee291a0e2..39bddba53ba1 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -401,9 +401,8 @@ static int cache_clean(void)
401 for (; ch; cp= & ch->next, ch= *cp) { 401 for (; ch; cp= & ch->next, ch= *cp) {
402 if (current_detail->nextcheck > ch->expiry_time) 402 if (current_detail->nextcheck > ch->expiry_time)
403 current_detail->nextcheck = ch->expiry_time+1; 403 current_detail->nextcheck = ch->expiry_time+1;
404 if (ch->expiry_time >= get_seconds() 404 if (ch->expiry_time >= get_seconds() &&
405 && ch->last_refresh >= current_detail->flush_time 405 ch->last_refresh >= current_detail->flush_time)
406 )
407 continue; 406 continue;
408 if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) 407 if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
409 cache_dequeue(current_detail, ch); 408 cache_dequeue(current_detail, ch);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 38829e20500b..154034b675bd 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -79,7 +79,7 @@ static void call_connect_status(struct rpc_task *task);
79 79
80static __be32 *rpc_encode_header(struct rpc_task *task); 80static __be32 *rpc_encode_header(struct rpc_task *task);
81static __be32 *rpc_verify_header(struct rpc_task *task); 81static __be32 *rpc_verify_header(struct rpc_task *task);
82static int rpc_ping(struct rpc_clnt *clnt, int flags); 82static int rpc_ping(struct rpc_clnt *clnt);
83 83
84static void rpc_register_client(struct rpc_clnt *clnt) 84static void rpc_register_client(struct rpc_clnt *clnt)
85{ 85{
@@ -340,7 +340,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
340 return clnt; 340 return clnt;
341 341
342 if (!(args->flags & RPC_CLNT_CREATE_NOPING)) { 342 if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
343 int err = rpc_ping(clnt, RPC_TASK_SOFT); 343 int err = rpc_ping(clnt);
344 if (err != 0) { 344 if (err != 0) {
345 rpc_shutdown_client(clnt); 345 rpc_shutdown_client(clnt);
346 return ERR_PTR(err); 346 return ERR_PTR(err);
@@ -528,7 +528,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
528 clnt->cl_prog = program->number; 528 clnt->cl_prog = program->number;
529 clnt->cl_vers = version->number; 529 clnt->cl_vers = version->number;
530 clnt->cl_stats = program->stats; 530 clnt->cl_stats = program->stats;
531 err = rpc_ping(clnt, RPC_TASK_SOFT); 531 err = rpc_ping(clnt);
532 if (err != 0) { 532 if (err != 0) {
533 rpc_shutdown_client(clnt); 533 rpc_shutdown_client(clnt);
534 clnt = ERR_PTR(err); 534 clnt = ERR_PTR(err);
@@ -1060,7 +1060,7 @@ call_bind_status(struct rpc_task *task)
1060 goto retry_timeout; 1060 goto retry_timeout;
1061 case -EPFNOSUPPORT: 1061 case -EPFNOSUPPORT:
1062 /* server doesn't support any rpcbind version we know of */ 1062 /* server doesn't support any rpcbind version we know of */
1063 dprintk("RPC: %5u remote rpcbind service unavailable\n", 1063 dprintk("RPC: %5u unrecognized remote rpcbind service\n",
1064 task->tk_pid); 1064 task->tk_pid);
1065 break; 1065 break;
1066 case -EPROTONOSUPPORT: 1066 case -EPROTONOSUPPORT:
@@ -1069,6 +1069,21 @@ call_bind_status(struct rpc_task *task)
1069 task->tk_status = 0; 1069 task->tk_status = 0;
1070 task->tk_action = call_bind; 1070 task->tk_action = call_bind;
1071 return; 1071 return;
1072 case -ECONNREFUSED: /* connection problems */
1073 case -ECONNRESET:
1074 case -ENOTCONN:
1075 case -EHOSTDOWN:
1076 case -EHOSTUNREACH:
1077 case -ENETUNREACH:
1078 case -EPIPE:
1079 dprintk("RPC: %5u remote rpcbind unreachable: %d\n",
1080 task->tk_pid, task->tk_status);
1081 if (!RPC_IS_SOFTCONN(task)) {
1082 rpc_delay(task, 5*HZ);
1083 goto retry_timeout;
1084 }
1085 status = task->tk_status;
1086 break;
1072 default: 1087 default:
1073 dprintk("RPC: %5u unrecognized rpcbind error (%d)\n", 1088 dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
1074 task->tk_pid, -task->tk_status); 1089 task->tk_pid, -task->tk_status);
@@ -1180,11 +1195,25 @@ static void
1180call_transmit_status(struct rpc_task *task) 1195call_transmit_status(struct rpc_task *task)
1181{ 1196{
1182 task->tk_action = call_status; 1197 task->tk_action = call_status;
1198
1199 /*
1200 * Common case: success. Force the compiler to put this
1201 * test first.
1202 */
1203 if (task->tk_status == 0) {
1204 xprt_end_transmit(task);
1205 rpc_task_force_reencode(task);
1206 return;
1207 }
1208
1183 switch (task->tk_status) { 1209 switch (task->tk_status) {
1184 case -EAGAIN: 1210 case -EAGAIN:
1185 break; 1211 break;
1186 default: 1212 default:
1213 dprint_status(task);
1187 xprt_end_transmit(task); 1214 xprt_end_transmit(task);
1215 rpc_task_force_reencode(task);
1216 break;
1188 /* 1217 /*
1189 * Special cases: if we've been waiting on the 1218 * Special cases: if we've been waiting on the
1190 * socket's write_space() callback, or if the 1219 * socket's write_space() callback, or if the
@@ -1192,11 +1221,16 @@ call_transmit_status(struct rpc_task *task)
1192 * then hold onto the transport lock. 1221 * then hold onto the transport lock.
1193 */ 1222 */
1194 case -ECONNREFUSED: 1223 case -ECONNREFUSED:
1195 case -ECONNRESET:
1196 case -ENOTCONN:
1197 case -EHOSTDOWN: 1224 case -EHOSTDOWN:
1198 case -EHOSTUNREACH: 1225 case -EHOSTUNREACH:
1199 case -ENETUNREACH: 1226 case -ENETUNREACH:
1227 if (RPC_IS_SOFTCONN(task)) {
1228 xprt_end_transmit(task);
1229 rpc_exit(task, task->tk_status);
1230 break;
1231 }
1232 case -ECONNRESET:
1233 case -ENOTCONN:
1200 case -EPIPE: 1234 case -EPIPE:
1201 rpc_task_force_reencode(task); 1235 rpc_task_force_reencode(task);
1202 } 1236 }
@@ -1346,6 +1380,10 @@ call_timeout(struct rpc_task *task)
1346 dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid); 1380 dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid);
1347 task->tk_timeouts++; 1381 task->tk_timeouts++;
1348 1382
1383 if (RPC_IS_SOFTCONN(task)) {
1384 rpc_exit(task, -ETIMEDOUT);
1385 return;
1386 }
1349 if (RPC_IS_SOFT(task)) { 1387 if (RPC_IS_SOFT(task)) {
1350 if (clnt->cl_chatty) 1388 if (clnt->cl_chatty)
1351 printk(KERN_NOTICE "%s: server %s not responding, timed out\n", 1389 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
@@ -1675,14 +1713,14 @@ static struct rpc_procinfo rpcproc_null = {
1675 .p_decode = rpcproc_decode_null, 1713 .p_decode = rpcproc_decode_null,
1676}; 1714};
1677 1715
1678static int rpc_ping(struct rpc_clnt *clnt, int flags) 1716static int rpc_ping(struct rpc_clnt *clnt)
1679{ 1717{
1680 struct rpc_message msg = { 1718 struct rpc_message msg = {
1681 .rpc_proc = &rpcproc_null, 1719 .rpc_proc = &rpcproc_null,
1682 }; 1720 };
1683 int err; 1721 int err;
1684 msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0); 1722 msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
1685 err = rpc_call_sync(clnt, &msg, flags); 1723 err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN);
1686 put_rpccred(msg.rpc_cred); 1724 put_rpccred(msg.rpc_cred);
1687 return err; 1725 return err;
1688} 1726}
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 830faf4d9997..3e3772d8eb92 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -20,6 +20,7 @@
20#include <linux/in6.h> 20#include <linux/in6.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/mutex.h>
23#include <net/ipv6.h> 24#include <net/ipv6.h>
24 25
25#include <linux/sunrpc/clnt.h> 26#include <linux/sunrpc/clnt.h>
@@ -110,6 +111,9 @@ static void rpcb_getport_done(struct rpc_task *, void *);
110static void rpcb_map_release(void *data); 111static void rpcb_map_release(void *data);
111static struct rpc_program rpcb_program; 112static struct rpc_program rpcb_program;
112 113
114static struct rpc_clnt * rpcb_local_clnt;
115static struct rpc_clnt * rpcb_local_clnt4;
116
113struct rpcbind_args { 117struct rpcbind_args {
114 struct rpc_xprt * r_xprt; 118 struct rpc_xprt * r_xprt;
115 119
@@ -163,21 +167,60 @@ static const struct sockaddr_in rpcb_inaddr_loopback = {
163 .sin_port = htons(RPCBIND_PORT), 167 .sin_port = htons(RPCBIND_PORT),
164}; 168};
165 169
166static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr, 170static DEFINE_MUTEX(rpcb_create_local_mutex);
167 size_t addrlen, u32 version) 171
172/*
173 * Returns zero on success, otherwise a negative errno value
174 * is returned.
175 */
176static int rpcb_create_local(void)
168{ 177{
169 struct rpc_create_args args = { 178 struct rpc_create_args args = {
170 .protocol = XPRT_TRANSPORT_UDP, 179 .protocol = XPRT_TRANSPORT_TCP,
171 .address = addr, 180 .address = (struct sockaddr *)&rpcb_inaddr_loopback,
172 .addrsize = addrlen, 181 .addrsize = sizeof(rpcb_inaddr_loopback),
173 .servername = "localhost", 182 .servername = "localhost",
174 .program = &rpcb_program, 183 .program = &rpcb_program,
175 .version = version, 184 .version = RPCBVERS_2,
176 .authflavor = RPC_AUTH_UNIX, 185 .authflavor = RPC_AUTH_UNIX,
177 .flags = RPC_CLNT_CREATE_NOPING, 186 .flags = RPC_CLNT_CREATE_NOPING,
178 }; 187 };
188 struct rpc_clnt *clnt, *clnt4;
189 int result = 0;
190
191 if (rpcb_local_clnt)
192 return result;
193
194 mutex_lock(&rpcb_create_local_mutex);
195 if (rpcb_local_clnt)
196 goto out;
197
198 clnt = rpc_create(&args);
199 if (IS_ERR(clnt)) {
200 dprintk("RPC: failed to create local rpcbind "
201 "client (errno %ld).\n", PTR_ERR(clnt));
202 result = -PTR_ERR(clnt);
203 goto out;
204 }
179 205
180 return rpc_create(&args); 206 /*
207 * This results in an RPC ping. On systems running portmapper,
208 * the v4 ping will fail. Proceed anyway, but disallow rpcb
209 * v4 upcalls.
210 */
211 clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
212 if (IS_ERR(clnt4)) {
213 dprintk("RPC: failed to create local rpcbind v4 "
214 "cleint (errno %ld).\n", PTR_ERR(clnt4));
215 clnt4 = NULL;
216 }
217
218 rpcb_local_clnt = clnt;
219 rpcb_local_clnt4 = clnt4;
220
221out:
222 mutex_unlock(&rpcb_create_local_mutex);
223 return result;
181} 224}
182 225
183static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, 226static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
@@ -209,22 +252,13 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
209 return rpc_create(&args); 252 return rpc_create(&args);
210} 253}
211 254
212static int rpcb_register_call(const u32 version, struct rpc_message *msg) 255static int rpcb_register_call(struct rpc_clnt *clnt, struct rpc_message *msg)
213{ 256{
214 struct sockaddr *addr = (struct sockaddr *)&rpcb_inaddr_loopback;
215 size_t addrlen = sizeof(rpcb_inaddr_loopback);
216 struct rpc_clnt *rpcb_clnt;
217 int result, error = 0; 257 int result, error = 0;
218 258
219 msg->rpc_resp = &result; 259 msg->rpc_resp = &result;
220 260
221 rpcb_clnt = rpcb_create_local(addr, addrlen, version); 261 error = rpc_call_sync(clnt, msg, RPC_TASK_SOFTCONN);
222 if (!IS_ERR(rpcb_clnt)) {
223 error = rpc_call_sync(rpcb_clnt, msg, 0);
224 rpc_shutdown_client(rpcb_clnt);
225 } else
226 error = PTR_ERR(rpcb_clnt);
227
228 if (error < 0) { 262 if (error < 0) {
229 dprintk("RPC: failed to contact local rpcbind " 263 dprintk("RPC: failed to contact local rpcbind "
230 "server (errno %d).\n", -error); 264 "server (errno %d).\n", -error);
@@ -279,6 +313,11 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
279 struct rpc_message msg = { 313 struct rpc_message msg = {
280 .rpc_argp = &map, 314 .rpc_argp = &map,
281 }; 315 };
316 int error;
317
318 error = rpcb_create_local();
319 if (error)
320 return error;
282 321
283 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " 322 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
284 "rpcbind\n", (port ? "" : "un"), 323 "rpcbind\n", (port ? "" : "un"),
@@ -288,7 +327,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
288 if (port) 327 if (port)
289 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET]; 328 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
290 329
291 return rpcb_register_call(RPCBVERS_2, &msg); 330 return rpcb_register_call(rpcb_local_clnt, &msg);
292} 331}
293 332
294/* 333/*
@@ -313,7 +352,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
313 if (port) 352 if (port)
314 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 353 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
315 354
316 result = rpcb_register_call(RPCBVERS_4, msg); 355 result = rpcb_register_call(rpcb_local_clnt4, msg);
317 kfree(map->r_addr); 356 kfree(map->r_addr);
318 return result; 357 return result;
319} 358}
@@ -340,7 +379,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
340 if (port) 379 if (port)
341 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 380 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
342 381
343 result = rpcb_register_call(RPCBVERS_4, msg); 382 result = rpcb_register_call(rpcb_local_clnt4, msg);
344 kfree(map->r_addr); 383 kfree(map->r_addr);
345 return result; 384 return result;
346} 385}
@@ -356,7 +395,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
356 map->r_addr = ""; 395 map->r_addr = "";
357 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; 396 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
358 397
359 return rpcb_register_call(RPCBVERS_4, msg); 398 return rpcb_register_call(rpcb_local_clnt4, msg);
360} 399}
361 400
362/** 401/**
@@ -414,6 +453,13 @@ int rpcb_v4_register(const u32 program, const u32 version,
414 struct rpc_message msg = { 453 struct rpc_message msg = {
415 .rpc_argp = &map, 454 .rpc_argp = &map,
416 }; 455 };
456 int error;
457
458 error = rpcb_create_local();
459 if (error)
460 return error;
461 if (rpcb_local_clnt4 == NULL)
462 return -EPROTONOSUPPORT;
417 463
418 if (address == NULL) 464 if (address == NULL)
419 return rpcb_unregister_all_protofamilies(&msg); 465 return rpcb_unregister_all_protofamilies(&msg);
@@ -491,7 +537,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
491 .rpc_message = &msg, 537 .rpc_message = &msg,
492 .callback_ops = &rpcb_getport_ops, 538 .callback_ops = &rpcb_getport_ops,
493 .callback_data = map, 539 .callback_data = map,
494 .flags = RPC_TASK_ASYNC, 540 .flags = RPC_TASK_ASYNC | RPC_TASK_SOFTCONN,
495 }; 541 };
496 542
497 return rpc_run_task(&task_setup_data); 543 return rpc_run_task(&task_setup_data);
@@ -1027,3 +1073,15 @@ static struct rpc_program rpcb_program = {
1027 .version = rpcb_version, 1073 .version = rpcb_version,
1028 .stats = &rpcb_stats, 1074 .stats = &rpcb_stats,
1029}; 1075};
1076
1077/**
1078 * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
1079 *
1080 */
1081void cleanup_rpcb_clnt(void)
1082{
1083 if (rpcb_local_clnt4)
1084 rpc_shutdown_client(rpcb_local_clnt4);
1085 if (rpcb_local_clnt)
1086 rpc_shutdown_client(rpcb_local_clnt);
1087}
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index cef74ba0666c..aae6907fd546 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -210,6 +210,7 @@ void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qnam
210{ 210{
211 __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY); 211 __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY);
212} 212}
213EXPORT_SYMBOL_GPL(rpc_init_priority_wait_queue);
213 214
214void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) 215void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname)
215{ 216{
@@ -385,6 +386,20 @@ static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct r
385} 386}
386 387
387/* 388/*
389 * Tests whether rpc queue is empty
390 */
391int rpc_queue_empty(struct rpc_wait_queue *queue)
392{
393 int res;
394
395 spin_lock_bh(&queue->lock);
396 res = queue->qlen;
397 spin_unlock_bh(&queue->lock);
398 return (res == 0);
399}
400EXPORT_SYMBOL_GPL(rpc_queue_empty);
401
402/*
388 * Wake up a task on a specific queue 403 * Wake up a task on a specific queue
389 */ 404 */
390void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) 405void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task)
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 8cce92189019..f438347d817b 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -24,6 +24,8 @@
24 24
25extern struct cache_detail ip_map_cache, unix_gid_cache; 25extern struct cache_detail ip_map_cache, unix_gid_cache;
26 26
27extern void cleanup_rpcb_clnt(void);
28
27static int __init 29static int __init
28init_sunrpc(void) 30init_sunrpc(void)
29{ 31{
@@ -53,6 +55,7 @@ out:
53static void __exit 55static void __exit
54cleanup_sunrpc(void) 56cleanup_sunrpc(void)
55{ 57{
58 cleanup_rpcb_clnt();
56 rpcauth_remove_module(); 59 rpcauth_remove_module();
57 cleanup_socket_xprt(); 60 cleanup_socket_xprt();
58 svc_cleanup_xprt_sock(); 61 svc_cleanup_xprt_sock();
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 952f206ff307..538ca433a56c 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1103,8 +1103,9 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1103 procp->pc_release(rqstp, NULL, rqstp->rq_resp); 1103 procp->pc_release(rqstp, NULL, rqstp->rq_resp);
1104 goto dropit; 1104 goto dropit;
1105 } 1105 }
1106 if (*statp == rpc_success && (xdr = procp->pc_encode) 1106 if (*statp == rpc_success &&
1107 && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { 1107 (xdr = procp->pc_encode) &&
1108 !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) {
1108 dprintk("svc: failed to encode reply\n"); 1109 dprintk("svc: failed to encode reply\n");
1109 /* serv->sv_stats->rpcsystemerr++; */ 1110 /* serv->sv_stats->rpcsystemerr++; */
1110 *statp = rpc_system_err; 1111 *statp = rpc_system_err;
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 810ffe8a636b..7d1f9e928f69 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -127,8 +127,8 @@ static void svc_xprt_free(struct kref *kref)
127 struct svc_xprt *xprt = 127 struct svc_xprt *xprt =
128 container_of(kref, struct svc_xprt, xpt_ref); 128 container_of(kref, struct svc_xprt, xpt_ref);
129 struct module *owner = xprt->xpt_class->xcl_owner; 129 struct module *owner = xprt->xpt_class->xcl_owner;
130 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) 130 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) &&
131 && xprt->xpt_auth_cache != NULL) 131 xprt->xpt_auth_cache != NULL)
132 svcauth_unix_info_release(xprt->xpt_auth_cache); 132 svcauth_unix_info_release(xprt->xpt_auth_cache);
133 xprt->xpt_ops->xpo_free(xprt); 133 xprt->xpt_ops->xpo_free(xprt);
134 module_put(owner); 134 module_put(owner);
@@ -835,8 +835,8 @@ static void svc_age_temp_xprts(unsigned long closure)
835 * through, close it. */ 835 * through, close it. */
836 if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) 836 if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags))
837 continue; 837 continue;
838 if (atomic_read(&xprt->xpt_ref.refcount) > 1 838 if (atomic_read(&xprt->xpt_ref.refcount) > 1 ||
839 || test_bit(XPT_BUSY, &xprt->xpt_flags)) 839 test_bit(XPT_BUSY, &xprt->xpt_flags))
840 continue; 840 continue;
841 svc_xprt_get(xprt); 841 svc_xprt_get(xprt);
842 list_move(le, &to_be_aged); 842 list_move(le, &to_be_aged);
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index e64109b02aee..4e9393c24687 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -46,8 +46,8 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
46 dprintk("svc: svc_authenticate (%d)\n", flavor); 46 dprintk("svc: svc_authenticate (%d)\n", flavor);
47 47
48 spin_lock(&authtab_lock); 48 spin_lock(&authtab_lock);
49 if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) 49 if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) ||
50 || !try_module_get(aops->owner)) { 50 !try_module_get(aops->owner)) {
51 spin_unlock(&authtab_lock); 51 spin_unlock(&authtab_lock);
52 *authp = rpc_autherr_badcred; 52 *authp = rpc_autherr_badcred;
53 return SVC_DENIED; 53 return SVC_DENIED;
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 97cc3de7432e..d8c041114497 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -125,8 +125,8 @@ static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
125{ 125{
126 struct ip_map *orig = container_of(corig, struct ip_map, h); 126 struct ip_map *orig = container_of(corig, struct ip_map, h);
127 struct ip_map *new = container_of(cnew, struct ip_map, h); 127 struct ip_map *new = container_of(cnew, struct ip_map, h);
128 return strcmp(orig->m_class, new->m_class) == 0 128 return strcmp(orig->m_class, new->m_class) == 0 &&
129 && ipv6_addr_equal(&orig->m_addr, &new->m_addr); 129 ipv6_addr_equal(&orig->m_addr, &new->m_addr);
130} 130}
131static void ip_map_init(struct cache_head *cnew, struct cache_head *citem) 131static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
132{ 132{
@@ -690,8 +690,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
690 case AF_INET: 690 case AF_INET:
691 sin = svc_addr_in(rqstp); 691 sin = svc_addr_in(rqstp);
692 sin6 = &sin6_storage; 692 sin6 = &sin6_storage;
693 ipv6_addr_set(&sin6->sin6_addr, 0, 0, 693 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr);
694 htonl(0x0000FFFF), sin->sin_addr.s_addr);
695 break; 694 break;
696 case AF_INET6: 695 case AF_INET6:
697 sin6 = svc_addr_in6(rqstp); 696 sin6 = svc_addr_in6(rqstp);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 1c246a4f491e..870929e08e5d 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -272,14 +272,14 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
272 case PF_INET: 272 case PF_INET:
273 len = snprintf(buf, remaining, "ipv4 %s %pI4 %d\n", 273 len = snprintf(buf, remaining, "ipv4 %s %pI4 %d\n",
274 proto_name, 274 proto_name,
275 &inet_sk(sk)->rcv_saddr, 275 &inet_sk(sk)->inet_rcv_saddr,
276 inet_sk(sk)->num); 276 inet_sk(sk)->inet_num);
277 break; 277 break;
278 case PF_INET6: 278 case PF_INET6:
279 len = snprintf(buf, remaining, "ipv6 %s %pI6 %d\n", 279 len = snprintf(buf, remaining, "ipv6 %s %pI6 %d\n",
280 proto_name, 280 proto_name,
281 &inet6_sk(sk)->rcv_saddr, 281 &inet6_sk(sk)->rcv_saddr,
282 inet_sk(sk)->num); 282 inet_sk(sk)->inet_num);
283 break; 283 break;
284 default: 284 default:
285 len = snprintf(buf, remaining, "*unknown-%d*\n", 285 len = snprintf(buf, remaining, "*unknown-%d*\n",
@@ -1311,7 +1311,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1311 /* Register socket with portmapper */ 1311 /* Register socket with portmapper */
1312 if (*errp >= 0 && pmap_register) 1312 if (*errp >= 0 && pmap_register)
1313 *errp = svc_register(serv, inet->sk_family, inet->sk_protocol, 1313 *errp = svc_register(serv, inet->sk_family, inet->sk_protocol,
1314 ntohs(inet_sk(inet)->sport)); 1314 ntohs(inet_sk(inet)->inet_sport));
1315 1315
1316 if (*errp < 0) { 1316 if (*errp < 0) {
1317 kfree(svsk); 1317 kfree(svsk);
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 42f9748ae093..e65dcc613339 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -139,46 +139,45 @@ static ctl_table debug_table[] = {
139 .data = &rpc_debug, 139 .data = &rpc_debug,
140 .maxlen = sizeof(int), 140 .maxlen = sizeof(int),
141 .mode = 0644, 141 .mode = 0644,
142 .proc_handler = &proc_dodebug 142 .proc_handler = proc_dodebug
143 }, 143 },
144 { 144 {
145 .procname = "nfs_debug", 145 .procname = "nfs_debug",
146 .data = &nfs_debug, 146 .data = &nfs_debug,
147 .maxlen = sizeof(int), 147 .maxlen = sizeof(int),
148 .mode = 0644, 148 .mode = 0644,
149 .proc_handler = &proc_dodebug 149 .proc_handler = proc_dodebug
150 }, 150 },
151 { 151 {
152 .procname = "nfsd_debug", 152 .procname = "nfsd_debug",
153 .data = &nfsd_debug, 153 .data = &nfsd_debug,
154 .maxlen = sizeof(int), 154 .maxlen = sizeof(int),
155 .mode = 0644, 155 .mode = 0644,
156 .proc_handler = &proc_dodebug 156 .proc_handler = proc_dodebug
157 }, 157 },
158 { 158 {
159 .procname = "nlm_debug", 159 .procname = "nlm_debug",
160 .data = &nlm_debug, 160 .data = &nlm_debug,
161 .maxlen = sizeof(int), 161 .maxlen = sizeof(int),
162 .mode = 0644, 162 .mode = 0644,
163 .proc_handler = &proc_dodebug 163 .proc_handler = proc_dodebug
164 }, 164 },
165 { 165 {
166 .procname = "transports", 166 .procname = "transports",
167 .maxlen = 256, 167 .maxlen = 256,
168 .mode = 0444, 168 .mode = 0444,
169 .proc_handler = &proc_do_xprt, 169 .proc_handler = proc_do_xprt,
170 }, 170 },
171 { .ctl_name = 0 } 171 { }
172}; 172};
173 173
174static ctl_table sunrpc_table[] = { 174static ctl_table sunrpc_table[] = {
175 { 175 {
176 .ctl_name = CTL_SUNRPC,
177 .procname = "sunrpc", 176 .procname = "sunrpc",
178 .mode = 0555, 177 .mode = 0555,
179 .child = debug_table 178 .child = debug_table
180 }, 179 },
181 { .ctl_name = 0 } 180 { }
182}; 181};
183 182
184#endif 183#endif
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index fd46d42afa89..469de292c23c 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -700,6 +700,10 @@ void xprt_connect(struct rpc_task *task)
700 } 700 }
701 if (!xprt_lock_write(xprt, task)) 701 if (!xprt_lock_write(xprt, task))
702 return; 702 return;
703
704 if (test_and_clear_bit(XPRT_CLOSE_WAIT, &xprt->state))
705 xprt->ops->close(xprt);
706
703 if (xprt_connected(xprt)) 707 if (xprt_connected(xprt))
704 xprt_release_write(xprt, task); 708 xprt_release_write(xprt, task);
705 else { 709 else {
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
index 35fb68b9c8ec..5b8a8ff93a25 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -120,8 +120,7 @@ static ctl_table svcrdma_parm_table[] = {
120 .data = &svcrdma_max_requests, 120 .data = &svcrdma_max_requests,
121 .maxlen = sizeof(unsigned int), 121 .maxlen = sizeof(unsigned int),
122 .mode = 0644, 122 .mode = 0644,
123 .proc_handler = &proc_dointvec_minmax, 123 .proc_handler = proc_dointvec_minmax,
124 .strategy = &sysctl_intvec,
125 .extra1 = &min_max_requests, 124 .extra1 = &min_max_requests,
126 .extra2 = &max_max_requests 125 .extra2 = &max_max_requests
127 }, 126 },
@@ -130,8 +129,7 @@ static ctl_table svcrdma_parm_table[] = {
130 .data = &svcrdma_max_req_size, 129 .data = &svcrdma_max_req_size,
131 .maxlen = sizeof(unsigned int), 130 .maxlen = sizeof(unsigned int),
132 .mode = 0644, 131 .mode = 0644,
133 .proc_handler = &proc_dointvec_minmax, 132 .proc_handler = proc_dointvec_minmax,
134 .strategy = &sysctl_intvec,
135 .extra1 = &min_max_inline, 133 .extra1 = &min_max_inline,
136 .extra2 = &max_max_inline 134 .extra2 = &max_max_inline
137 }, 135 },
@@ -140,8 +138,7 @@ static ctl_table svcrdma_parm_table[] = {
140 .data = &svcrdma_ord, 138 .data = &svcrdma_ord,
141 .maxlen = sizeof(unsigned int), 139 .maxlen = sizeof(unsigned int),
142 .mode = 0644, 140 .mode = 0644,
143 .proc_handler = &proc_dointvec_minmax, 141 .proc_handler = proc_dointvec_minmax,
144 .strategy = &sysctl_intvec,
145 .extra1 = &min_ord, 142 .extra1 = &min_ord,
146 .extra2 = &max_ord, 143 .extra2 = &max_ord,
147 }, 144 },
@@ -151,67 +148,65 @@ static ctl_table svcrdma_parm_table[] = {
151 .data = &rdma_stat_read, 148 .data = &rdma_stat_read,
152 .maxlen = sizeof(atomic_t), 149 .maxlen = sizeof(atomic_t),
153 .mode = 0644, 150 .mode = 0644,
154 .proc_handler = &read_reset_stat, 151 .proc_handler = read_reset_stat,
155 }, 152 },
156 { 153 {
157 .procname = "rdma_stat_recv", 154 .procname = "rdma_stat_recv",
158 .data = &rdma_stat_recv, 155 .data = &rdma_stat_recv,
159 .maxlen = sizeof(atomic_t), 156 .maxlen = sizeof(atomic_t),
160 .mode = 0644, 157 .mode = 0644,
161 .proc_handler = &read_reset_stat, 158 .proc_handler = read_reset_stat,
162 }, 159 },
163 { 160 {
164 .procname = "rdma_stat_write", 161 .procname = "rdma_stat_write",
165 .data = &rdma_stat_write, 162 .data = &rdma_stat_write,
166 .maxlen = sizeof(atomic_t), 163 .maxlen = sizeof(atomic_t),
167 .mode = 0644, 164 .mode = 0644,
168 .proc_handler = &read_reset_stat, 165 .proc_handler = read_reset_stat,
169 }, 166 },
170 { 167 {
171 .procname = "rdma_stat_sq_starve", 168 .procname = "rdma_stat_sq_starve",
172 .data = &rdma_stat_sq_starve, 169 .data = &rdma_stat_sq_starve,
173 .maxlen = sizeof(atomic_t), 170 .maxlen = sizeof(atomic_t),
174 .mode = 0644, 171 .mode = 0644,
175 .proc_handler = &read_reset_stat, 172 .proc_handler = read_reset_stat,
176 }, 173 },
177 { 174 {
178 .procname = "rdma_stat_rq_starve", 175 .procname = "rdma_stat_rq_starve",
179 .data = &rdma_stat_rq_starve, 176 .data = &rdma_stat_rq_starve,
180 .maxlen = sizeof(atomic_t), 177 .maxlen = sizeof(atomic_t),
181 .mode = 0644, 178 .mode = 0644,
182 .proc_handler = &read_reset_stat, 179 .proc_handler = read_reset_stat,
183 }, 180 },
184 { 181 {
185 .procname = "rdma_stat_rq_poll", 182 .procname = "rdma_stat_rq_poll",
186 .data = &rdma_stat_rq_poll, 183 .data = &rdma_stat_rq_poll,
187 .maxlen = sizeof(atomic_t), 184 .maxlen = sizeof(atomic_t),
188 .mode = 0644, 185 .mode = 0644,
189 .proc_handler = &read_reset_stat, 186 .proc_handler = read_reset_stat,
190 }, 187 },
191 { 188 {
192 .procname = "rdma_stat_rq_prod", 189 .procname = "rdma_stat_rq_prod",
193 .data = &rdma_stat_rq_prod, 190 .data = &rdma_stat_rq_prod,
194 .maxlen = sizeof(atomic_t), 191 .maxlen = sizeof(atomic_t),
195 .mode = 0644, 192 .mode = 0644,
196 .proc_handler = &read_reset_stat, 193 .proc_handler = read_reset_stat,
197 }, 194 },
198 { 195 {
199 .procname = "rdma_stat_sq_poll", 196 .procname = "rdma_stat_sq_poll",
200 .data = &rdma_stat_sq_poll, 197 .data = &rdma_stat_sq_poll,
201 .maxlen = sizeof(atomic_t), 198 .maxlen = sizeof(atomic_t),
202 .mode = 0644, 199 .mode = 0644,
203 .proc_handler = &read_reset_stat, 200 .proc_handler = read_reset_stat,
204 }, 201 },
205 { 202 {
206 .procname = "rdma_stat_sq_prod", 203 .procname = "rdma_stat_sq_prod",
207 .data = &rdma_stat_sq_prod, 204 .data = &rdma_stat_sq_prod,
208 .maxlen = sizeof(atomic_t), 205 .maxlen = sizeof(atomic_t),
209 .mode = 0644, 206 .mode = 0644,
210 .proc_handler = &read_reset_stat, 207 .proc_handler = read_reset_stat,
211 },
212 {
213 .ctl_name = 0,
214 }, 208 },
209 { },
215}; 210};
216 211
217static ctl_table svcrdma_table[] = { 212static ctl_table svcrdma_table[] = {
@@ -220,21 +215,16 @@ static ctl_table svcrdma_table[] = {
220 .mode = 0555, 215 .mode = 0555,
221 .child = svcrdma_parm_table 216 .child = svcrdma_parm_table
222 }, 217 },
223 { 218 { },
224 .ctl_name = 0,
225 },
226}; 219};
227 220
228static ctl_table svcrdma_root_table[] = { 221static ctl_table svcrdma_root_table[] = {
229 { 222 {
230 .ctl_name = CTL_SUNRPC,
231 .procname = "sunrpc", 223 .procname = "sunrpc",
232 .mode = 0555, 224 .mode = 0555,
233 .child = svcrdma_table 225 .child = svcrdma_table
234 }, 226 },
235 { 227 { },
236 .ctl_name = 0,
237 },
238}; 228};
239 229
240void svc_rdma_cleanup(void) 230void svc_rdma_cleanup(void)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 9e884383134f..f92e37eb413c 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -337,10 +337,9 @@ static int rdma_set_ctxt_sge(struct svcxprt_rdma *xprt,
337 337
338static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) 338static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count)
339{ 339{
340 if ((RDMA_TRANSPORT_IWARP == 340 if ((rdma_node_get_transport(xprt->sc_cm_id->device->node_type) ==
341 rdma_node_get_transport(xprt->sc_cm_id-> 341 RDMA_TRANSPORT_IWARP) &&
342 device->node_type)) 342 sge_count > 1)
343 && sge_count > 1)
344 return 1; 343 return 1;
345 else 344 else
346 return min_t(int, sge_count, xprt->sc_max_sge); 345 return min_t(int, sge_count, xprt->sc_max_sge);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index f11be72a1a80..b15e1ebb2bfa 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -54,7 +54,7 @@
54 * Assumptions: 54 * Assumptions:
55 * - head[0] is physically contiguous. 55 * - head[0] is physically contiguous.
56 * - tail[0] is physically contiguous. 56 * - tail[0] is physically contiguous.
57 * - pages[] is not physically or virtually contigous and consists of 57 * - pages[] is not physically or virtually contiguous and consists of
58 * PAGE_SIZE elements. 58 * PAGE_SIZE elements.
59 * 59 *
60 * Output: 60 * Output:
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 9a63f669ece4..7018eef1dcdd 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -86,79 +86,63 @@ static struct ctl_table_header *sunrpc_table_header;
86 86
87static ctl_table xr_tunables_table[] = { 87static ctl_table xr_tunables_table[] = {
88 { 88 {
89 .ctl_name = CTL_UNNUMBERED,
90 .procname = "rdma_slot_table_entries", 89 .procname = "rdma_slot_table_entries",
91 .data = &xprt_rdma_slot_table_entries, 90 .data = &xprt_rdma_slot_table_entries,
92 .maxlen = sizeof(unsigned int), 91 .maxlen = sizeof(unsigned int),
93 .mode = 0644, 92 .mode = 0644,
94 .proc_handler = &proc_dointvec_minmax, 93 .proc_handler = proc_dointvec_minmax,
95 .strategy = &sysctl_intvec,
96 .extra1 = &min_slot_table_size, 94 .extra1 = &min_slot_table_size,
97 .extra2 = &max_slot_table_size 95 .extra2 = &max_slot_table_size
98 }, 96 },
99 { 97 {
100 .ctl_name = CTL_UNNUMBERED,
101 .procname = "rdma_max_inline_read", 98 .procname = "rdma_max_inline_read",
102 .data = &xprt_rdma_max_inline_read, 99 .data = &xprt_rdma_max_inline_read,
103 .maxlen = sizeof(unsigned int), 100 .maxlen = sizeof(unsigned int),
104 .mode = 0644, 101 .mode = 0644,
105 .proc_handler = &proc_dointvec, 102 .proc_handler = proc_dointvec,
106 .strategy = &sysctl_intvec,
107 }, 103 },
108 { 104 {
109 .ctl_name = CTL_UNNUMBERED,
110 .procname = "rdma_max_inline_write", 105 .procname = "rdma_max_inline_write",
111 .data = &xprt_rdma_max_inline_write, 106 .data = &xprt_rdma_max_inline_write,
112 .maxlen = sizeof(unsigned int), 107 .maxlen = sizeof(unsigned int),
113 .mode = 0644, 108 .mode = 0644,
114 .proc_handler = &proc_dointvec, 109 .proc_handler = proc_dointvec,
115 .strategy = &sysctl_intvec,
116 }, 110 },
117 { 111 {
118 .ctl_name = CTL_UNNUMBERED,
119 .procname = "rdma_inline_write_padding", 112 .procname = "rdma_inline_write_padding",
120 .data = &xprt_rdma_inline_write_padding, 113 .data = &xprt_rdma_inline_write_padding,
121 .maxlen = sizeof(unsigned int), 114 .maxlen = sizeof(unsigned int),
122 .mode = 0644, 115 .mode = 0644,
123 .proc_handler = &proc_dointvec_minmax, 116 .proc_handler = proc_dointvec_minmax,
124 .strategy = &sysctl_intvec,
125 .extra1 = &zero, 117 .extra1 = &zero,
126 .extra2 = &max_padding, 118 .extra2 = &max_padding,
127 }, 119 },
128 { 120 {
129 .ctl_name = CTL_UNNUMBERED,
130 .procname = "rdma_memreg_strategy", 121 .procname = "rdma_memreg_strategy",
131 .data = &xprt_rdma_memreg_strategy, 122 .data = &xprt_rdma_memreg_strategy,
132 .maxlen = sizeof(unsigned int), 123 .maxlen = sizeof(unsigned int),
133 .mode = 0644, 124 .mode = 0644,
134 .proc_handler = &proc_dointvec_minmax, 125 .proc_handler = proc_dointvec_minmax,
135 .strategy = &sysctl_intvec,
136 .extra1 = &min_memreg, 126 .extra1 = &min_memreg,
137 .extra2 = &max_memreg, 127 .extra2 = &max_memreg,
138 }, 128 },
139 { 129 {
140 .ctl_name = CTL_UNNUMBERED,
141 .procname = "rdma_pad_optimize", 130 .procname = "rdma_pad_optimize",
142 .data = &xprt_rdma_pad_optimize, 131 .data = &xprt_rdma_pad_optimize,
143 .maxlen = sizeof(unsigned int), 132 .maxlen = sizeof(unsigned int),
144 .mode = 0644, 133 .mode = 0644,
145 .proc_handler = &proc_dointvec, 134 .proc_handler = proc_dointvec,
146 },
147 {
148 .ctl_name = 0,
149 }, 135 },
136 { },
150}; 137};
151 138
152static ctl_table sunrpc_table[] = { 139static ctl_table sunrpc_table[] = {
153 { 140 {
154 .ctl_name = CTL_SUNRPC,
155 .procname = "sunrpc", 141 .procname = "sunrpc",
156 .mode = 0555, 142 .mode = 0555,
157 .child = xr_tunables_table 143 .child = xr_tunables_table
158 }, 144 },
159 { 145 { },
160 .ctl_name = 0,
161 },
162}; 146};
163 147
164#endif 148#endif
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 465aafc2007f..2209aa87d899 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -878,8 +878,8 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
878 * others indicate a transport condition which has already 878 * others indicate a transport condition which has already
879 * undergone a best-effort. 879 * undergone a best-effort.
880 */ 880 */
881 if (ep->rep_connected == -ECONNREFUSED 881 if (ep->rep_connected == -ECONNREFUSED &&
882 && ++retry_count <= RDMA_CONNECT_RETRY_MAX) { 882 ++retry_count <= RDMA_CONNECT_RETRY_MAX) {
883 dprintk("RPC: %s: non-peer_reject, retry\n", __func__); 883 dprintk("RPC: %s: non-peer_reject, retry\n", __func__);
884 goto retry; 884 goto retry;
885 } 885 }
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 37c5475ba258..3d739e5d15d8 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -81,46 +81,38 @@ static struct ctl_table_header *sunrpc_table_header;
81 */ 81 */
82static ctl_table xs_tunables_table[] = { 82static ctl_table xs_tunables_table[] = {
83 { 83 {
84 .ctl_name = CTL_SLOTTABLE_UDP,
85 .procname = "udp_slot_table_entries", 84 .procname = "udp_slot_table_entries",
86 .data = &xprt_udp_slot_table_entries, 85 .data = &xprt_udp_slot_table_entries,
87 .maxlen = sizeof(unsigned int), 86 .maxlen = sizeof(unsigned int),
88 .mode = 0644, 87 .mode = 0644,
89 .proc_handler = &proc_dointvec_minmax, 88 .proc_handler = proc_dointvec_minmax,
90 .strategy = &sysctl_intvec,
91 .extra1 = &min_slot_table_size, 89 .extra1 = &min_slot_table_size,
92 .extra2 = &max_slot_table_size 90 .extra2 = &max_slot_table_size
93 }, 91 },
94 { 92 {
95 .ctl_name = CTL_SLOTTABLE_TCP,
96 .procname = "tcp_slot_table_entries", 93 .procname = "tcp_slot_table_entries",
97 .data = &xprt_tcp_slot_table_entries, 94 .data = &xprt_tcp_slot_table_entries,
98 .maxlen = sizeof(unsigned int), 95 .maxlen = sizeof(unsigned int),
99 .mode = 0644, 96 .mode = 0644,
100 .proc_handler = &proc_dointvec_minmax, 97 .proc_handler = proc_dointvec_minmax,
101 .strategy = &sysctl_intvec,
102 .extra1 = &min_slot_table_size, 98 .extra1 = &min_slot_table_size,
103 .extra2 = &max_slot_table_size 99 .extra2 = &max_slot_table_size
104 }, 100 },
105 { 101 {
106 .ctl_name = CTL_MIN_RESVPORT,
107 .procname = "min_resvport", 102 .procname = "min_resvport",
108 .data = &xprt_min_resvport, 103 .data = &xprt_min_resvport,
109 .maxlen = sizeof(unsigned int), 104 .maxlen = sizeof(unsigned int),
110 .mode = 0644, 105 .mode = 0644,
111 .proc_handler = &proc_dointvec_minmax, 106 .proc_handler = proc_dointvec_minmax,
112 .strategy = &sysctl_intvec,
113 .extra1 = &xprt_min_resvport_limit, 107 .extra1 = &xprt_min_resvport_limit,
114 .extra2 = &xprt_max_resvport_limit 108 .extra2 = &xprt_max_resvport_limit
115 }, 109 },
116 { 110 {
117 .ctl_name = CTL_MAX_RESVPORT,
118 .procname = "max_resvport", 111 .procname = "max_resvport",
119 .data = &xprt_max_resvport, 112 .data = &xprt_max_resvport,
120 .maxlen = sizeof(unsigned int), 113 .maxlen = sizeof(unsigned int),
121 .mode = 0644, 114 .mode = 0644,
122 .proc_handler = &proc_dointvec_minmax, 115 .proc_handler = proc_dointvec_minmax,
123 .strategy = &sysctl_intvec,
124 .extra1 = &xprt_min_resvport_limit, 116 .extra1 = &xprt_min_resvport_limit,
125 .extra2 = &xprt_max_resvport_limit 117 .extra2 = &xprt_max_resvport_limit
126 }, 118 },
@@ -129,24 +121,18 @@ static ctl_table xs_tunables_table[] = {
129 .data = &xs_tcp_fin_timeout, 121 .data = &xs_tcp_fin_timeout,
130 .maxlen = sizeof(xs_tcp_fin_timeout), 122 .maxlen = sizeof(xs_tcp_fin_timeout),
131 .mode = 0644, 123 .mode = 0644,
132 .proc_handler = &proc_dointvec_jiffies, 124 .proc_handler = proc_dointvec_jiffies,
133 .strategy = sysctl_jiffies
134 },
135 {
136 .ctl_name = 0,
137 }, 125 },
126 { },
138}; 127};
139 128
140static ctl_table sunrpc_table[] = { 129static ctl_table sunrpc_table[] = {
141 { 130 {
142 .ctl_name = CTL_SUNRPC,
143 .procname = "sunrpc", 131 .procname = "sunrpc",
144 .mode = 0555, 132 .mode = 0555,
145 .child = xs_tunables_table 133 .child = xs_tunables_table
146 }, 134 },
147 { 135 { },
148 .ctl_name = 0,
149 },
150}; 136};
151 137
152#endif 138#endif
@@ -2033,7 +2019,7 @@ static void xs_connect(struct rpc_task *task)
2033 if (xprt_test_and_set_connecting(xprt)) 2019 if (xprt_test_and_set_connecting(xprt))
2034 return; 2020 return;
2035 2021
2036 if (transport->sock != NULL) { 2022 if (transport->sock != NULL && !RPC_IS_SOFTCONN(task)) {
2037 dprintk("RPC: xs_connect delayed xprt %p for %lu " 2023 dprintk("RPC: xs_connect delayed xprt %p for %lu "
2038 "seconds\n", 2024 "seconds\n",
2039 xprt, xprt->reestablish_timeout / HZ); 2025 xprt, xprt->reestablish_timeout / HZ);