Skip to content

Commit a73881c

Browse files
author
Trond Myklebust
committed
SUNRPC: Fix an Oops in udp_poll()
udp_poll() checks the struct file for the O_NONBLOCK flag, so we must not call it with a NULL file pointer. Fixes: 0ffe86f ("SUNRPC: Use poll() to fix up the socket requeue races") Signed-off-by: Trond Myklebust <[email protected]>
1 parent 06b5fc3 commit a73881c

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

include/linux/sunrpc/xprtsock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct sock_xprt {
2626
*/
2727
struct socket * sock;
2828
struct sock * inet;
29+
struct file * file;
2930

3031
/*
3132
* State of TCP reply receive

net/sunrpc/xprtsock.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,8 @@ xs_read_stream(struct sock_xprt *transport, int flags)
670670

671671
static __poll_t xs_poll_socket(struct sock_xprt *transport)
672672
{
673-
return transport->sock->ops->poll(NULL, transport->sock, NULL);
673+
return transport->sock->ops->poll(transport->file, transport->sock,
674+
NULL);
674675
}
675676

676677
static bool xs_poll_socket_readable(struct sock_xprt *transport)
@@ -1253,6 +1254,7 @@ static void xs_reset_transport(struct sock_xprt *transport)
12531254
struct socket *sock = transport->sock;
12541255
struct sock *sk = transport->inet;
12551256
struct rpc_xprt *xprt = &transport->xprt;
1257+
struct file *filp = transport->file;
12561258

12571259
if (sk == NULL)
12581260
return;
@@ -1266,6 +1268,7 @@ static void xs_reset_transport(struct sock_xprt *transport)
12661268
write_lock_bh(&sk->sk_callback_lock);
12671269
transport->inet = NULL;
12681270
transport->sock = NULL;
1271+
transport->file = NULL;
12691272

12701273
sk->sk_user_data = NULL;
12711274

@@ -1278,7 +1281,7 @@ static void xs_reset_transport(struct sock_xprt *transport)
12781281
mutex_unlock(&transport->recv_mutex);
12791282

12801283
trace_rpc_socket_close(xprt, sock);
1281-
sock_release(sock);
1284+
fput(filp);
12821285

12831286
xprt_disconnect_done(xprt);
12841287
}
@@ -1873,6 +1876,7 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt,
18731876
struct sock_xprt *transport, int family, int type,
18741877
int protocol, bool reuseport)
18751878
{
1879+
struct file *filp;
18761880
struct socket *sock;
18771881
int err;
18781882

@@ -1893,6 +1897,11 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt,
18931897
goto out;
18941898
}
18951899

1900+
filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
1901+
if (IS_ERR(filp))
1902+
return ERR_CAST(filp);
1903+
transport->file = filp;
1904+
18961905
return sock;
18971906
out:
18981907
return ERR_PTR(err);
@@ -1938,6 +1947,7 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
19381947
static int xs_local_setup_socket(struct sock_xprt *transport)
19391948
{
19401949
struct rpc_xprt *xprt = &transport->xprt;
1950+
struct file *filp;
19411951
struct socket *sock;
19421952
int status = -EIO;
19431953

@@ -1950,6 +1960,13 @@ static int xs_local_setup_socket(struct sock_xprt *transport)
19501960
}
19511961
xs_reclassify_socket(AF_LOCAL, sock);
19521962

1963+
filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
1964+
if (IS_ERR(filp)) {
1965+
status = PTR_ERR(filp);
1966+
goto out;
1967+
}
1968+
transport->file = filp;
1969+
19531970
dprintk("RPC: worker connecting xprt %p via AF_LOCAL to %s\n",
19541971
xprt, xprt->address_strings[RPC_DISPLAY_ADDR]);
19551972

0 commit comments

Comments
 (0)