diff options
-rw-r--r-- | fs/nfs/callback.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 51297b2d0532..18efeb5f005d 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -217,12 +217,50 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, | |||
217 | } | 217 | } |
218 | #endif /* CONFIG_NFS_V4_1 */ | 218 | #endif /* CONFIG_NFS_V4_1 */ |
219 | 219 | ||
220 | static struct svc_serv *nfs_callback_create_svc(int minorversion) | ||
221 | { | ||
222 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; | ||
223 | struct svc_serv *serv; | ||
224 | |||
225 | /* | ||
226 | * Check whether we're already up and running. | ||
227 | */ | ||
228 | if (cb_info->task) { | ||
229 | /* | ||
230 | * Note: increase service usage, because later in case of error | ||
231 | * svc_destroy() will be called. | ||
232 | */ | ||
233 | svc_get(cb_info->serv); | ||
234 | return cb_info->serv; | ||
235 | } | ||
236 | |||
237 | /* | ||
238 | * Sanity check: if there's no task, | ||
239 | * we should be the first user ... | ||
240 | */ | ||
241 | if (cb_info->users) | ||
242 | printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n", | ||
243 | cb_info->users); | ||
244 | |||
245 | serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); | ||
246 | if (!serv) { | ||
247 | printk(KERN_ERR "nfs_callback_create_svc: create service failed\n"); | ||
248 | return ERR_PTR(-ENOMEM); | ||
249 | } | ||
250 | /* As there is only one thread we need to over-ride the | ||
251 | * default maximum of 80 connections | ||
252 | */ | ||
253 | serv->sv_maxconn = 1024; | ||
254 | dprintk("nfs_callback_create_svc: service created\n"); | ||
255 | return serv; | ||
256 | } | ||
257 | |||
220 | /* | 258 | /* |
221 | * Bring up the callback thread if it is not already up. | 259 | * Bring up the callback thread if it is not already up. |
222 | */ | 260 | */ |
223 | int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) | 261 | int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) |
224 | { | 262 | { |
225 | struct svc_serv *serv = NULL; | 263 | struct svc_serv *serv; |
226 | struct svc_rqst *rqstp; | 264 | struct svc_rqst *rqstp; |
227 | int (*callback_svc)(void *vrqstp); | 265 | int (*callback_svc)(void *vrqstp); |
228 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; | 266 | struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; |
@@ -232,19 +270,17 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) | |||
232 | struct net *net = &init_net; | 270 | struct net *net = &init_net; |
233 | 271 | ||
234 | mutex_lock(&nfs_callback_mutex); | 272 | mutex_lock(&nfs_callback_mutex); |
273 | |||
274 | serv = nfs_callback_create_svc(minorversion); | ||
275 | if (IS_ERR(serv)) { | ||
276 | ret = PTR_ERR(serv); | ||
277 | goto err_create; | ||
278 | } | ||
279 | |||
235 | if (cb_info->users++ || cb_info->task != NULL) { | 280 | if (cb_info->users++ || cb_info->task != NULL) { |
236 | nfs_callback_bc_serv(minorversion, xprt, cb_info); | 281 | nfs_callback_bc_serv(minorversion, xprt, cb_info); |
237 | goto out; | 282 | goto out; |
238 | } | 283 | } |
239 | serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); | ||
240 | if (!serv) { | ||
241 | ret = -ENOMEM; | ||
242 | goto out_err; | ||
243 | } | ||
244 | /* As there is only one thread we need to over-ride the | ||
245 | * default maximum of 80 connections | ||
246 | */ | ||
247 | serv->sv_maxconn = 1024; | ||
248 | 284 | ||
249 | ret = svc_bind(serv, net); | 285 | ret = svc_bind(serv, net); |
250 | if (ret < 0) { | 286 | if (ret < 0) { |
@@ -285,16 +321,15 @@ out: | |||
285 | * on both success and failure so that the refcount is 1 when the | 321 | * on both success and failure so that the refcount is 1 when the |
286 | * thread exits. | 322 | * thread exits. |
287 | */ | 323 | */ |
288 | if (serv) | 324 | svc_destroy(serv); |
289 | svc_destroy(serv); | 325 | err_create: |
290 | mutex_unlock(&nfs_callback_mutex); | 326 | mutex_unlock(&nfs_callback_mutex); |
291 | return ret; | 327 | return ret; |
292 | out_err: | 328 | out_err: |
293 | dprintk("NFS: Couldn't create callback socket or server thread; " | 329 | dprintk("NFS: Couldn't create callback socket or server thread; " |
294 | "err = %d\n", ret); | 330 | "err = %d\n", ret); |
295 | cb_info->users--; | 331 | cb_info->users--; |
296 | if (serv) | 332 | svc_shutdown_net(serv, net); |
297 | svc_shutdown_net(serv, net); | ||
298 | goto out; | 333 | goto out; |
299 | } | 334 | } |
300 | 335 | ||