All of lore.kernel.org
 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 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.