Commit 4e5caaa5 authored by Tom Tucker's avatar Tom Tucker Committed by J. Bruce Fields

svc: Move create logic to common code

Move the svc transport list logic into common transport creation code.
Refactor this code path to make the flow of control easier to read.

Move the setting and clearing of the BUSY_BIT during transport creation
to common code.
Signed-off-by: default avatarTom Tucker <tom@opengridcomputing.com>
Acked-by: default avatarNeil Brown <neilb@suse.de>
Reviewed-by: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarGreg Banks <gnb@sgi.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 9f8bfae6
...@@ -105,6 +105,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt, ...@@ -105,6 +105,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
INIT_LIST_HEAD(&xprt->xpt_deferred); INIT_LIST_HEAD(&xprt->xpt_deferred);
mutex_init(&xprt->xpt_mutex); mutex_init(&xprt->xpt_mutex);
spin_lock_init(&xprt->xpt_lock); spin_lock_init(&xprt->xpt_lock);
set_bit(XPT_BUSY, &xprt->xpt_flags);
} }
EXPORT_SYMBOL_GPL(svc_xprt_init); EXPORT_SYMBOL_GPL(svc_xprt_init);
...@@ -112,7 +113,6 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, ...@@ -112,7 +113,6 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
int flags) int flags)
{ {
struct svc_xprt_class *xcl; struct svc_xprt_class *xcl;
int ret = -ENOENT;
struct sockaddr_in sin = { struct sockaddr_in sin = {
.sin_family = AF_INET, .sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY, .sin_addr.s_addr = INADDR_ANY,
...@@ -121,27 +121,34 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, ...@@ -121,27 +121,34 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
dprintk("svc: creating transport %s[%d]\n", xprt_name, port); dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
spin_lock(&svc_xprt_class_lock); spin_lock(&svc_xprt_class_lock);
list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
if (strcmp(xprt_name, xcl->xcl_name) == 0) { struct svc_xprt *newxprt;
spin_unlock(&svc_xprt_class_lock);
if (try_module_get(xcl->xcl_owner)) { if (strcmp(xprt_name, xcl->xcl_name))
struct svc_xprt *newxprt; continue;
newxprt = xcl->xcl_ops->xpo_create
(serv, if (!try_module_get(xcl->xcl_owner))
(struct sockaddr *)&sin, sizeof(sin), goto err;
flags);
if (IS_ERR(newxprt)) { spin_unlock(&svc_xprt_class_lock);
module_put(xcl->xcl_owner); newxprt = xcl->xcl_ops->
ret = PTR_ERR(newxprt); xpo_create(serv, (struct sockaddr *)&sin, sizeof(sin),
} else flags);
ret = svc_xprt_local_port(newxprt); if (IS_ERR(newxprt)) {
} module_put(xcl->xcl_owner);
goto out; return PTR_ERR(newxprt);
} }
clear_bit(XPT_TEMP, &newxprt->xpt_flags);
spin_lock_bh(&serv->sv_lock);
list_add(&newxprt->xpt_list, &serv->sv_permsocks);
spin_unlock_bh(&serv->sv_lock);
clear_bit(XPT_BUSY, &newxprt->xpt_flags);
return svc_xprt_local_port(newxprt);
} }
err:
spin_unlock(&svc_xprt_class_lock); spin_unlock(&svc_xprt_class_lock);
dprintk("svc: transport %s not found\n", xprt_name); dprintk("svc: transport %s not found\n", xprt_name);
out: return -ENOENT;
return ret;
} }
EXPORT_SYMBOL_GPL(svc_create_xprt); EXPORT_SYMBOL_GPL(svc_create_xprt);
......
...@@ -94,6 +94,7 @@ static int svc_deferred_recv(struct svc_rqst *rqstp); ...@@ -94,6 +94,7 @@ static int svc_deferred_recv(struct svc_rqst *rqstp);
static struct cache_deferred_req *svc_defer(struct cache_req *req); static struct cache_deferred_req *svc_defer(struct cache_req *req);
static struct svc_xprt *svc_create_socket(struct svc_serv *, int, static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
struct sockaddr *, int, int); struct sockaddr *, int, int);
static void svc_age_temp_xprts(unsigned long closure);
/* apparently the "standard" is that clients close /* apparently the "standard" is that clients close
* idle connections after 5 minutes, servers after * idle connections after 5 minutes, servers after
...@@ -1573,6 +1574,19 @@ svc_recv(struct svc_rqst *rqstp, long timeout) ...@@ -1573,6 +1574,19 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
*/ */
__module_get(newxpt->xpt_class->xcl_owner); __module_get(newxpt->xpt_class->xcl_owner);
svc_check_conn_limits(xprt->xpt_server); svc_check_conn_limits(xprt->xpt_server);
spin_lock_bh(&serv->sv_lock);
set_bit(XPT_TEMP, &newxpt->xpt_flags);
list_add(&newxpt->xpt_list, &serv->sv_tempsocks);
serv->sv_tmpcnt++;
if (serv->sv_temptimer.function == NULL) {
/* setup timer to age temp sockets */
setup_timer(&serv->sv_temptimer,
svc_age_temp_xprts,
(unsigned long)serv);
mod_timer(&serv->sv_temptimer,
jiffies + svc_conn_age_period * HZ);
}
spin_unlock_bh(&serv->sv_lock);
svc_xprt_received(newxpt); svc_xprt_received(newxpt);
} }
svc_xprt_received(xprt); svc_xprt_received(xprt);
...@@ -1716,7 +1730,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, ...@@ -1716,7 +1730,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
struct svc_sock *svsk; struct svc_sock *svsk;
struct sock *inet; struct sock *inet;
int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); int pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
int is_temporary = flags & SVC_SOCK_TEMPORARY;
dprintk("svc: svc_setup_socket %p\n", sock); dprintk("svc: svc_setup_socket %p\n", sock);
if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
...@@ -1736,7 +1749,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, ...@@ -1736,7 +1749,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
return NULL; return NULL;
} }
set_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags);
inet->sk_user_data = svsk; inet->sk_user_data = svsk;
svsk->sk_sock = sock; svsk->sk_sock = sock;
svsk->sk_sk = inet; svsk->sk_sk = inet;
...@@ -1750,24 +1762,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, ...@@ -1750,24 +1762,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
else else
svc_tcp_init(svsk, serv); svc_tcp_init(svsk, serv);
spin_lock_bh(&serv->sv_lock);
if (is_temporary) {
set_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
list_add(&svsk->sk_xprt.xpt_list, &serv->sv_tempsocks);
serv->sv_tmpcnt++;
if (serv->sv_temptimer.function == NULL) {
/* setup timer to age temp sockets */
setup_timer(&serv->sv_temptimer, svc_age_temp_xprts,
(unsigned long)serv);
mod_timer(&serv->sv_temptimer,
jiffies + svc_conn_age_period * HZ);
}
} else {
clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks);
}
spin_unlock_bh(&serv->sv_lock);
dprintk("svc: svc_setup_socket created %p (inet %p)\n", dprintk("svc: svc_setup_socket created %p (inet %p)\n",
svsk, svsk->sk_sk); svsk, svsk->sk_sk);
...@@ -1800,6 +1794,10 @@ int svc_addsock(struct svc_serv *serv, ...@@ -1800,6 +1794,10 @@ int svc_addsock(struct svc_serv *serv,
int salen; int salen;
if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0) if (kernel_getsockname(svsk->sk_sock, sin, &salen) == 0)
svc_xprt_set_local(&svsk->sk_xprt, sin, salen); svc_xprt_set_local(&svsk->sk_xprt, sin, salen);
clear_bit(XPT_TEMP, &svsk->sk_xprt.xpt_flags);
spin_lock_bh(&serv->sv_lock);
list_add(&svsk->sk_xprt.xpt_list, &serv->sv_permsocks);
spin_unlock_bh(&serv->sv_lock);
svc_xprt_received(&svsk->sk_xprt); svc_xprt_received(&svsk->sk_xprt);
err = 0; err = 0;
} }
...@@ -1865,7 +1863,6 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, ...@@ -1865,7 +1863,6 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) { if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) {
svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen); svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen);
svc_xprt_received(&svsk->sk_xprt);
return (struct svc_xprt *)svsk; return (struct svc_xprt *)svsk;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment