Commit 210f0353 authored by David Howells's avatar David Howells

rxrpc: Allow listen(sock, 0) to be used to disable listening

Allow listen() with a backlog of 0 to be used to disable listening on an
AF_RXRPC socket.  This also releases any preallocation, thereby making it
easier for a kernel service to account for all allocated call structures
when shutting down the service.

The socket cannot thereafter have listening reenabled, but must rather be
closed and reopened.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 56ff9c83
...@@ -224,6 +224,14 @@ static int rxrpc_listen(struct socket *sock, int backlog) ...@@ -224,6 +224,14 @@ static int rxrpc_listen(struct socket *sock, int backlog)
else else
sk->sk_max_ack_backlog = old; sk->sk_max_ack_backlog = old;
break; break;
case RXRPC_SERVER_LISTENING:
if (backlog == 0) {
rx->sk.sk_state = RXRPC_SERVER_LISTEN_DISABLED;
sk->sk_max_ack_backlog = 0;
rxrpc_discard_prealloc(rx);
ret = 0;
break;
}
default: default:
ret = -EBUSY; ret = -EBUSY;
break; break;
......
...@@ -60,6 +60,7 @@ enum { ...@@ -60,6 +60,7 @@ enum {
RXRPC_CLIENT_BOUND, /* client local address bound */ RXRPC_CLIENT_BOUND, /* client local address bound */
RXRPC_SERVER_BOUND, /* server local address bound */ RXRPC_SERVER_BOUND, /* server local address bound */
RXRPC_SERVER_LISTENING, /* server listening for connections */ RXRPC_SERVER_LISTENING, /* server listening for connections */
RXRPC_SERVER_LISTEN_DISABLED, /* server listening disabled */
RXRPC_CLOSE, /* socket is being closed */ RXRPC_CLOSE, /* socket is being closed */
}; };
......
...@@ -349,7 +349,8 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local, ...@@ -349,7 +349,8 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local,
found_service: found_service:
spin_lock(&rx->incoming_lock); spin_lock(&rx->incoming_lock);
if (rx->sk.sk_state == RXRPC_CLOSE) { if (rx->sk.sk_state == RXRPC_SERVER_LISTEN_DISABLED ||
rx->sk.sk_state == RXRPC_CLOSE) {
trace_rxrpc_abort("CLS", sp->hdr.cid, sp->hdr.callNumber, trace_rxrpc_abort("CLS", sp->hdr.cid, sp->hdr.callNumber,
sp->hdr.seq, RX_INVALID_OPERATION, ESHUTDOWN); sp->hdr.seq, RX_INVALID_OPERATION, ESHUTDOWN);
skb->mark = RXRPC_SKB_MARK_LOCAL_ABORT; skb->mark = RXRPC_SKB_MARK_LOCAL_ABORT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment