[PATCH v3 1/4] nvmet-tcp: unify sockopt with do_sock_setsockopt
Geliang Tang
geliang at kernel.org
Sat Aug 15 17:59:57 PDT 2026
From: Geliang Tang <tanggeliang at kylinos.cn>
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 <tanggeliang at kylinos.cn>
---
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
More information about the Linux-nvme
mailing list