All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: nfsv4@linux-nfs.org, nfs@lists.sourceforge.net
Subject: Re: [NFS] [PATCH 4/7] SUNRPC: Use shutdown() instead of close()	when disconnecting a TCP socket
Date: Wed, 07 Nov 2007 18:11:36 -0500	[thread overview]
Message-ID: <47324628.4080306@oracle.com> (raw)
In-Reply-To: <20071107003956.13713.51521.stgit@heimdal.trondhjem.org>

[-- Attachment #1: Type: text/plain, Size: 4139 bytes --]

Trond Myklebust wrote:
> From: Trond Myklebust <Trond.Myklebust@netapp.com>
> 
> By using shutdown() rather than close() we allow the RPC client to wait
> for the TCP close handshake to complete before we start trying to reconnect
> using the same port.
> We use shutdown(SHUT_WR) only instead of shutting down both directions,
> however we wait until the server has closed the connection on its side.

Yeah, that seems like a more friendly and nuanced behavior, and is 
probably one of the more important features of this set of changes.

> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
> ---
> 
>  net/sunrpc/xprtsock.c |   53 +++++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 46 insertions(+), 7 deletions(-)
> 
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 99c0166..d610d28 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -614,6 +614,34 @@ static int xs_udp_send_request(struct rpc_task *task)
>  	return status;
>  }
>  
> +static int xs_shutdown(struct socket *sock, int how)
> +{
> +	/*
> +	 * Note: 'how - 1' trick converts
> +	 *        RCV_SHUTDOWN -> SHUT_RD = 0
> +	 *        SEND_SHUTDOWN -> SHUT_WR = 1
> +	 *        RCV_SHUTDOWN|SEND_SHUTDOWN -> SHUT_RDWR = 2
> +	 */
> +	return sock->ops->shutdown(sock, how - 1);
> +}
> +
> +/**
> + * xs_tcp_shutdown - gracefully shut down a TCP socket
> + * @xprt: transport
> + *
> + * Initiates a graceful shutdown of the TCP socket by calling the
> + * equivalent of shutdown(SHUT_WR);
> + */
> +static void xs_tcp_shutdown(struct rpc_xprt *xprt)
> +{
> +	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
> +	struct socket *sock = transport->sock;
> +
> +	if (sock != NULL)
> +		xs_shutdown(sock, SEND_SHUTDOWN);

I'm not sure why simply

		sock->ops->shutdown(sock, SHUT_WR);

isn't adequate here.

> +	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
> +}
> +
>  static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf)
>  {
>  	u32 reclen = buf->len - sizeof(rpc_fraghdr);
> @@ -691,7 +719,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
>  	default:
>  		dprintk("RPC:       sendmsg returned unrecognized error %d\n",
>  			-status);
> -		xprt_disconnect(xprt);
> +		xs_tcp_shutdown(xprt);

Hrm.  I would have thought this case was handled adequately by 
xprt_release_write?

>  		break;
>  	}
>  
> @@ -1627,8 +1655,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
>  				break;
>  			default:
>  				/* get rid of existing socket, and retry */
> -				xs_close(xprt);
> -				break;
> +				xs_tcp_shutdown(xprt);
>  		}
>  	}
>  out:
> @@ -1687,8 +1714,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
>  				break;
>  			default:
>  				/* get rid of existing socket, and retry */
> -				xs_close(xprt);
> -				break;
> +				xs_tcp_shutdown(xprt);
>  		}
>  	}
>  out:
> @@ -1735,6 +1761,19 @@ static void xs_connect(struct rpc_task *task)
>  	}
>  }
>  
> +static void xs_tcp_connect(struct rpc_task *task)
> +{
> +	struct rpc_xprt *xprt = task->tk_xprt;
> +
> +	/* Initiate graceful shutdown of the socket if not already done */
> +	if (!test_bit(XPRT_CONNECTING, &xprt->state))
> +		xs_tcp_shutdown(xprt);
> +	/* Exit if we need to wait for socket shutdown to complete */
> +	if (test_bit(XPRT_CLOSING, &xprt->state))
> +		return;
> +	xs_connect(task);
> +}
> +
>  /**
>   * xs_udp_print_stats - display UDP socket-specifc stats
>   * @xprt: rpc_xprt struct containing statistics

Adding xs_tcp_connect will allow a lot more clean up in xs_connect, 
especially simplifying UDP transport connects.

> @@ -1805,12 +1844,12 @@ static struct rpc_xprt_ops xs_tcp_ops = {
>  	.release_xprt		= xs_tcp_release_xprt,
>  	.rpcbind		= rpcb_getport_async,
>  	.set_port		= xs_set_port,
> -	.connect		= xs_connect,
> +	.connect		= xs_tcp_connect,
>  	.buf_alloc		= rpc_malloc,
>  	.buf_free		= rpc_free,
>  	.send_request		= xs_tcp_send_request,
>  	.set_retrans_timeout	= xprt_set_retrans_timeout_def,
> -	.close			= xs_close,
> +	.close			= xs_tcp_shutdown,
>  	.destroy		= xs_destroy,
>  	.print_stats		= xs_tcp_print_stats,
>  };

[-- Attachment #2: chuck.lever.vcf --]
[-- Type: text/x-vcard, Size: 259 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Chuck
org:Oracle Corporation;Corporate Architecture: Linux Projects Group
adr:;;1015 Granger Avenue;Ann Arbor;MI;48104;USA
title:Principal Member of Staff
tel;work:+1 248 614 5091
x-mozilla-html:FALSE
version:2.1
end:vcard


[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
NFSv4 mailing list
NFSv4@linux-nfs.org
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4

  reply	other threads:[~2007-11-07 23:11 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-07  0:39 [PATCH 0/7] Improve the NFS/TCP reconnection code Trond Myklebust
2007-11-07  0:39 ` [PATCH 1/7] SUNRPC: Fix a race in xs_tcp_state_change() Trond Myklebust
2007-11-07 22:21   ` Chuck Lever
2007-11-07 22:32     ` [NFS] " Trond Myklebust
2007-11-07 23:47       ` setclientid: string in use on NFS v4 share on Debian Etch & hosts file "solution" Matt Weatherford
2007-11-09 19:55         ` J. Bruce Fields
2007-11-08 15:40       ` [NFS] [PATCH 1/7] SUNRPC: Fix a race in xs_tcp_state_change() Chuck Lever
2007-11-08 16:12         ` Trond Myklebust
2007-11-07  0:39 ` [PATCH 2/7] SUNRPC: Fix TCP rebinding logic Trond Myklebust
2007-11-07 22:48   ` Chuck Lever
2007-11-07 23:08     ` Trond Myklebust
2007-11-07 23:28       ` [NFS] " Chuck Lever
2007-11-07 23:47         ` Trond Myklebust
2007-11-09 13:35   ` Talpey, Thomas
2007-11-07  0:39 ` [PATCH 3/7] SUNRPC: Allow the client to detect if the TCP connection is closed Trond Myklebust
2007-11-09 14:04   ` Talpey, Thomas
2007-11-09 14:33     ` [NFS] " Trond Myklebust
2007-11-09 14:35       ` Talpey, Thomas
2007-11-09 14:48         ` Trond Myklebust
2007-11-09 15:25           ` Talpey, Thomas
2007-11-09 15:32             ` [NFS] " Trond Myklebust
2007-11-09 16:53               ` Talpey, Thomas
2007-11-09 17:37                 ` Trond Myklebust
2007-11-09 17:52                   ` [NFS] " Talpey, Thomas
2007-11-09 18:21                     ` Trond Myklebust
2007-11-07  0:39 ` [PATCH 4/7] SUNRPC: Use shutdown() instead of close() when disconnecting a TCP socket Trond Myklebust
2007-11-07 23:11   ` Chuck Lever [this message]
2007-11-07 23:59     ` [NFS] " Trond Myklebust
2007-11-09 13:38   ` Talpey, Thomas
2007-11-09 13:51     ` [NFS] " Trond Myklebust
2007-11-07  0:40 ` [PATCH 5/7] SUNRPC: xprt_autoclose() should not call xprt_disconnect() Trond Myklebust
2007-11-09 13:56   ` [NFS] " Talpey, Thomas
2007-11-07  0:40 ` [PATCH 6/7] SUNRPC: Make call_status()/call_decode() call xprt_force_disconnect() Trond Myklebust
2007-11-07 23:15   ` [NFS] " Chuck Lever
2007-11-07  0:40 ` [PATCH 7/7] SUNRPC: Rename xprt_disconnect() Trond Myklebust
2007-11-07 23:16   ` [NFS] " Chuck Lever
2007-11-08  0:01     ` Trond Myklebust

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47324628.4080306@oracle.com \
    --to=chuck.lever@oracle.com \
    --cc=Trond.Myklebust@netapp.com \
    --cc=nfs@lists.sourceforge.net \
    --cc=nfsv4@linux-nfs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.