One fix for an NFS/RDMA crash.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJYLznTAAoJECebzXlCjuG+ThgP/0tQByIqOKGqUNcEE0MLT4/+ E2/V/Basi3tnCIatAjYZiAN/rKnO5f4iuyh7PKG/bzlYluLv5MLq68HUia8EorN8 LExNvZAwYhjEQwDTzhBSityLHWmCwy3G0yYsJQ1DnbUdh8wAKr7lj4R0sr8RGJc1 GxgWnlhi2lAJSGYRa8tYHzh0tTXGOCoR8POKXFJ91PTx8gEO6VzULvbIQm0RLSow +LGW36ov/ChQtJzVJsfcW6Hf4wHFevrtVTPtLWckMEtRq/DJ7hS2btgc02hpqFZm MK7wywHT35LV+DvU6QPmwUUaf5IXJjWx0W7thOsjWbYMbAHC/0D3De8bgGaAI3B1 nB+B96BpGrALyhTX2pXQiQxsavXBl37BOGl3Ft03WrAVI4aJsfkaWDRS2X1jxfXI zhGBN2vseoiJblie95hLIgvMtkRmOq4E44oNDiP9zKTwrIkISoz5jmvLHY/8Mj7E NCof2P+K6ays8ywD2DqHlJKmiGA7PdNT87ZeeS4ZFvEjWSd4S1pfa0R+jg5FVxZl Vl7QQX5D/Ep+sXszJin4dYQnl844+sVMVaj6CdQOK0udml81UZTRO5fvjNexs3e4 4Zd/ymC/XGs6Hz3pbPeIkAd/MzXCK0zNojNAdZnicOMzQpG2sZ76SJRZQg0sTCFH EP6QTWxOog4lnDfML13E =F2DQ -----END PGP SIGNATURE----- Merge tag 'nfsd-4.9-2' of git://linux-nfs.org/~bfields/linux Pull nfsd bugfix from Bruce Fields: "Just one fix for an NFS/RDMA crash" * tag 'nfsd-4.9-2' of git://linux-nfs.org/~bfields/linux: sunrpc: svc_age_temp_xprts_now should not call setsockopt non-tcp transports
This commit is contained in:
commit
aad931a30f
|
@ -25,6 +25,7 @@ struct svc_xprt_ops {
|
||||||
void (*xpo_detach)(struct svc_xprt *);
|
void (*xpo_detach)(struct svc_xprt *);
|
||||||
void (*xpo_free)(struct svc_xprt *);
|
void (*xpo_free)(struct svc_xprt *);
|
||||||
int (*xpo_secure_port)(struct svc_rqst *);
|
int (*xpo_secure_port)(struct svc_rqst *);
|
||||||
|
void (*xpo_kill_temp_xprt)(struct svc_xprt *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct svc_xprt_class {
|
struct svc_xprt_class {
|
||||||
|
|
|
@ -1002,14 +1002,8 @@ static void svc_age_temp_xprts(unsigned long closure)
|
||||||
void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
|
void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
|
||||||
{
|
{
|
||||||
struct svc_xprt *xprt;
|
struct svc_xprt *xprt;
|
||||||
struct svc_sock *svsk;
|
|
||||||
struct socket *sock;
|
|
||||||
struct list_head *le, *next;
|
struct list_head *le, *next;
|
||||||
LIST_HEAD(to_be_closed);
|
LIST_HEAD(to_be_closed);
|
||||||
struct linger no_linger = {
|
|
||||||
.l_onoff = 1,
|
|
||||||
.l_linger = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
spin_lock_bh(&serv->sv_lock);
|
spin_lock_bh(&serv->sv_lock);
|
||||||
list_for_each_safe(le, next, &serv->sv_tempsocks) {
|
list_for_each_safe(le, next, &serv->sv_tempsocks) {
|
||||||
|
@ -1027,10 +1021,7 @@ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
|
||||||
list_del_init(le);
|
list_del_init(le);
|
||||||
xprt = list_entry(le, struct svc_xprt, xpt_list);
|
xprt = list_entry(le, struct svc_xprt, xpt_list);
|
||||||
dprintk("svc_age_temp_xprts_now: closing %p\n", xprt);
|
dprintk("svc_age_temp_xprts_now: closing %p\n", xprt);
|
||||||
svsk = container_of(xprt, struct svc_sock, sk_xprt);
|
xprt->xpt_ops->xpo_kill_temp_xprt(xprt);
|
||||||
sock = svsk->sk_sock;
|
|
||||||
kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
|
|
||||||
(char *)&no_linger, sizeof(no_linger));
|
|
||||||
svc_close_xprt(xprt);
|
svc_close_xprt(xprt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -438,6 +438,21 @@ static int svc_tcp_has_wspace(struct svc_xprt *xprt)
|
||||||
return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
|
return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void svc_tcp_kill_temp_xprt(struct svc_xprt *xprt)
|
||||||
|
{
|
||||||
|
struct svc_sock *svsk;
|
||||||
|
struct socket *sock;
|
||||||
|
struct linger no_linger = {
|
||||||
|
.l_onoff = 1,
|
||||||
|
.l_linger = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
svsk = container_of(xprt, struct svc_sock, sk_xprt);
|
||||||
|
sock = svsk->sk_sock;
|
||||||
|
kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
|
||||||
|
(char *)&no_linger, sizeof(no_linger));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
|
* See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
|
||||||
*/
|
*/
|
||||||
|
@ -648,6 +663,10 @@ static struct svc_xprt *svc_udp_accept(struct svc_xprt *xprt)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void svc_udp_kill_temp_xprt(struct svc_xprt *xprt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static struct svc_xprt *svc_udp_create(struct svc_serv *serv,
|
static struct svc_xprt *svc_udp_create(struct svc_serv *serv,
|
||||||
struct net *net,
|
struct net *net,
|
||||||
struct sockaddr *sa, int salen,
|
struct sockaddr *sa, int salen,
|
||||||
|
@ -667,6 +686,7 @@ static struct svc_xprt_ops svc_udp_ops = {
|
||||||
.xpo_has_wspace = svc_udp_has_wspace,
|
.xpo_has_wspace = svc_udp_has_wspace,
|
||||||
.xpo_accept = svc_udp_accept,
|
.xpo_accept = svc_udp_accept,
|
||||||
.xpo_secure_port = svc_sock_secure_port,
|
.xpo_secure_port = svc_sock_secure_port,
|
||||||
|
.xpo_kill_temp_xprt = svc_udp_kill_temp_xprt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct svc_xprt_class svc_udp_class = {
|
static struct svc_xprt_class svc_udp_class = {
|
||||||
|
@ -1242,6 +1262,7 @@ static struct svc_xprt_ops svc_tcp_ops = {
|
||||||
.xpo_has_wspace = svc_tcp_has_wspace,
|
.xpo_has_wspace = svc_tcp_has_wspace,
|
||||||
.xpo_accept = svc_tcp_accept,
|
.xpo_accept = svc_tcp_accept,
|
||||||
.xpo_secure_port = svc_sock_secure_port,
|
.xpo_secure_port = svc_sock_secure_port,
|
||||||
|
.xpo_kill_temp_xprt = svc_tcp_kill_temp_xprt,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct svc_xprt_class svc_tcp_class = {
|
static struct svc_xprt_class svc_tcp_class = {
|
||||||
|
|
|
@ -67,6 +67,7 @@ static void svc_rdma_detach(struct svc_xprt *xprt);
|
||||||
static void svc_rdma_free(struct svc_xprt *xprt);
|
static void svc_rdma_free(struct svc_xprt *xprt);
|
||||||
static int svc_rdma_has_wspace(struct svc_xprt *xprt);
|
static int svc_rdma_has_wspace(struct svc_xprt *xprt);
|
||||||
static int svc_rdma_secure_port(struct svc_rqst *);
|
static int svc_rdma_secure_port(struct svc_rqst *);
|
||||||
|
static void svc_rdma_kill_temp_xprt(struct svc_xprt *);
|
||||||
|
|
||||||
static struct svc_xprt_ops svc_rdma_ops = {
|
static struct svc_xprt_ops svc_rdma_ops = {
|
||||||
.xpo_create = svc_rdma_create,
|
.xpo_create = svc_rdma_create,
|
||||||
|
@ -79,6 +80,7 @@ static struct svc_xprt_ops svc_rdma_ops = {
|
||||||
.xpo_has_wspace = svc_rdma_has_wspace,
|
.xpo_has_wspace = svc_rdma_has_wspace,
|
||||||
.xpo_accept = svc_rdma_accept,
|
.xpo_accept = svc_rdma_accept,
|
||||||
.xpo_secure_port = svc_rdma_secure_port,
|
.xpo_secure_port = svc_rdma_secure_port,
|
||||||
|
.xpo_kill_temp_xprt = svc_rdma_kill_temp_xprt,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct svc_xprt_class svc_rdma_class = {
|
struct svc_xprt_class svc_rdma_class = {
|
||||||
|
@ -1317,6 +1319,10 @@ static int svc_rdma_secure_port(struct svc_rqst *rqstp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
|
int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
|
||||||
{
|
{
|
||||||
struct ib_send_wr *bad_wr, *n_wr;
|
struct ib_send_wr *bad_wr, *n_wr;
|
||||||
|
|
Loading…
Reference in New Issue