Linux NFS development
 help / color / mirror / Atom feed
From: Trond Myklebust <trond.myklebust@fys.uio.no>
To: Chuck Lever <chucklever@gmail.com>
Cc: nfs@lists.sourceforge.net
Subject: Re: [PATCH 02/25] SUNRPC: Create a helper to tell whether a	transport is bound
Date: Wed, 09 Aug 2006 11:19:52 -0400	[thread overview]
Message-ID: <1155136792.5731.84.camel@localhost> (raw)
In-Reply-To: <20060809145853.3914.64708.stgit@picasso.dsl.sfldmi.ameritech.net>

On Wed, 2006-08-09 at 10:58 -0400, Chuck Lever wrote:
> Hide the contents and format of xprt->addr by eliminating direct uses
> of the xprt->addr.sin_port field.  This change is required to support
> alternate RPC host address formats (eg IPv6).
> 
> Test-plan:
> Destructive testing (unplugging the network temporarily).  Repeated runs of
> Connectathon locking suite with UDP and TCP.
> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  include/linux/sunrpc/xprt.h |   16 ++++++++++++++++
>  net/sunrpc/clnt.c           |   10 +++++-----
>  net/sunrpc/xprt.c           |    6 +++++-
>  net/sunrpc/xprtsock.c       |   16 ++++++++++++----
>  4 files changed, 38 insertions(+), 10 deletions(-)
> 
> diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
> index 3a0cca2..e65474f 100644
> --- a/include/linux/sunrpc/xprt.h
> +++ b/include/linux/sunrpc/xprt.h
> @@ -269,6 +269,7 @@ #define XPRT_LOCKED		(0)
>  #define XPRT_CONNECTED		(1)
>  #define XPRT_CONNECTING		(2)
>  #define XPRT_CLOSE_WAIT		(3)
> +#define XPRT_BOUND		(4)
>  
>  static inline void xprt_set_connected(struct rpc_xprt *xprt)
>  {
> @@ -312,6 +313,21 @@ static inline int xprt_test_and_set_conn
>  	return test_and_set_bit(XPRT_CONNECTING, &xprt->state);
>  }
>  
> +static inline void xprt_set_bound(struct rpc_xprt *xprt)
> +{
> +	set_bit(XPRT_BOUND, &xprt->state);
> +}
> +
> +static inline int xprt_bound(struct rpc_xprt *xprt)
> +{
> +	return test_bit(XPRT_BOUND, &xprt->state);
> +}
> +
> +static inline void xprt_clear_bound(struct rpc_xprt *xprt)
> +{
> +	clear_bit(XPRT_BOUND, &xprt->state);
> +}
> +
>  #endif /* __KERNEL__*/
>  
>  #endif /* _LINUX_SUNRPC_XPRT_H */
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index d6409e7..4f353dd 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -148,7 +148,6 @@ rpc_new_client(struct rpc_xprt *xprt, ch
>  	clnt->cl_maxproc  = version->nrprocs;
>  	clnt->cl_protname = program->name;
>  	clnt->cl_pmap	  = &clnt->cl_pmap_default;
> -	clnt->cl_port     = xprt->addr.sin_port;
>  	clnt->cl_prog     = program->number;
>  	clnt->cl_vers     = version->number;
>  	clnt->cl_prot     = xprt->prot;
> @@ -156,7 +155,7 @@ rpc_new_client(struct rpc_xprt *xprt, ch
>  	clnt->cl_metrics  = rpc_alloc_iostats(clnt);
>  	rpc_init_wait_queue(&clnt->cl_pmap_default.pm_bindwait, "bindwait");
>  
> -	if (!clnt->cl_port)
> +	if (!xprt_bound(clnt->cl_xprt))
>  		clnt->cl_autobind = 1;
>  
>  	clnt->cl_rtt = &clnt->cl_rtt_default;
> @@ -573,7 +572,7 @@ EXPORT_SYMBOL(rpc_max_payload);
>  void rpc_force_rebind(struct rpc_clnt *clnt)
>  {
>  	if (clnt->cl_autobind)
> -		clnt->cl_port = 0;
> +		xprt_clear_bound(clnt->cl_xprt);
>  }
>  EXPORT_SYMBOL(rpc_force_rebind);
>  
> @@ -785,14 +784,15 @@ static void
>  call_bind(struct rpc_task *task)
>  {
>  	struct rpc_clnt	*clnt = task->tk_client;
> +	struct rpc_xprt *xprt = task->tk_xprt;
>  
>  	dprintk("RPC: %4d call_bind (status %d)\n",
>  				task->tk_pid, task->tk_status);
>  
>  	task->tk_action = call_connect;
> -	if (!clnt->cl_port) {
> +	if (!xprt_bound(xprt)) {
>  		task->tk_action = call_bind_status;
> -		task->tk_timeout = task->tk_xprt->bind_timeout;
> +		task->tk_timeout = xprt->bind_timeout;
>  		rpc_getport(task, clnt);
>  	}
>  }
> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> index e8c2bc4..10ba1f6 100644
> --- a/net/sunrpc/xprt.c
> +++ b/net/sunrpc/xprt.c
> @@ -534,7 +534,11 @@ void xprt_connect(struct rpc_task *task)
>  	dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid,
>  			xprt, (xprt_connected(xprt) ? "is" : "is not"));
>  
> -	if (!xprt->addr.sin_port) {
> +	if (xprt->shutdown) {
> +		task->tk_status = -EIO;
> +		return;
> +	}

Why are you reinstating the test for xprt->shutdown? It was removed
because it is pretty much useless there. Any task should already have
been signalled to exit by rpc_shutdown_client()...

> +	if (!xprt_bound(xprt)) {
>  		task->tk_status = -EIO;
>  		return;
>  	}
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index 441bd53..43b59c2 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -974,6 +974,8 @@ static void xs_set_port(struct rpc_xprt 
>  {
>  	dprintk("RPC:      setting port for xprt %p to %u\n", xprt, port);
>  	xprt->addr.sin_port = htons(port);
> +	if (port != 0)
> +		xprt_set_bound(xprt);

Hmm... This looks odd. If port == 0, why not exit immediately?

Furthermore, what if the port is already bound: is it correct to set it
again? IOW: should it be conditional on test_and_set_bit()?

Cheers,
  Trond

>  }
>  
>  static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
> @@ -1016,7 +1018,7 @@ static void xs_udp_connect_worker(void *
>  	struct socket *sock = xprt->sock;
>  	int err, status = -EIO;
>  
> -	if (xprt->shutdown || xprt->addr.sin_port == 0)
> +	if (xprt->shutdown || !xprt_bound(xprt))
>  		goto out;
>  
>  	dprintk("RPC:      xs_udp_connect_worker for xprt %p\n", xprt);
> @@ -1099,7 +1101,7 @@ static void xs_tcp_connect_worker(void *
>  	struct socket *sock = xprt->sock;
>  	int err, status = -EIO;
>  
> -	if (xprt->shutdown || xprt->addr.sin_port == 0)
> +	if (xprt->shutdown || !xprt_bound(xprt))
>  		goto out;
>  
>  	dprintk("RPC:      xs_tcp_connect_worker for xprt %p\n", xprt);
> @@ -1307,8 +1309,11 @@ int xs_setup_udp(struct rpc_xprt *xprt, 
>  	if (xprt->slot == NULL)
>  		return -ENOMEM;
>  
> -	xprt->prot = IPPROTO_UDP;
> +	if (ntohs(xprt->addr.sin_port) != 0)
> +		xprt_set_bound(xprt);
>  	xprt->port = xs_get_random_port();
> +
> +	xprt->prot = IPPROTO_UDP;
>  	xprt->tsh_size = 0;
>  	xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
>  	/* XXX: header size can vary due to auth type, IPv6, etc. */
> @@ -1348,8 +1353,11 @@ int xs_setup_tcp(struct rpc_xprt *xprt, 
>  	if (xprt->slot == NULL)
>  		return -ENOMEM;
>  
> -	xprt->prot = IPPROTO_TCP;
> +	if (ntohs(xprt->addr.sin_port) != 0)
> +		xprt_set_bound(xprt);
>  	xprt->port = xs_get_random_port();
> +
> +	xprt->prot = IPPROTO_TCP;
>  	xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
>  	xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0;
>  	xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

  reply	other threads:[~2006-08-09 15:20 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-09 14:47 [PATCH 00/25] RPC client transport switch, continued Chuck Lever
2006-08-09 14:58 ` [PATCH 01/25] SUNRPC: avoid choosing an IPMI port for RPC traffic Chuck Lever
2006-08-09 15:04   ` Christoph Hellwig
2006-08-09 14:58 ` [PATCH 02/25] SUNRPC: Create a helper to tell whether a transport is bound Chuck Lever
2006-08-09 15:19   ` Trond Myklebust [this message]
2006-08-09 15:27     ` Chuck Lever
2006-08-09 15:37       ` Trond Myklebust
2006-08-09 14:58 ` [PATCH 03/25] SUNRPC: Make RPC portmapper use per-transport storage Chuck Lever
2006-08-09 14:58 ` [PATCH 04/25] SUNRPC: Clean-up after recent changes to sunrpc/pmap_clnt.c Chuck Lever
2006-08-09 14:59 ` [PATCH 05/25] SUNRPC: Support for RPC child tasks no longer needed Chuck Lever
2006-08-09 14:59 ` [PATCH 06/25] SUNRPC: Introduce transport switch callout for pluggable rpcbind Chuck Lever
2006-08-09 14:59 ` [PATCH 07/25] SUNRPC: create API for getting remote peer address Chuck Lever
2006-08-09 15:06   ` Christoph Hellwig
2006-08-09 14:59 ` [PATCH 08/25] LOCKD: Teach lockd to use the new rpc_peeraddr() API Chuck Lever
2006-08-09 14:59 ` [PATCH 09/25] SUNRPC: Teach the RPC portmapper " Chuck Lever
2006-08-09 14:59 ` [PATCH 10/25] SUNRPC: remove extraneous header inclusions Chuck Lever
2006-08-09 14:59 ` [PATCH 11/25] SUNRPC: add xprt switch API for printing formatted remote peer addresses Chuck Lever
2006-08-09 14:59 ` [PATCH 12/25] SUNRPC: Create API for displaying remote peer address Chuck Lever
2006-08-09 14:59 ` [PATCH 13/25] SUNRPC: Teach rpc_pipe.c to use new rpc_peeraddr() API Chuck Lever
2006-08-09 14:59 ` [PATCH 14/25] SUNRPC: Use "sockaddr_storage" for storing RPC client's remote peer address Chuck Lever
2006-08-09 14:59 ` [PATCH 15/25] SUNRPC: Clean-up after previous patches Chuck Lever
2006-08-09 14:59 ` [PATCH 16/25] SUNRPC: use sockaddr + size when creating remote transport endpoints Chuck Lever
2006-08-09 14:59 ` [PATCH 17/25] LOCKD: Convert to use new rpc_create() API Chuck Lever
2006-08-09 14:59 ` [PATCH 18/25] NFS: Convert NFS client " Chuck Lever
2006-08-09 15:30   ` Trond Myklebust
2006-08-09 14:59 ` [PATCH 19/25] NFSD: Convert NFS server callback logic to use new rpc_create API Chuck Lever
2006-08-09 14:59 ` [PATCH 20/25] SUNRPC: Convert RPC portmapper to use new rpc_create() API Chuck Lever
2006-08-09 14:59 ` [PATCH 21/25] SUNRPC: Eliminate xprt_create_proto and rpc_create_client Chuck Lever
2006-08-09 14:59 ` [PATCH 22/25] NFS: remove a no-longer-needed error check in nfs_symlink() Chuck Lever
2006-08-10  2:10   ` Greg Banks
2006-08-10 12:36     ` Peter Staubach
2006-08-09 14:59 ` [PATCH 23/25] NFS: Fix double d_drop in nfs_instantiate() error path Chuck Lever
2006-08-09 15:34   ` Trond Myklebust
2006-08-09 14:59 ` [PATCH 24/25] NFS: copy symlinks into page cache before sending NFS SYMLINK request Chuck Lever
2006-08-09 14:59 ` [PATCH 25/25] NFS: Use cached page as buffer for NFS symlink requests Chuck Lever

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=1155136792.5731.84.camel@localhost \
    --to=trond.myklebust@fys.uio.no \
    --cc=chucklever@gmail.com \
    --cc=nfs@lists.sourceforge.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox