Commit c433594c authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller
Browse files

net: add sock_no_linger



Add a helper to directly set the SO_LINGER sockopt from kernel space
with onoff set to true and a linger time of 0 without going through a
fake uaccess.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b58f0e8f
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -1313,7 +1313,6 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
{
	struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
	struct nvme_tcp_queue *queue = &ctrl->queues[qid];
	struct linger sol = { .l_onoff = 1, .l_linger = 0 };
	int ret, opt, rcv_pdu_size;

	queue->ctrl = ctrl;
@@ -1361,13 +1360,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
	 * close. This is done to prevent stale data from being sent should
	 * the network connection be restored before TCP times out.
	 */
	ret = kernel_setsockopt(queue->sock, SOL_SOCKET, SO_LINGER,
			(char *)&sol, sizeof(sol));
	if (ret) {
		dev_err(nctrl->device,
			"failed to set SO_LINGER sock opt %d\n", ret);
		goto err_sock;
	}
	sock_no_linger(queue->sock->sk);

	if (so_priority > 0) {
		ret = kernel_setsockopt(queue->sock, SOL_SOCKET, SO_PRIORITY,
+1 −5
Original line number Diff line number Diff line
@@ -1429,7 +1429,6 @@ 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);
	struct linger sol = { .l_onoff = 1, .l_linger = 0 };
	int ret;

	ret = kernel_getsockname(sock,
@@ -1447,10 +1446,7 @@ 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.
	 */
	ret = kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
			(char *)&sol, sizeof(sol));
	if (ret)
		return ret;
	sock_no_linger(sock->sk);

	if (so_priority > 0) {
		ret = kernel_setsockopt(sock, SOL_SOCKET, SO_PRIORITY,
+1 −0
Original line number Diff line number Diff line
@@ -2688,6 +2688,7 @@ static inline bool sk_dev_equal_l3scope(struct sock *sk, int dif)

void sock_def_readable(struct sock *sk);

void sock_no_linger(struct sock *sk);
void sock_set_reuseaddr(struct sock *sk);

#endif	/* _SOCK_H */
+9 −0
Original line number Diff line number Diff line
@@ -720,6 +720,15 @@ void sock_set_reuseaddr(struct sock *sk)
}
EXPORT_SYMBOL(sock_set_reuseaddr);

void sock_no_linger(struct sock *sk)
{
	lock_sock(sk);
	sk->sk_lingertime = 0;
	sock_set_flag(sk, SOCK_LINGER);
	release_sock(sk);
}
EXPORT_SYMBOL(sock_no_linger);

/*
 *	This is meant for all protocols to use and covers goings on
 *	at the socket level. Everything here is generic.
+0 −1
Original line number Diff line number Diff line
@@ -73,7 +73,6 @@ void rds_tcp_listen_data_ready(struct sock *sk);
int rds_tcp_accept_one(struct socket *sock);
int rds_tcp_keepalive(struct socket *sock);
void *rds_tcp_listen_sock_def_readable(struct net *net);
void rds_tcp_set_linger(struct socket *sock);

/* tcp_recv.c */
int rds_tcp_recv_init(void);
Loading