diff options
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r-- | net/sunrpc/svc_xprt.c | 43 |
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 | } |
109 | EXPORT_SYMBOL_GPL(svc_xprt_init); | 110 | EXPORT_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 | } |
146 | EXPORT_SYMBOL_GPL(svc_create_xprt); | 153 | EXPORT_SYMBOL_GPL(svc_create_xprt); |
147 | 154 | ||