aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-02 19:21:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-02 19:21:50 -0500
commite45428a436765fcd154d461a2739b5640916dc00 (patch)
tree6f9e52b8e02471353bbe5247b37ba2991dfdca3b /net
parent85f78456f286da46fb054c7d45e4193cb757ac83 (diff)
parent0ad30ff67bd3e82da8c1dc4d74b88aca846dbbd9 (diff)
Merge tag 'nfsd-4.21' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "Thanks to Vasily Averin for fixing a use-after-free in the containerized NFSv4.2 client, and cleaning up some convoluted backchannel server code in the process. Otherwise, miscellaneous smaller bugfixes and cleanup" * tag 'nfsd-4.21' of git://linux-nfs.org/~bfields/linux: (25 commits) nfs: fixed broken compilation in nfs_callback_up_net() nfs: minor typo in nfs4_callback_up_net() sunrpc: fix debug message in svc_create_xprt() sunrpc: make visible processing error in bc_svc_process() sunrpc: remove unused xpo_prep_reply_hdr callback sunrpc: remove svc_rdma_bc_class sunrpc: remove svc_tcp_bc_class sunrpc: remove unused bc_up operation from rpc_xprt_ops sunrpc: replace svc_serv->sv_bc_xprt by boolean flag sunrpc: use-after-free in svc_process_common() sunrpc: use SVC_NET() in svcauth_gss_* functions nfsd: drop useless LIST_HEAD lockd: Show pid of lockd for remote locks NFSD remove OP_CACHEME from 4.2 op_flags nfsd: Return EPERM, not EACCES, in some SETATTR cases sunrpc: fix cache_head leak due to queued request nfsd: clean up indentation, increase indentation in switch statement svcrdma: Optimize the logic that selects the R_key to invalidate nfsd: fix a warning in __cld_pipe_upcall() nfsd4: fix crash on writing v4_end_grace before nfsd startup ...
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c8
-rw-r--r--net/sunrpc/cache.c10
-rw-r--r--net/sunrpc/svc.c24
-rw-r--r--net/sunrpc/svc_xprt.c9
-rw-r--r--net/sunrpc/svcsock.c120
-rw-r--r--net/sunrpc/xprtrdma/backchannel.c20
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma.c6
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c63
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c57
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c59
-rw-r--r--net/sunrpc/xprtrdma/transport.c1
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h1
-rw-r--r--net/sunrpc/xprtsock.c12
13 files changed, 112 insertions, 278 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 1ece4bc3eb8d..152790ed309c 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1142,7 +1142,7 @@ static int svcauth_gss_legacy_init(struct svc_rqst *rqstp,
1142 struct kvec *resv = &rqstp->rq_res.head[0]; 1142 struct kvec *resv = &rqstp->rq_res.head[0];
1143 struct rsi *rsip, rsikey; 1143 struct rsi *rsip, rsikey;
1144 int ret; 1144 int ret;
1145 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); 1145 struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
1146 1146
1147 memset(&rsikey, 0, sizeof(rsikey)); 1147 memset(&rsikey, 0, sizeof(rsikey));
1148 ret = gss_read_verf(gc, argv, authp, 1148 ret = gss_read_verf(gc, argv, authp,
@@ -1253,7 +1253,7 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp,
1253 uint64_t handle; 1253 uint64_t handle;
1254 int status; 1254 int status;
1255 int ret; 1255 int ret;
1256 struct net *net = rqstp->rq_xprt->xpt_net; 1256 struct net *net = SVC_NET(rqstp);
1257 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1257 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1258 1258
1259 memset(&ud, 0, sizeof(ud)); 1259 memset(&ud, 0, sizeof(ud));
@@ -1444,7 +1444,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1444 __be32 *rpcstart; 1444 __be32 *rpcstart;
1445 __be32 *reject_stat = resv->iov_base + resv->iov_len; 1445 __be32 *reject_stat = resv->iov_base + resv->iov_len;
1446 int ret; 1446 int ret;
1447 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); 1447 struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
1448 1448
1449 dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", 1449 dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n",
1450 argv->iov_len); 1450 argv->iov_len);
@@ -1734,7 +1734,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
1734 struct rpc_gss_wire_cred *gc = &gsd->clcred; 1734 struct rpc_gss_wire_cred *gc = &gsd->clcred;
1735 struct xdr_buf *resbuf = &rqstp->rq_res; 1735 struct xdr_buf *resbuf = &rqstp->rq_res;
1736 int stat = -EINVAL; 1736 int stat = -EINVAL;
1737 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); 1737 struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
1738 1738
1739 if (gc->gc_proc != RPC_GSS_PROC_DATA) 1739 if (gc->gc_proc != RPC_GSS_PROC_DATA)
1740 goto out; 1740 goto out;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index f96345b1180e..12bb23b8e0c5 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -54,6 +54,11 @@ static void cache_init(struct cache_head *h, struct cache_detail *detail)
54 h->last_refresh = now; 54 h->last_refresh = now;
55} 55}
56 56
57static void cache_fresh_locked(struct cache_head *head, time_t expiry,
58 struct cache_detail *detail);
59static void cache_fresh_unlocked(struct cache_head *head,
60 struct cache_detail *detail);
61
57static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail, 62static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail,
58 struct cache_head *key, 63 struct cache_head *key,
59 int hash) 64 int hash)
@@ -100,6 +105,7 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
100 if (cache_is_expired(detail, tmp)) { 105 if (cache_is_expired(detail, tmp)) {
101 hlist_del_init_rcu(&tmp->cache_list); 106 hlist_del_init_rcu(&tmp->cache_list);
102 detail->entries --; 107 detail->entries --;
108 cache_fresh_locked(tmp, 0, detail);
103 freeme = tmp; 109 freeme = tmp;
104 break; 110 break;
105 } 111 }
@@ -115,8 +121,10 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
115 cache_get(new); 121 cache_get(new);
116 spin_unlock(&detail->hash_lock); 122 spin_unlock(&detail->hash_lock);
117 123
118 if (freeme) 124 if (freeme) {
125 cache_fresh_unlocked(freeme, detail);
119 cache_put(freeme, detail); 126 cache_put(freeme, detail);
127 }
120 return new; 128 return new;
121} 129}
122 130
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index d13e05f1a990..e87ddb9f7feb 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1145,6 +1145,17 @@ static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ..
1145#endif 1145#endif
1146 1146
1147/* 1147/*
1148 * Setup response header for TCP, it has a 4B record length field.
1149 */
1150static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
1151{
1152 struct kvec *resv = &rqstp->rq_res.head[0];
1153
1154 /* tcp needs a space for the record length... */
1155 svc_putnl(resv, 0);
1156}
1157
1158/*
1148 * Common routine for processing the RPC request. 1159 * Common routine for processing the RPC request.
1149 */ 1160 */
1150static int 1161static int
@@ -1172,7 +1183,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1172 clear_bit(RQ_DROPME, &rqstp->rq_flags); 1183 clear_bit(RQ_DROPME, &rqstp->rq_flags);
1173 1184
1174 /* Setup reply header */ 1185 /* Setup reply header */
1175 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); 1186 if (rqstp->rq_prot == IPPROTO_TCP)
1187 svc_tcp_prep_reply_hdr(rqstp);
1176 1188
1177 svc_putu32(resv, rqstp->rq_xid); 1189 svc_putu32(resv, rqstp->rq_xid);
1178 1190
@@ -1244,7 +1256,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1244 * for lower versions. RPC_PROG_MISMATCH seems to be the closest 1256 * for lower versions. RPC_PROG_MISMATCH seems to be the closest
1245 * fit. 1257 * fit.
1246 */ 1258 */
1247 if (versp->vs_need_cong_ctrl && 1259 if (versp->vs_need_cong_ctrl && rqstp->rq_xprt &&
1248 !test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags)) 1260 !test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags))
1249 goto err_bad_vers; 1261 goto err_bad_vers;
1250 1262
@@ -1336,7 +1348,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
1336 return 0; 1348 return 0;
1337 1349
1338 close: 1350 close:
1339 if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) 1351 if (rqstp->rq_xprt && test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
1340 svc_close_xprt(rqstp->rq_xprt); 1352 svc_close_xprt(rqstp->rq_xprt);
1341 dprintk("svc: svc_process close\n"); 1353 dprintk("svc: svc_process close\n");
1342 return 0; 1354 return 0;
@@ -1459,10 +1471,10 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
1459 dprintk("svc: %s(%p)\n", __func__, req); 1471 dprintk("svc: %s(%p)\n", __func__, req);
1460 1472
1461 /* Build the svc_rqst used by the common processing routine */ 1473 /* Build the svc_rqst used by the common processing routine */
1462 rqstp->rq_xprt = serv->sv_bc_xprt;
1463 rqstp->rq_xid = req->rq_xid; 1474 rqstp->rq_xid = req->rq_xid;
1464 rqstp->rq_prot = req->rq_xprt->prot; 1475 rqstp->rq_prot = req->rq_xprt->prot;
1465 rqstp->rq_server = serv; 1476 rqstp->rq_server = serv;
1477 rqstp->rq_bc_net = req->rq_xprt->xprt_net;
1466 1478
1467 rqstp->rq_addrlen = sizeof(req->rq_xprt->addr); 1479 rqstp->rq_addrlen = sizeof(req->rq_xprt->addr);
1468 memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen); 1480 memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
@@ -1499,9 +1511,9 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
1499 if (!proc_error) { 1511 if (!proc_error) {
1500 /* Processing error: drop the request */ 1512 /* Processing error: drop the request */
1501 xprt_free_bc_request(req); 1513 xprt_free_bc_request(req);
1502 return 0; 1514 error = -EINVAL;
1515 goto out;
1503 } 1516 }
1504
1505 /* Finally, send the reply synchronously */ 1517 /* Finally, send the reply synchronously */
1506 memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf)); 1518 memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf));
1507 task = rpc_run_bc_task(req); 1519 task = rpc_run_bc_task(req);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 51d36230b6e3..4eb8fbf2508d 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -296,9 +296,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
296 request_module("svc%s", xprt_name); 296 request_module("svc%s", xprt_name);
297 err = _svc_create_xprt(serv, xprt_name, net, family, port, flags); 297 err = _svc_create_xprt(serv, xprt_name, net, family, port, flags);
298 } 298 }
299 if (err) 299 if (err < 0)
300 dprintk("svc: transport %s not found, err %d\n", 300 dprintk("svc: transport %s not found, err %d\n",
301 xprt_name, err); 301 xprt_name, -err);
302 return err; 302 return err;
303} 303}
304EXPORT_SYMBOL_GPL(svc_create_xprt); 304EXPORT_SYMBOL_GPL(svc_create_xprt);
@@ -468,10 +468,11 @@ out:
468 */ 468 */
469void svc_reserve(struct svc_rqst *rqstp, int space) 469void svc_reserve(struct svc_rqst *rqstp, int space)
470{ 470{
471 struct svc_xprt *xprt = rqstp->rq_xprt;
472
471 space += rqstp->rq_res.head[0].iov_len; 473 space += rqstp->rq_res.head[0].iov_len;
472 474
473 if (space < rqstp->rq_reserved) { 475 if (xprt && space < rqstp->rq_reserved) {
474 struct svc_xprt *xprt = rqstp->rq_xprt;
475 atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved); 476 atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved);
476 rqstp->rq_reserved = space; 477 rqstp->rq_reserved = space;
477 478
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 986f3ed7d1a2..c7ae1ed5324f 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -70,13 +70,6 @@ static void svc_sock_free(struct svc_xprt *);
70static struct svc_xprt *svc_create_socket(struct svc_serv *, int, 70static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
71 struct net *, struct sockaddr *, 71 struct net *, struct sockaddr *,
72 int, int); 72 int, int);
73#if defined(CONFIG_SUNRPC_BACKCHANNEL)
74static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int,
75 struct net *, struct sockaddr *,
76 int, int);
77static void svc_bc_sock_free(struct svc_xprt *xprt);
78#endif /* CONFIG_SUNRPC_BACKCHANNEL */
79
80#ifdef CONFIG_DEBUG_LOCK_ALLOC 73#ifdef CONFIG_DEBUG_LOCK_ALLOC
81static struct lock_class_key svc_key[2]; 74static struct lock_class_key svc_key[2];
82static struct lock_class_key svc_slock_key[2]; 75static struct lock_class_key svc_slock_key[2];
@@ -617,10 +610,6 @@ svc_udp_sendto(struct svc_rqst *rqstp)
617 return error; 610 return error;
618} 611}
619 612
620static void svc_udp_prep_reply_hdr(struct svc_rqst *rqstp)
621{
622}
623
624static int svc_udp_has_wspace(struct svc_xprt *xprt) 613static int svc_udp_has_wspace(struct svc_xprt *xprt)
625{ 614{
626 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt); 615 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
@@ -664,7 +653,6 @@ static const struct svc_xprt_ops svc_udp_ops = {
664 .xpo_release_rqst = svc_release_udp_skb, 653 .xpo_release_rqst = svc_release_udp_skb,
665 .xpo_detach = svc_sock_detach, 654 .xpo_detach = svc_sock_detach,
666 .xpo_free = svc_sock_free, 655 .xpo_free = svc_sock_free,
667 .xpo_prep_reply_hdr = svc_udp_prep_reply_hdr,
668 .xpo_has_wspace = svc_udp_has_wspace, 656 .xpo_has_wspace = svc_udp_has_wspace,
669 .xpo_accept = svc_udp_accept, 657 .xpo_accept = svc_udp_accept,
670 .xpo_secure_port = svc_sock_secure_port, 658 .xpo_secure_port = svc_sock_secure_port,
@@ -1170,17 +1158,6 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp)
1170 return sent; 1158 return sent;
1171} 1159}
1172 1160
1173/*
1174 * Setup response header. TCP has a 4B record length field.
1175 */
1176static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
1177{
1178 struct kvec *resv = &rqstp->rq_res.head[0];
1179
1180 /* tcp needs a space for the record length... */
1181 svc_putnl(resv, 0);
1182}
1183
1184static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, 1161static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
1185 struct net *net, 1162 struct net *net,
1186 struct sockaddr *sa, int salen, 1163 struct sockaddr *sa, int salen,
@@ -1189,58 +1166,6 @@ static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
1189 return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); 1166 return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
1190} 1167}
1191 1168
1192#if defined(CONFIG_SUNRPC_BACKCHANNEL)
1193static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int,
1194 struct net *, struct sockaddr *,
1195 int, int);
1196static void svc_bc_sock_free(struct svc_xprt *xprt);
1197
1198static struct svc_xprt *svc_bc_tcp_create(struct svc_serv *serv,
1199 struct net *net,
1200 struct sockaddr *sa, int salen,
1201 int flags)
1202{
1203 return svc_bc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
1204}
1205
1206static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt)
1207{
1208}
1209
1210static const struct svc_xprt_ops svc_tcp_bc_ops = {
1211 .xpo_create = svc_bc_tcp_create,
1212 .xpo_detach = svc_bc_tcp_sock_detach,
1213 .xpo_free = svc_bc_sock_free,
1214 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
1215 .xpo_secure_port = svc_sock_secure_port,
1216};
1217
1218static struct svc_xprt_class svc_tcp_bc_class = {
1219 .xcl_name = "tcp-bc",
1220 .xcl_owner = THIS_MODULE,
1221 .xcl_ops = &svc_tcp_bc_ops,
1222 .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
1223};
1224
1225static void svc_init_bc_xprt_sock(void)
1226{
1227 svc_reg_xprt_class(&svc_tcp_bc_class);
1228}
1229
1230static void svc_cleanup_bc_xprt_sock(void)
1231{
1232 svc_unreg_xprt_class(&svc_tcp_bc_class);
1233}
1234#else /* CONFIG_SUNRPC_BACKCHANNEL */
1235static void svc_init_bc_xprt_sock(void)
1236{
1237}
1238
1239static void svc_cleanup_bc_xprt_sock(void)
1240{
1241}
1242#endif /* CONFIG_SUNRPC_BACKCHANNEL */
1243
1244static const struct svc_xprt_ops svc_tcp_ops = { 1169static const struct svc_xprt_ops svc_tcp_ops = {
1245 .xpo_create = svc_tcp_create, 1170 .xpo_create = svc_tcp_create,
1246 .xpo_recvfrom = svc_tcp_recvfrom, 1171 .xpo_recvfrom = svc_tcp_recvfrom,
@@ -1248,7 +1173,6 @@ static const struct svc_xprt_ops svc_tcp_ops = {
1248 .xpo_release_rqst = svc_release_skb, 1173 .xpo_release_rqst = svc_release_skb,
1249 .xpo_detach = svc_tcp_sock_detach, 1174 .xpo_detach = svc_tcp_sock_detach,
1250 .xpo_free = svc_sock_free, 1175 .xpo_free = svc_sock_free,
1251 .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr,
1252 .xpo_has_wspace = svc_tcp_has_wspace, 1176 .xpo_has_wspace = svc_tcp_has_wspace,
1253 .xpo_accept = svc_tcp_accept, 1177 .xpo_accept = svc_tcp_accept,
1254 .xpo_secure_port = svc_sock_secure_port, 1178 .xpo_secure_port = svc_sock_secure_port,
@@ -1267,14 +1191,12 @@ void svc_init_xprt_sock(void)
1267{ 1191{
1268 svc_reg_xprt_class(&svc_tcp_class); 1192 svc_reg_xprt_class(&svc_tcp_class);
1269 svc_reg_xprt_class(&svc_udp_class); 1193 svc_reg_xprt_class(&svc_udp_class);
1270 svc_init_bc_xprt_sock();
1271} 1194}
1272 1195
1273void svc_cleanup_xprt_sock(void) 1196void svc_cleanup_xprt_sock(void)
1274{ 1197{
1275 svc_unreg_xprt_class(&svc_tcp_class); 1198 svc_unreg_xprt_class(&svc_tcp_class);
1276 svc_unreg_xprt_class(&svc_udp_class); 1199 svc_unreg_xprt_class(&svc_udp_class);
1277 svc_cleanup_bc_xprt_sock();
1278} 1200}
1279 1201
1280static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) 1202static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
@@ -1595,45 +1517,3 @@ static void svc_sock_free(struct svc_xprt *xprt)
1595 sock_release(svsk->sk_sock); 1517 sock_release(svsk->sk_sock);
1596 kfree(svsk); 1518 kfree(svsk);
1597} 1519}
1598
1599#if defined(CONFIG_SUNRPC_BACKCHANNEL)
1600/*
1601 * Create a back channel svc_xprt which shares the fore channel socket.
1602 */
1603static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
1604 int protocol,
1605 struct net *net,
1606 struct sockaddr *sin, int len,
1607 int flags)
1608{
1609 struct svc_sock *svsk;
1610 struct svc_xprt *xprt;
1611
1612 if (protocol != IPPROTO_TCP) {
1613 printk(KERN_WARNING "svc: only TCP sockets"
1614 " supported on shared back channel\n");
1615 return ERR_PTR(-EINVAL);
1616 }
1617
1618 svsk = kzalloc(sizeof(*svsk), GFP_KERNEL);
1619 if (!svsk)
1620 return ERR_PTR(-ENOMEM);
1621
1622 xprt = &svsk->sk_xprt;
1623 svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
1624 set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
1625
1626 serv->sv_bc_xprt = xprt;
1627
1628 return xprt;
1629}
1630
1631/*
1632 * Free a back channel svc_sock.
1633 */
1634static void svc_bc_sock_free(struct svc_xprt *xprt)
1635{
1636 if (xprt)
1637 kfree(container_of(xprt, struct svc_sock, sk_xprt));
1638}
1639#endif /* CONFIG_SUNRPC_BACKCHANNEL */
diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c
index e5b367a3e517..edba0d35776b 100644
--- a/net/sunrpc/xprtrdma/backchannel.c
+++ b/net/sunrpc/xprtrdma/backchannel.c
@@ -114,26 +114,6 @@ out_err:
114} 114}
115 115
116/** 116/**
117 * xprt_rdma_bc_up - Create transport endpoint for backchannel service
118 * @serv: server endpoint
119 * @net: network namespace
120 *
121 * The "xprt" is an implied argument: it supplies the name of the
122 * backchannel transport class.
123 *
124 * Returns zero on success, negative errno on failure
125 */
126int xprt_rdma_bc_up(struct svc_serv *serv, struct net *net)
127{
128 int ret;
129
130 ret = svc_create_xprt(serv, "rdma-bc", net, PF_INET, 0, 0);
131 if (ret < 0)
132 return ret;
133 return 0;
134}
135
136/**
137 * xprt_rdma_bc_maxpayload - Return maximum backchannel message size 117 * xprt_rdma_bc_maxpayload - Return maximum backchannel message size
138 * @xprt: transport 118 * @xprt: transport
139 * 119 *
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
index 134bef6a451e..abdb3004a1e3 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -235,9 +235,6 @@ void svc_rdma_cleanup(void)
235 unregister_sysctl_table(svcrdma_table_header); 235 unregister_sysctl_table(svcrdma_table_header);
236 svcrdma_table_header = NULL; 236 svcrdma_table_header = NULL;
237 } 237 }
238#if defined(CONFIG_SUNRPC_BACKCHANNEL)
239 svc_unreg_xprt_class(&svc_rdma_bc_class);
240#endif
241 svc_unreg_xprt_class(&svc_rdma_class); 238 svc_unreg_xprt_class(&svc_rdma_class);
242} 239}
243 240
@@ -259,8 +256,5 @@ int svc_rdma_init(void)
259 256
260 /* Register RDMA with the SVC transport switch */ 257 /* Register RDMA with the SVC transport switch */
261 svc_reg_xprt_class(&svc_rdma_class); 258 svc_reg_xprt_class(&svc_rdma_class);
262#if defined(CONFIG_SUNRPC_BACKCHANNEL)
263 svc_reg_xprt_class(&svc_rdma_bc_class);
264#endif
265 return 0; 259 return 0;
266} 260}
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index b24d5b8f2fee..828b149eaaef 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -485,6 +485,68 @@ static __be32 *xdr_check_reply_chunk(__be32 *p, const __be32 *end)
485 return p; 485 return p;
486} 486}
487 487
488/* RPC-over-RDMA Version One private extension: Remote Invalidation.
489 * Responder's choice: requester signals it can handle Send With
490 * Invalidate, and responder chooses one R_key to invalidate.
491 *
492 * If there is exactly one distinct R_key in the received transport
493 * header, set rc_inv_rkey to that R_key. Otherwise, set it to zero.
494 *
495 * Perform this operation while the received transport header is
496 * still in the CPU cache.
497 */
498static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma,
499 struct svc_rdma_recv_ctxt *ctxt)
500{
501 __be32 inv_rkey, *p;
502 u32 i, segcount;
503
504 ctxt->rc_inv_rkey = 0;
505
506 if (!rdma->sc_snd_w_inv)
507 return;
508
509 inv_rkey = xdr_zero;
510 p = ctxt->rc_recv_buf;
511 p += rpcrdma_fixed_maxsz;
512
513 /* Read list */
514 while (*p++ != xdr_zero) {
515 p++; /* position */
516 if (inv_rkey == xdr_zero)
517 inv_rkey = *p;
518 else if (inv_rkey != *p)
519 return;
520 p += 4;
521 }
522
523 /* Write list */
524 while (*p++ != xdr_zero) {
525 segcount = be32_to_cpup(p++);
526 for (i = 0; i < segcount; i++) {
527 if (inv_rkey == xdr_zero)
528 inv_rkey = *p;
529 else if (inv_rkey != *p)
530 return;
531 p += 4;
532 }
533 }
534
535 /* Reply chunk */
536 if (*p++ != xdr_zero) {
537 segcount = be32_to_cpup(p++);
538 for (i = 0; i < segcount; i++) {
539 if (inv_rkey == xdr_zero)
540 inv_rkey = *p;
541 else if (inv_rkey != *p)
542 return;
543 p += 4;
544 }
545 }
546
547 ctxt->rc_inv_rkey = be32_to_cpu(inv_rkey);
548}
549
488/* On entry, xdr->head[0].iov_base points to first byte in the 550/* On entry, xdr->head[0].iov_base points to first byte in the
489 * RPC-over-RDMA header. 551 * RPC-over-RDMA header.
490 * 552 *
@@ -746,6 +808,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
746 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt); 808 svc_rdma_recv_ctxt_put(rdma_xprt, ctxt);
747 return ret; 809 return ret;
748 } 810 }
811 svc_rdma_get_inv_rkey(rdma_xprt, ctxt);
749 812
750 p += rpcrdma_fixed_maxsz; 813 p += rpcrdma_fixed_maxsz;
751 if (*p != xdr_zero) 814 if (*p != xdr_zero)
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 8602a5f1b515..cf51b8f9b15f 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -484,32 +484,6 @@ static void svc_rdma_get_write_arrays(__be32 *rdma_argp,
484 *reply = NULL; 484 *reply = NULL;
485} 485}
486 486
487/* RPC-over-RDMA Version One private extension: Remote Invalidation.
488 * Responder's choice: requester signals it can handle Send With
489 * Invalidate, and responder chooses one rkey to invalidate.
490 *
491 * Find a candidate rkey to invalidate when sending a reply. Picks the
492 * first R_key it finds in the chunk lists.
493 *
494 * Returns zero if RPC's chunk lists are empty.
495 */
496static u32 svc_rdma_get_inv_rkey(__be32 *rdma_argp,
497 __be32 *wr_lst, __be32 *rp_ch)
498{
499 __be32 *p;
500
501 p = rdma_argp + rpcrdma_fixed_maxsz;
502 if (*p != xdr_zero)
503 p += 2;
504 else if (wr_lst && be32_to_cpup(wr_lst + 1))
505 p = wr_lst + 2;
506 else if (rp_ch && be32_to_cpup(rp_ch + 1))
507 p = rp_ch + 2;
508 else
509 return 0;
510 return be32_to_cpup(p);
511}
512
513static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma, 487static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma,
514 struct svc_rdma_send_ctxt *ctxt, 488 struct svc_rdma_send_ctxt *ctxt,
515 struct page *page, 489 struct page *page,
@@ -672,7 +646,7 @@ static void svc_rdma_save_io_pages(struct svc_rqst *rqstp,
672 * 646 *
673 * RDMA Send is the last step of transmitting an RPC reply. Pages 647 * RDMA Send is the last step of transmitting an RPC reply. Pages
674 * involved in the earlier RDMA Writes are here transferred out 648 * involved in the earlier RDMA Writes are here transferred out
675 * of the rqstp and into the ctxt's page array. These pages are 649 * of the rqstp and into the sctxt's page array. These pages are
676 * DMA unmapped by each Write completion, but the subsequent Send 650 * DMA unmapped by each Write completion, but the subsequent Send
677 * completion finally releases these pages. 651 * completion finally releases these pages.
678 * 652 *
@@ -680,32 +654,31 @@ static void svc_rdma_save_io_pages(struct svc_rqst *rqstp,
680 * - The Reply's transport header will never be larger than a page. 654 * - The Reply's transport header will never be larger than a page.
681 */ 655 */
682static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, 656static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma,
683 struct svc_rdma_send_ctxt *ctxt, 657 struct svc_rdma_send_ctxt *sctxt,
684 __be32 *rdma_argp, 658 struct svc_rdma_recv_ctxt *rctxt,
685 struct svc_rqst *rqstp, 659 struct svc_rqst *rqstp,
686 __be32 *wr_lst, __be32 *rp_ch) 660 __be32 *wr_lst, __be32 *rp_ch)
687{ 661{
688 int ret; 662 int ret;
689 663
690 if (!rp_ch) { 664 if (!rp_ch) {
691 ret = svc_rdma_map_reply_msg(rdma, ctxt, 665 ret = svc_rdma_map_reply_msg(rdma, sctxt,
692 &rqstp->rq_res, wr_lst); 666 &rqstp->rq_res, wr_lst);
693 if (ret < 0) 667 if (ret < 0)
694 return ret; 668 return ret;
695 } 669 }
696 670
697 svc_rdma_save_io_pages(rqstp, ctxt); 671 svc_rdma_save_io_pages(rqstp, sctxt);
698 672
699 ctxt->sc_send_wr.opcode = IB_WR_SEND; 673 if (rctxt->rc_inv_rkey) {
700 if (rdma->sc_snd_w_inv) { 674 sctxt->sc_send_wr.opcode = IB_WR_SEND_WITH_INV;
701 ctxt->sc_send_wr.ex.invalidate_rkey = 675 sctxt->sc_send_wr.ex.invalidate_rkey = rctxt->rc_inv_rkey;
702 svc_rdma_get_inv_rkey(rdma_argp, wr_lst, rp_ch); 676 } else {
703 if (ctxt->sc_send_wr.ex.invalidate_rkey) 677 sctxt->sc_send_wr.opcode = IB_WR_SEND;
704 ctxt->sc_send_wr.opcode = IB_WR_SEND_WITH_INV;
705 } 678 }
706 dprintk("svcrdma: posting Send WR with %u sge(s)\n", 679 dprintk("svcrdma: posting Send WR with %u sge(s)\n",
707 ctxt->sc_send_wr.num_sge); 680 sctxt->sc_send_wr.num_sge);
708 return svc_rdma_send(rdma, &ctxt->sc_send_wr); 681 return svc_rdma_send(rdma, &sctxt->sc_send_wr);
709} 682}
710 683
711/* Given the client-provided Write and Reply chunks, the server was not 684/* Given the client-provided Write and Reply chunks, the server was not
@@ -741,10 +714,6 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma,
741 return 0; 714 return 0;
742} 715}
743 716
744void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp)
745{
746}
747
748/** 717/**
749 * svc_rdma_sendto - Transmit an RPC reply 718 * svc_rdma_sendto - Transmit an RPC reply
750 * @rqstp: processed RPC request, reply XDR already in ::rq_res 719 * @rqstp: processed RPC request, reply XDR already in ::rq_res
@@ -809,7 +778,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
809 } 778 }
810 779
811 svc_rdma_sync_reply_hdr(rdma, sctxt, svc_rdma_reply_hdr_len(rdma_resp)); 780 svc_rdma_sync_reply_hdr(rdma, sctxt, svc_rdma_reply_hdr_len(rdma_resp));
812 ret = svc_rdma_send_reply_msg(rdma, sctxt, rdma_argp, rqstp, 781 ret = svc_rdma_send_reply_msg(rdma, sctxt, rctxt, rqstp,
813 wr_lst, rp_ch); 782 wr_lst, rp_ch);
814 if (ret < 0) 783 if (ret < 0)
815 goto err1; 784 goto err1;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 2f7ec8912f49..924c17d46903 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -85,7 +85,6 @@ static const struct svc_xprt_ops svc_rdma_ops = {
85 .xpo_release_rqst = svc_rdma_release_rqst, 85 .xpo_release_rqst = svc_rdma_release_rqst,
86 .xpo_detach = svc_rdma_detach, 86 .xpo_detach = svc_rdma_detach,
87 .xpo_free = svc_rdma_free, 87 .xpo_free = svc_rdma_free,
88 .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr,
89 .xpo_has_wspace = svc_rdma_has_wspace, 88 .xpo_has_wspace = svc_rdma_has_wspace,
90 .xpo_accept = svc_rdma_accept, 89 .xpo_accept = svc_rdma_accept,
91 .xpo_secure_port = svc_rdma_secure_port, 90 .xpo_secure_port = svc_rdma_secure_port,
@@ -100,64 +99,6 @@ struct svc_xprt_class svc_rdma_class = {
100 .xcl_ident = XPRT_TRANSPORT_RDMA, 99 .xcl_ident = XPRT_TRANSPORT_RDMA,
101}; 100};
102 101
103#if defined(CONFIG_SUNRPC_BACKCHANNEL)
104static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *, struct net *,
105 struct sockaddr *, int, int);
106static void svc_rdma_bc_detach(struct svc_xprt *);
107static void svc_rdma_bc_free(struct svc_xprt *);
108
109static const struct svc_xprt_ops svc_rdma_bc_ops = {
110 .xpo_create = svc_rdma_bc_create,
111 .xpo_detach = svc_rdma_bc_detach,
112 .xpo_free = svc_rdma_bc_free,
113 .xpo_prep_reply_hdr = svc_rdma_prep_reply_hdr,
114 .xpo_secure_port = svc_rdma_secure_port,
115};
116
117struct svc_xprt_class svc_rdma_bc_class = {
118 .xcl_name = "rdma-bc",
119 .xcl_owner = THIS_MODULE,
120 .xcl_ops = &svc_rdma_bc_ops,
121 .xcl_max_payload = (1024 - RPCRDMA_HDRLEN_MIN)
122};
123
124static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *serv,
125 struct net *net,
126 struct sockaddr *sa, int salen,
127 int flags)
128{
129 struct svcxprt_rdma *cma_xprt;
130 struct svc_xprt *xprt;
131
132 cma_xprt = svc_rdma_create_xprt(serv, net);
133 if (!cma_xprt)
134 return ERR_PTR(-ENOMEM);
135 xprt = &cma_xprt->sc_xprt;
136
137 svc_xprt_init(net, &svc_rdma_bc_class, xprt, serv);
138 set_bit(XPT_CONG_CTRL, &xprt->xpt_flags);
139 serv->sv_bc_xprt = xprt;
140
141 dprintk("svcrdma: %s(%p)\n", __func__, xprt);
142 return xprt;
143}
144
145static void svc_rdma_bc_detach(struct svc_xprt *xprt)
146{
147 dprintk("svcrdma: %s(%p)\n", __func__, xprt);
148}
149
150static void svc_rdma_bc_free(struct svc_xprt *xprt)
151{
152 struct svcxprt_rdma *rdma =
153 container_of(xprt, struct svcxprt_rdma, sc_xprt);
154
155 dprintk("svcrdma: %s(%p)\n", __func__, xprt);
156 if (xprt)
157 kfree(rdma);
158}
159#endif /* CONFIG_SUNRPC_BACKCHANNEL */
160
161/* QP event handler */ 102/* QP event handler */
162static void qp_event_handler(struct ib_event *event, void *context) 103static void qp_event_handler(struct ib_event *event, void *context)
163{ 104{
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index ae2a83828953..9141068693fa 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -827,7 +827,6 @@ static const struct rpc_xprt_ops xprt_rdma_procs = {
827 .inject_disconnect = xprt_rdma_inject_disconnect, 827 .inject_disconnect = xprt_rdma_inject_disconnect,
828#if defined(CONFIG_SUNRPC_BACKCHANNEL) 828#if defined(CONFIG_SUNRPC_BACKCHANNEL)
829 .bc_setup = xprt_rdma_bc_setup, 829 .bc_setup = xprt_rdma_bc_setup,
830 .bc_up = xprt_rdma_bc_up,
831 .bc_maxpayload = xprt_rdma_bc_maxpayload, 830 .bc_maxpayload = xprt_rdma_bc_maxpayload,
832 .bc_free_rqst = xprt_rdma_bc_free_rqst, 831 .bc_free_rqst = xprt_rdma_bc_free_rqst,
833 .bc_destroy = xprt_rdma_bc_destroy, 832 .bc_destroy = xprt_rdma_bc_destroy,
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index a13ccb643ce0..9218dbebedce 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -661,7 +661,6 @@ void xprt_rdma_cleanup(void);
661 */ 661 */
662#if defined(CONFIG_SUNRPC_BACKCHANNEL) 662#if defined(CONFIG_SUNRPC_BACKCHANNEL)
663int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int); 663int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int);
664int xprt_rdma_bc_up(struct svc_serv *, struct net *);
665size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *); 664size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *);
666int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int); 665int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int);
667void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *); 666void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index f0b3700cec95..44467caf3cd8 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1400,17 +1400,6 @@ static void xs_tcp_force_close(struct rpc_xprt *xprt)
1400} 1400}
1401 1401
1402#if defined(CONFIG_SUNRPC_BACKCHANNEL) 1402#if defined(CONFIG_SUNRPC_BACKCHANNEL)
1403static int xs_tcp_bc_up(struct svc_serv *serv, struct net *net)
1404{
1405 int ret;
1406
1407 ret = svc_create_xprt(serv, "tcp-bc", net, PF_INET, 0,
1408 SVC_SOCK_ANONYMOUS);
1409 if (ret < 0)
1410 return ret;
1411 return 0;
1412}
1413
1414static size_t xs_tcp_bc_maxpayload(struct rpc_xprt *xprt) 1403static size_t xs_tcp_bc_maxpayload(struct rpc_xprt *xprt)
1415{ 1404{
1416 return PAGE_SIZE; 1405 return PAGE_SIZE;
@@ -2665,7 +2654,6 @@ static const struct rpc_xprt_ops xs_tcp_ops = {
2665 .inject_disconnect = xs_inject_disconnect, 2654 .inject_disconnect = xs_inject_disconnect,
2666#ifdef CONFIG_SUNRPC_BACKCHANNEL 2655#ifdef CONFIG_SUNRPC_BACKCHANNEL
2667 .bc_setup = xprt_setup_bc, 2656 .bc_setup = xprt_setup_bc,
2668 .bc_up = xs_tcp_bc_up,
2669 .bc_maxpayload = xs_tcp_bc_maxpayload, 2657 .bc_maxpayload = xs_tcp_bc_maxpayload,
2670 .bc_free_rqst = xprt_free_bc_rqst, 2658 .bc_free_rqst = xprt_free_bc_rqst,
2671 .bc_destroy = xprt_destroy_bc, 2659 .bc_destroy = xprt_destroy_bc,