diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 63cd9f939f19965b3b2f049b444b9bbba97528f9..4832de84d52cba73f96466ae4e73ffc2906566bd 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -85,18 +85,14 @@ int afs_open_socket(void) skb_queue_head_init(&afs_incoming_calls); + ret = -ENOMEM; afs_async_calls = create_singlethread_workqueue("kafsd"); - if (!afs_async_calls) { - _leave(" = -ENOMEM [wq]"); - return -ENOMEM; - } + if (!afs_async_calls) + goto error_0; ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET, &socket); - if (ret < 0) { - destroy_workqueue(afs_async_calls); - _leave(" = %d [socket]", ret); - return ret; - } + if (ret < 0) + goto error_1; socket->sk->sk_allocation = GFP_NOFS; @@ -111,18 +107,26 @@ int afs_open_socket(void) sizeof(srx.transport.sin.sin_addr)); ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); - if (ret < 0) { - sock_release(socket); - destroy_workqueue(afs_async_calls); - _leave(" = %d [bind]", ret); - return ret; - } + if (ret < 0) + goto error_2; + + ret = kernel_listen(socket, INT_MAX); + if (ret < 0) + goto error_2; rxrpc_kernel_intercept_rx_messages(socket, afs_rx_interceptor); afs_socket = socket; _leave(" = 0"); return 0; + +error_2: + sock_release(socket); +error_1: + destroy_workqueue(afs_async_calls); +error_0: + _leave(" = %d", ret); + return ret; } /* diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 38512a200db683e643df6f5f185cd0d86405949f..a1bcb0e17250255479995870c2854307d2f10f4b 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -33,8 +33,6 @@ unsigned int rxrpc_debug; // = RXRPC_DEBUG_KPROTO; module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO); MODULE_PARM_DESC(debug, "RxRPC debugging mask"); -static int sysctl_rxrpc_max_qlen __read_mostly = 10; - static struct proto rxrpc_proto; static const struct proto_ops rxrpc_rpc_ops; @@ -191,6 +189,7 @@ static int rxrpc_listen(struct socket *sock, int backlog) { struct sock *sk = sock->sk; struct rxrpc_sock *rx = rxrpc_sk(sk); + unsigned int max; int ret; _enter("%p,%d", rx, backlog); @@ -201,17 +200,21 @@ static int rxrpc_listen(struct socket *sock, int backlog) case RXRPC_UNBOUND: ret = -EADDRNOTAVAIL; break; - case RXRPC_CLIENT_UNBOUND: - case RXRPC_CLIENT_BOUND: - default: - ret = -EBUSY; - break; case RXRPC_SERVER_BOUND: ASSERT(rx->local != NULL); + max = READ_ONCE(rxrpc_max_backlog); + ret = -EINVAL; + if (backlog == INT_MAX) + backlog = max; + else if (backlog < 0 || backlog > max) + break; sk->sk_max_ack_backlog = backlog; rx->sk.sk_state = RXRPC_SERVER_LISTENING; ret = 0; break; + default: + ret = -EBUSY; + break; } release_sock(&rx->sk); @@ -591,7 +594,7 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol, sock_init_data(sock, sk); sk->sk_state = RXRPC_UNBOUND; sk->sk_write_space = rxrpc_write_space; - sk->sk_max_ack_backlog = sysctl_rxrpc_max_qlen; + sk->sk_max_ack_backlog = 0; sk->sk_destruct = rxrpc_sock_destructor; rx = rxrpc_sk(sk); diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index b89dcdcbc65a378ea4c8a160f8f08c461b775efc..f715cca767cd60b1e54aa6613bad8e14e33bef0e 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -641,6 +641,7 @@ extern const struct rxrpc_security rxrpc_no_security; /* * misc.c */ +extern unsigned int rxrpc_max_backlog __read_mostly; extern unsigned int rxrpc_requested_ack_delay; extern unsigned int rxrpc_soft_ack_delay; extern unsigned int rxrpc_idle_ack_delay; diff --git a/net/rxrpc/misc.c b/net/rxrpc/misc.c index 1afe9876e79fa9fb22750bc641e30d658215710d..bdc5e42fe600ef6f112fb15f5f17c4809ddc927f 100644 --- a/net/rxrpc/misc.c +++ b/net/rxrpc/misc.c @@ -14,6 +14,12 @@ #include #include "ar-internal.h" +/* + * The maximum listening backlog queue size that may be set on a socket by + * listen(). + */ +unsigned int rxrpc_max_backlog __read_mostly = 10; + /* * How long to wait before scheduling ACK generation after seeing a * packet with RXRPC_REQUEST_ACK set (in jiffies). diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c index d20ed575acf40909b1c4dc02431a2e05d4d0eb5b..a99690a8a3dad4e41e24295eac09deeb849ad02a 100644 --- a/net/rxrpc/sysctl.c +++ b/net/rxrpc/sysctl.c @@ -18,6 +18,7 @@ static struct ctl_table_header *rxrpc_sysctl_reg_table; static const unsigned int zero = 0; static const unsigned int one = 1; static const unsigned int four = 4; +static const unsigned int thirtytwo = 32; static const unsigned int n_65535 = 65535; static const unsigned int n_max_acks = RXRPC_MAXACKS; @@ -99,6 +100,15 @@ static struct ctl_table rxrpc_sysctl_table[] = { }, /* Non-time values */ + { + .procname = "max_backlog", + .data = &rxrpc_max_backlog, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = (void *)&four, + .extra2 = (void *)&thirtytwo, + }, { .procname = "rx_window_size", .data = &rxrpc_rx_window_size,