From: Geliang Tang This patch consolidates socket option settings in nvmet-tcp by utilizing the generic do_sock_setsockopt() helper for options including SO_LINGER, SO_PRIORITY, SO_REUSEADDR, TCP_NODELAY, and IP_TOS. This change eliminates the need to export and use specialized helpers for each individual socket option. A key benefit of this refactoring is that it decouples the socket option configuration from the underlying transport protocol. This makes it easier to extend nvmet-tcp to support other protocols, such as MPTCP, in the future, as do_sock_setsockopt() abstracts away protocol-specific differences without requiring per-option protocol-specific wrappers. Signed-off-by: Geliang Tang --- drivers/nvme/target/tcp.c | 53 +++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 75a276d73be3..e64592b79257 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1696,10 +1696,48 @@ static void nvmet_tcp_state_change(struct sock *sk) read_unlock_bh(&sk->sk_callback_lock); } +static void nvmet_tcp_sock_no_linger(struct sock *sk) +{ + struct linger ling = { .l_onoff = 1, .l_linger = 0 }; + + do_sock_setsockopt(sk->sk_socket, false, SOL_SOCKET, SO_LINGER, + KERNEL_SOCKPTR(&ling), sizeof(ling)); +} + +static void nvmet_tcp_sock_set_priority(struct sock *sk, u32 priority) +{ + do_sock_setsockopt(sk->sk_socket, false, SOL_SOCKET, SO_PRIORITY, + KERNEL_SOCKPTR(&priority), sizeof(priority)); +} + +static void nvmet_tcp_sock_set_reuseaddr(struct sock *sk) +{ + int val = SK_CAN_REUSE; + + do_sock_setsockopt(sk->sk_socket, false, SOL_SOCKET, SO_REUSEADDR, + KERNEL_SOCKPTR(&val), sizeof(val)); +} + +static void nvmet_tcp_sock_set_nodelay(struct sock *sk) +{ + int val = 1; + + do_sock_setsockopt(sk->sk_socket, false, SOL_TCP, TCP_NODELAY, + KERNEL_SOCKPTR(&val), sizeof(val)); +} + +static void nvmet_tcp_sock_set_tos(struct sock *sk) +{ + u8 tos = inet_sk(sk)->rcv_tos; + + if (tos > 0) + do_sock_setsockopt(sk->sk_socket, false, SOL_IP, IP_TOS, + KERNEL_SOCKPTR(&tos), sizeof(tos)); +} + static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue) { struct socket *sock = queue->sock; - struct inet_sock *inet = inet_sk(sock->sk); int ret; ret = kernel_getsockname(sock, @@ -1717,14 +1755,13 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue) * close. This is done to prevent stale data from being sent should * the network connection be restored before TCP times out. */ - sock_no_linger(sock->sk); + nvmet_tcp_sock_no_linger(sock->sk); if (so_priority > 0) - sock_set_priority(sock->sk, so_priority); + nvmet_tcp_sock_set_priority(sock->sk, so_priority); /* Set socket type of service */ - if (inet->rcv_tos > 0) - ip_sock_set_tos(sock->sk, inet->rcv_tos); + nvmet_tcp_sock_set_tos(sock->sk); ret = 0; write_lock_bh(&sock->sk->sk_callback_lock); @@ -2098,10 +2135,10 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport) port->sock->sk->sk_user_data = port; port->data_ready = port->sock->sk->sk_data_ready; port->sock->sk->sk_data_ready = nvmet_tcp_listen_data_ready; - sock_set_reuseaddr(port->sock->sk); - tcp_sock_set_nodelay(port->sock->sk); + nvmet_tcp_sock_set_reuseaddr(port->sock->sk); + nvmet_tcp_sock_set_nodelay(port->sock->sk); if (so_priority > 0) - sock_set_priority(port->sock->sk, so_priority); + nvmet_tcp_sock_set_priority(port->sock->sk, so_priority); ret = kernel_bind(port->sock, (struct sockaddr_unsized *)&port->addr, sizeof(port->addr)); -- 2.53.0