]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sunrpc/svc_xprt.c
svc: Move create logic to common code
[linux-2.6-omap-h63xx.git] / net / sunrpc / svc_xprt.c
index eb650af50c492df632b36fd17d7c0bcf75696e78..271467c5138d72d961d7cb62c8aa4ccd752a1bb6 100644 (file)
@@ -105,6 +105,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
        INIT_LIST_HEAD(&xprt->xpt_deferred);
        mutex_init(&xprt->xpt_mutex);
        spin_lock_init(&xprt->xpt_lock);
+       set_bit(XPT_BUSY, &xprt->xpt_flags);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_init);
 
@@ -112,7 +113,6 @@ 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,
@@ -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);
        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)) {
-                               struct svc_xprt *newxprt;
-                               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);
-                               } else
-                                       ret = svc_xprt_local_port(newxprt);
-                       }
-                       goto out;
+               struct svc_xprt *newxprt;
+
+               if (strcmp(xprt_name, xcl->xcl_name))
+                       continue;
+
+               if (!try_module_get(xcl->xcl_owner))
+                       goto err;
+
+               spin_unlock(&svc_xprt_class_lock);
+               newxprt = xcl->xcl_ops->
+                       xpo_create(serv, (struct sockaddr *)&sin, sizeof(sin),
+                                  flags);
+               if (IS_ERR(newxprt)) {
+                       module_put(xcl->xcl_owner);
+                       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);
        dprintk("svc: transport %s not found\n", xprt_name);
- out:
-       return ret;
+       return -ENOENT;
 }
 EXPORT_SYMBOL_GPL(svc_create_xprt);