diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-02 19:21:50 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-02 19:21:50 -0500 |
| commit | e45428a436765fcd154d461a2739b5640916dc00 (patch) | |
| tree | 6f9e52b8e02471353bbe5247b37ba2991dfdca3b /net | |
| parent | 85f78456f286da46fb054c7d45e4193cb757ac83 (diff) | |
| parent | 0ad30ff67bd3e82da8c1dc4d74b88aca846dbbd9 (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.c | 8 | ||||
| -rw-r--r-- | net/sunrpc/cache.c | 10 | ||||
| -rw-r--r-- | net/sunrpc/svc.c | 24 | ||||
| -rw-r--r-- | net/sunrpc/svc_xprt.c | 9 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 120 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/backchannel.c | 20 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma.c | 6 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 63 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_sendto.c | 57 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 59 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/transport.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 12 |
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 | ||
| 57 | static void cache_fresh_locked(struct cache_head *head, time_t expiry, | ||
| 58 | struct cache_detail *detail); | ||
| 59 | static void cache_fresh_unlocked(struct cache_head *head, | ||
| 60 | struct cache_detail *detail); | ||
| 61 | |||
| 57 | static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail, | 62 | static 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 | */ | ||
| 1150 | static 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 | */ |
| 1150 | static int | 1161 | static 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 | } |
| 304 | EXPORT_SYMBOL_GPL(svc_create_xprt); | 304 | EXPORT_SYMBOL_GPL(svc_create_xprt); |
| @@ -468,10 +468,11 @@ out: | |||
| 468 | */ | 468 | */ |
| 469 | void svc_reserve(struct svc_rqst *rqstp, int space) | 469 | void 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 *); | |||
| 70 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 70 | static 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) | ||
| 74 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
| 75 | struct net *, struct sockaddr *, | ||
| 76 | int, int); | ||
| 77 | static 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 |
| 81 | static struct lock_class_key svc_key[2]; | 74 | static struct lock_class_key svc_key[2]; |
| 82 | static struct lock_class_key svc_slock_key[2]; | 75 | static 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 | ||
| 620 | static void svc_udp_prep_reply_hdr(struct svc_rqst *rqstp) | ||
| 621 | { | ||
| 622 | } | ||
| 623 | |||
| 624 | static int svc_udp_has_wspace(struct svc_xprt *xprt) | 613 | static 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 | */ | ||
| 1176 | static 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 | |||
| 1184 | static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, | 1161 | static 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) | ||
| 1193 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
| 1194 | struct net *, struct sockaddr *, | ||
| 1195 | int, int); | ||
| 1196 | static void svc_bc_sock_free(struct svc_xprt *xprt); | ||
| 1197 | |||
| 1198 | static 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 | |||
| 1206 | static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt) | ||
| 1207 | { | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | static 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 | |||
| 1218 | static 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 | |||
| 1225 | static void svc_init_bc_xprt_sock(void) | ||
| 1226 | { | ||
| 1227 | svc_reg_xprt_class(&svc_tcp_bc_class); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | static void svc_cleanup_bc_xprt_sock(void) | ||
| 1231 | { | ||
| 1232 | svc_unreg_xprt_class(&svc_tcp_bc_class); | ||
| 1233 | } | ||
| 1234 | #else /* CONFIG_SUNRPC_BACKCHANNEL */ | ||
| 1235 | static void svc_init_bc_xprt_sock(void) | ||
| 1236 | { | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | static void svc_cleanup_bc_xprt_sock(void) | ||
| 1240 | { | ||
| 1241 | } | ||
| 1242 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ | ||
| 1243 | |||
| 1244 | static const struct svc_xprt_ops svc_tcp_ops = { | 1169 | static 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 | ||
| 1273 | void svc_cleanup_xprt_sock(void) | 1196 | void 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 | ||
| 1280 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | 1202 | static 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 | */ | ||
| 1603 | static 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 | */ | ||
| 1634 | static 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 | */ | ||
| 126 | int 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 | */ | ||
| 498 | static 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 | */ | ||
| 496 | static 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 | |||
| 513 | static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma, | 487 | static 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 | */ |
| 682 | static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, | 656 | static 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 | ||
| 744 | void 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) | ||
| 104 | static struct svc_xprt *svc_rdma_bc_create(struct svc_serv *, struct net *, | ||
| 105 | struct sockaddr *, int, int); | ||
| 106 | static void svc_rdma_bc_detach(struct svc_xprt *); | ||
| 107 | static void svc_rdma_bc_free(struct svc_xprt *); | ||
| 108 | |||
| 109 | static 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 | |||
| 117 | struct 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 | |||
| 124 | static 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 | |||
| 145 | static void svc_rdma_bc_detach(struct svc_xprt *xprt) | ||
| 146 | { | ||
| 147 | dprintk("svcrdma: %s(%p)\n", __func__, xprt); | ||
| 148 | } | ||
| 149 | |||
| 150 | static 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 */ |
| 162 | static void qp_event_handler(struct ib_event *event, void *context) | 103 | static 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) |
| 663 | int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int); | 663 | int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int); |
| 664 | int xprt_rdma_bc_up(struct svc_serv *, struct net *); | ||
| 665 | size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *); | 664 | size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *); |
| 666 | int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int); | 665 | int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int); |
| 667 | void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *); | 666 | void 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) |
| 1403 | static 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 | |||
| 1414 | static size_t xs_tcp_bc_maxpayload(struct rpc_xprt *xprt) | 1403 | static 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, |
