Linux NFS development
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Tom Tucker <tom@opengridcomputing.com>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [RFC,PATCH 12/38] svc: Add a generic transport svc_create_xprt function
Date: Fri, 14 Dec 2007 18:05:23 -0500	[thread overview]
Message-ID: <20071214230523.GI23121@fieldses.org> (raw)
In-Reply-To: <20071129225603.15275.54556.stgit-gUwIgmpLGaKNDNWfRnPdfg@public.gmane.org>

On Thu, Nov 29, 2007 at 04:56:03PM -0600, Tom Tucker wrote:
> 
> The svc_create_xprt function is a transport independent version
> of the svc_makesock function. 
> 
> Since transport instance creation contains transport dependent and 
> independent components, add an xpo_create transport function. The 
> transport implementation of this function allocates the memory for the 
> endpoint, implements the transport dependent initialization logic, and
> calls svc_xprt_init to initialize the transport independent field (svc_xprt) 
> in it's data structure.
> 
> Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
> ---
> 
>  include/linux/sunrpc/svc_xprt.h |    4 +++
>  net/sunrpc/svc_xprt.c           |   37 ++++++++++++++++++++++++++
>  net/sunrpc/svcsock.c            |   56 +++++++++++++++++++++++++++++----------
>  3 files changed, 82 insertions(+), 15 deletions(-)
> 
> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
> index 1527ff1..3f4a1df 100644
> --- a/include/linux/sunrpc/svc_xprt.h
> +++ b/include/linux/sunrpc/svc_xprt.h
> @@ -10,6 +10,9 @@
>  #include <linux/sunrpc/svc.h>
>  
>  struct svc_xprt_ops {
> +	struct svc_xprt	*(*xpo_create)(struct svc_serv *,
> +				       struct sockaddr *, int,
> +				       int);
>  	struct svc_xprt	*(*xpo_accept)(struct svc_xprt *);
>  	int		(*xpo_has_wspace)(struct svc_xprt *);
>  	int		(*xpo_recvfrom)(struct svc_rqst *);
> @@ -36,5 +39,6 @@ struct svc_xprt {
>  int	svc_reg_xprt_class(struct svc_xprt_class *);
>  int	svc_unreg_xprt_class(struct svc_xprt_class *);
>  void	svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *);
> +int	svc_create_xprt(struct svc_serv *, char *, unsigned short, int);
>  
>  #endif /* SUNRPC_SVC_XPRT_H */
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index 92ea85b..9136da4 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -93,3 +93,40 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt)
>  	xprt->xpt_ops = xcl->xcl_ops;
>  }
>  EXPORT_SYMBOL_GPL(svc_xprt_init);
> +
> +int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
> +		    int flags)
> +{
> +	struct svc_xprt_class *xcl;
> +	int ret = -ENOENT;
> +	struct sockaddr_in sin = {
> +		.sin_family		= AF_INET,
> +		.sin_addr.s_addr	= INADDR_ANY,
> +		.sin_port		= htons(port),
> +	};
> +	dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
> +	spin_lock(&svc_xprt_class_lock);
> +	list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
> +		if (strcmp(xprt_name, xcl->xcl_name) == 0) {
> +			spin_unlock(&svc_xprt_class_lock);
> +			if (try_module_get(xcl->xcl_owner)) {


Hm.  I wonder if this is right.  Don't you need to do the try_module_get
while still under the svc_xprt_class_lock?

--b.

> +				struct svc_xprt *newxprt;
> +				ret = 0;
> +				newxprt = xcl->xcl_ops->xpo_create
> +					(serv,
> +					 (struct sockaddr *)&sin, sizeof(sin),
> +					 flags);
> +				if (IS_ERR(newxprt)) {
> +					module_put(xcl->xcl_owner);
> +					ret = PTR_ERR(newxprt);
> +				}
> +			}
> +			goto out;
> +		}
> +	}
> +	spin_unlock(&svc_xprt_class_lock);
> +	dprintk("svc: transport %s not found\n", xprt_name);
> + out:
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(svc_create_xprt);
> diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
> index 661162b..0bfffbc 100644
> --- a/net/sunrpc/svcsock.c
> +++ b/net/sunrpc/svcsock.c
> @@ -91,6 +91,8 @@ static void		svc_sock_free(struct svc_xprt *);
>  static struct svc_deferred_req *svc_deferred_dequeue(struct svc_sock *svsk);
>  static int svc_deferred_recv(struct svc_rqst *rqstp);
>  static struct cache_deferred_req *svc_defer(struct cache_req *req);
> +static struct svc_xprt *
> +svc_create_socket(struct svc_serv *, int, struct sockaddr *, int, int);
>  
>  /* apparently the "standard" is that clients close
>   * idle connections after 5 minutes, servers after
> @@ -381,6 +383,7 @@ svc_sock_put(struct svc_sock *svsk)
>  {
>  	if (atomic_dec_and_test(&svsk->sk_inuse)) {
>  		BUG_ON(!test_bit(SK_DEAD, &svsk->sk_flags));
> +		module_put(svsk->sk_xprt.xpt_class->xcl_owner);
>  		svsk->sk_xprt.xpt_ops->xpo_free(&svsk->sk_xprt);
>  	}
>  }
> @@ -918,7 +921,14 @@ static struct svc_xprt *svc_udp_accept(struct svc_xprt *xprt)
>  	return NULL;
>  }
>  
> +static struct svc_xprt *
> +svc_udp_create(struct svc_serv *serv, struct sockaddr *sa, int salen, int flags)
> +{
> +	return svc_create_socket(serv, IPPROTO_UDP, sa, salen, flags);
> +}
> +
>  static struct svc_xprt_ops svc_udp_ops = {
> +	.xpo_create = svc_udp_create,
>  	.xpo_recvfrom = svc_udp_recvfrom,
>  	.xpo_sendto = svc_udp_sendto,
>  	.xpo_release_rqst = svc_release_skb,
> @@ -931,6 +941,7 @@ static struct svc_xprt_ops svc_udp_ops = {
>  
>  static struct svc_xprt_class svc_udp_class = {
>  	.xcl_name = "udp",
> +	.xcl_owner = THIS_MODULE,
>  	.xcl_ops = &svc_udp_ops,
>  	.xcl_max_payload = RPCSVC_MAXPAYLOAD_UDP,
>  };
> @@ -1351,7 +1362,14 @@ static int svc_tcp_has_wspace(struct svc_xprt *xprt)
>  	return 1;
>  }
>  
> +static struct svc_xprt *
> +svc_tcp_create(struct svc_serv *serv, struct sockaddr *sa, int salen, int flags)
> +{
> +	return svc_create_socket(serv, IPPROTO_TCP, sa, salen, flags);
> +}
> +
>  static struct svc_xprt_ops svc_tcp_ops = {
> +	.xpo_create = svc_tcp_create,
>  	.xpo_recvfrom = svc_tcp_recvfrom,
>  	.xpo_sendto = svc_tcp_sendto,
>  	.xpo_release_rqst = svc_release_skb,
> @@ -1364,6 +1382,7 @@ static struct svc_xprt_ops svc_tcp_ops = {
>  
>  static struct svc_xprt_class svc_tcp_class = {
>  	.xcl_name = "tcp",
> +	.xcl_owner = THIS_MODULE,
>  	.xcl_ops = &svc_tcp_ops,
>  	.xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
>  };
> @@ -1589,8 +1608,14 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
>  	} else if (test_bit(SK_LISTENER, &svsk->sk_flags)) {
>  		struct svc_xprt *newxpt;
>  		newxpt = svsk->sk_xprt.xpt_ops->xpo_accept(&svsk->sk_xprt);
> -		if (newxpt)
> +		if (newxpt) {
> +			/*
> +			 * We know this module_get will succeed because the
> +			 * listener holds a reference too
> +			 */
> +			__module_get(newxpt->xpt_class->xcl_owner);
>  			svc_check_conn_limits(svsk->sk_server);
> +		}
>  		svc_sock_received(svsk);
>  	} else {
>  		dprintk("svc: server %p, pool %u, socket %p, inuse=%d\n",
> @@ -1830,8 +1855,9 @@ EXPORT_SYMBOL_GPL(svc_addsock);
>  /*
>   * Create socket for RPC service.
>   */
> -static int svc_create_socket(struct svc_serv *serv, int protocol,
> -				struct sockaddr *sin, int len, int flags)
> +static struct svc_xprt *
> +svc_create_socket(struct svc_serv *serv, int protocol,
> +		  struct sockaddr *sin, int len, int flags)
>  {
>  	struct svc_sock	*svsk;
>  	struct socket	*sock;
> @@ -1846,13 +1872,13 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,
>  	if (protocol != IPPROTO_UDP && protocol != IPPROTO_TCP) {
>  		printk(KERN_WARNING "svc: only UDP and TCP "
>  				"sockets supported\n");
> -		return -EINVAL;
> +		return ERR_PTR(-EINVAL);
>  	}
>  	type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
>  
>  	error = sock_create_kern(sin->sa_family, type, protocol, &sock);
>  	if (error < 0)
> -		return error;
> +		return ERR_PTR(error);
>  
>  	svc_reclassify_socket(sock);
>  
> @@ -1869,13 +1895,13 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,
>  
>  	if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) {
>  		svc_sock_received(svsk);
> -		return ntohs(inet_sk(svsk->sk_sk)->sport);
> +		return (struct svc_xprt *)svsk;
>  	}
>  
>  bummer:
>  	dprintk("svc: svc_create_socket error = %d\n", -error);
>  	sock_release(sock);
> -	return error;
> +	return ERR_PTR(error);
>  }
>  
>  /*
> @@ -1986,15 +2012,15 @@ void svc_force_close_socket(struct svc_sock *svsk)
>  int svc_makesock(struct svc_serv *serv, int protocol, unsigned short port,
>  			int flags)
>  {
> -	struct sockaddr_in sin = {
> -		.sin_family		= AF_INET,
> -		.sin_addr.s_addr	= INADDR_ANY,
> -		.sin_port		= htons(port),
> -	};
> -
>  	dprintk("svc: creating socket proto = %d\n", protocol);
> -	return svc_create_socket(serv, protocol, (struct sockaddr *) &sin,
> -							sizeof(sin), flags);
> +	switch (protocol) {
> +	case IPPROTO_TCP:
> +		return svc_create_xprt(serv, "tcp", port, flags);
> +	case IPPROTO_UDP:
> +		return svc_create_xprt(serv, "udp", port, flags);
> +	default:
> +		return -EINVAL;
> +	}
>  }
>  
>  /*
> -
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2007-12-14 23:05 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-29 22:55 [RFC,PATCH 00/38] RPC Transport Switch Tom Tucker
     [not found] ` <20071129225510.15275.82660.stgit-gUwIgmpLGaKNDNWfRnPdfg@public.gmane.org>
2007-11-29 22:55   ` [RFC,PATCH 01/38] svc: Add an svc transport class Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 02/38] svc: Make svc_sock the tcp/udp transport Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 03/38] svc: Change the svc_sock in the rqstp structure to a transport Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 04/38] svc: Add a max payload value to the transport Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 05/38] svc: Move sk_sendto and sk_recvfrom to svc_xprt_class Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 06/38] svc: Add transport specific xpo_release function Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 07/38] svc: Add per-transport delete functions Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 08/38] svc: Add xpo_prep_reply_hdr Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 09/38] svc: Add a transport function that checks for write space Tom Tucker
2007-11-29 22:55   ` [RFC,PATCH 10/38] svc: Move close processing to a single place Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 11/38] svc: Add xpo_accept transport function Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 12/38] svc: Add a generic transport svc_create_xprt function Tom Tucker
     [not found]     ` <20071129225603.15275.54556.stgit-gUwIgmpLGaKNDNWfRnPdfg@public.gmane.org>
2007-12-14 23:05       ` J. Bruce Fields [this message]
2007-12-21 18:18         ` Tom Tucker
     [not found]           ` <1198261117.14237.47.camel-SMNkleLxa3ZimH42XvhXlA@public.gmane.org>
2008-01-03 19:00             ` J. Bruce Fields
2007-11-29 22:56   ` [RFC,PATCH 13/38] svc: Change services to use new svc_create_xprt service Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 14/38] svc: Change sk_inuse to a kref Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 15/38] svc: Move sk_flags to the svc_xprt structure Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 16/38] svc: Move sk_server and sk_pool to svc_xprt Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 17/38] svc: Make close transport independent Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 18/38] svc: Move sk_reserved to svc_xprt Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 19/38] svc: Make the enqueue service transport neutral and export it Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 20/38] svc: Make svc_send transport neutral Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 21/38] svc: Change svc_sock_received to svc_xprt_received and export it Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 22/38] svc: Remove sk_lastrecv Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 24/38] svc: Make deferral processing xprt independent Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 25/38] svc: Move the sockaddr information to svc_xprt Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 26/38] svc: Make svc_sock_release svc_xprt_release Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 27/38] svc: Make svc_recv transport neutral Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 28/38] svc: Make svc_age_temp_sockets svc_age_temp_transports Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 29/38] svc: Move common create logic to common code Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 30/38] svc: Removing remaining references to rq_sock in rqstp Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 31/38] svc: Make svc_check_conn_limits xprt independent Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 32/38] svc: Move the xprt independent code to the svc_xprt.c file Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 33/38] svc: Add transport hdr size for defer/revisit Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 34/38] svc: Add /proc/sys/sunrpc/transport files Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 35/38] knfsd: Support adding transports by writing portlist file Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 36/38] svc: Add svc API that queries for a transport instance Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 37/38] knfsd: Modify write_ports to use svc_find_xprt service Tom Tucker
2007-11-29 22:56   ` [RFC,PATCH 38/38] svc: Add svc_xprt_names service to replace svc_sock_names Tom Tucker
2007-11-30  0:27   ` [RFC,PATCH 00/38] RPC Transport Switch J. Bruce Fields
2007-11-30  2:01     ` Tom Tucker
  -- strict thread matches above, loose matches on Subject: below --
2007-11-29 22:51 [RFC,PATCH 00/38] SVC " Tom Tucker
     [not found] ` <20071129225142.15107.46200.stgit-gUwIgmpLGaKNDNWfRnPdfg@public.gmane.org>
2007-11-29 22:53   ` [RFC,PATCH 12/38] svc: Add a generic transport svc_create_xprt function Tom Tucker
2007-11-29 22:39 [RFC,PATCH 00/38] SVC Transport Switch Tom Tucker
     [not found] ` <20071129223917.14563.77633.stgit-gUwIgmpLGaKNDNWfRnPdfg@public.gmane.org>
2007-11-29 22:40   ` [RFC,PATCH 12/38] svc: Add a generic transport svc_create_xprt function Tom Tucker

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=20071214230523.GI23121@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=tom@opengridcomputing.com \
    /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