aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc_xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r--net/sunrpc/svc_xprt.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index eb650af50c49..271467c5138d 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -105,6 +105,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
105 INIT_LIST_HEAD(&xprt->xpt_deferred); 105 INIT_LIST_HEAD(&xprt->xpt_deferred);
106 mutex_init(&xprt->xpt_mutex); 106 mutex_init(&xprt->xpt_mutex);
107 spin_lock_init(&xprt->xpt_lock); 107 spin_lock_init(&xprt->xpt_lock);
108 set_bit(XPT_BUSY, &xprt->xpt_flags);
108} 109}
109EXPORT_SYMBOL_GPL(svc_xprt_init); 110EXPORT_SYMBOL_GPL(svc_xprt_init);
110 111
@@ -112,7 +113,6 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
112 int flags) 113 int flags)
113{ 114{
114 struct svc_xprt_class *xcl; 115 struct svc_xprt_class *xcl;
115 int ret = -ENOENT;
116 struct sockaddr_in sin = { 116 struct sockaddr_in sin = {
117 .sin_family = AF_INET, 117 .sin_family = AF_INET,
118 .sin_addr.s_addr = INADDR_ANY, 118 .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 dprintk("svc: creating transport %s[%d]\n", xprt_name, port); 121 dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
122 spin_lock(&svc_xprt_class_lock); 122 spin_lock(&svc_xprt_class_lock);
123 list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { 123 list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
124 if (strcmp(xprt_name, xcl->xcl_name) == 0) { 124 struct svc_xprt *newxprt;
125 spin_unlock(&svc_xprt_class_lock); 125
126 if (try_module_get(xcl->xcl_owner)) { 126 if (strcmp(xprt_name, xcl->xcl_name))
127 struct svc_xprt *newxprt; 127 continue;
128 newxprt = xcl->xcl_ops->xpo_create 128
129 (serv, 129 if (!try_module_get(xcl->xcl_owner))
130 (struct sockaddr *)&sin, sizeof(sin), 130 goto err;
131 flags); 131
132 if (IS_ERR(newxprt)) { 132 spin_unlock(&svc_xprt_class_lock);
133 module_put(xcl->xcl_owner); 133 newxprt = xcl->xcl_ops->
134 ret = PTR_ERR(newxprt); 134 xpo_create(serv, (struct sockaddr *)&sin, sizeof(sin),
135 } else 135 flags);
136 ret = svc_xprt_local_port(newxprt); 136 if (IS_ERR(newxprt)) {
137 } 137 module_put(xcl->xcl_owner);
138 goto out; 138 return PTR_ERR(newxprt);
139 } 139 }
140
141 clear_bit(XPT_TEMP, &newxprt->xpt_flags);
142 spin_lock_bh(&serv->sv_lock);
143 list_add(&newxprt->xpt_list, &serv->sv_permsocks);
144 spin_unlock_bh(&serv->sv_lock);
145 clear_bit(XPT_BUSY, &newxprt->xpt_flags);
146 return svc_xprt_local_port(newxprt);
140 } 147 }
148 err:
141 spin_unlock(&svc_xprt_class_lock); 149 spin_unlock(&svc_xprt_class_lock);
142 dprintk("svc: transport %s not found\n", xprt_name); 150 dprintk("svc: transport %s not found\n", xprt_name);
143 out: 151 return -ENOENT;
144 return ret;
145} 152}
146EXPORT_SYMBOL_GPL(svc_create_xprt); 153EXPORT_SYMBOL_GPL(svc_create_xprt);
147 154