SUNRPC: Enable the keepalive option for TCP sockets
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 24 Sep 2013 15:25:22 +0000 (11:25 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 1 Oct 2013 22:22:10 +0000 (18:22 -0400)
For NFSv4 we want to avoid retransmitting RPC calls unless the TCP
connection breaks. However we still want to detect TCP connection
breakage as soon as possible. Do this by setting the keepalive option
with the idle timeout and count set to the 'timeo' and 'retrans' mount
options.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/xprtsock.c

index ee03d35677d962a3385d8d01a31968b70fa77b56..208a7634b916a967de5c8e1512a28285d680f20d 100644 (file)
@@ -2112,6 +2112,19 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
 
        if (!transport->inet) {
                struct sock *sk = sock->sk;
+               unsigned int keepidle = xprt->timeout->to_initval / HZ;
+               unsigned int keepcnt = xprt->timeout->to_retries + 1;
+               unsigned int opt_on = 1;
+
+               /* TCP Keepalive options */
+               kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+                               (char *)&opt_on, sizeof(opt_on));
+               kernel_setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,
+                               (char *)&keepidle, sizeof(keepidle));
+               kernel_setsockopt(sock, SOL_TCP, TCP_KEEPINTVL,
+                               (char *)&keepidle, sizeof(keepidle));
+               kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT,
+                               (char *)&keepcnt, sizeof(keepcnt));
 
                write_lock_bh(&sk->sk_callback_lock);