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
next prev parent 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.