diff options
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 30d70abb4e2c..6e038884ae0c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -366,6 +366,42 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu) | |||
366 | return &serv->sv_pools[pidx % serv->sv_nrpools]; | 366 | return &serv->sv_pools[pidx % serv->sv_nrpools]; |
367 | } | 367 | } |
368 | 368 | ||
369 | static int svc_rpcb_setup(struct svc_serv *serv) | ||
370 | { | ||
371 | int err; | ||
372 | |||
373 | err = rpcb_create_local(); | ||
374 | if (err) | ||
375 | return err; | ||
376 | |||
377 | /* Remove any stale portmap registrations */ | ||
378 | svc_unregister(serv); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | void svc_rpcb_cleanup(struct svc_serv *serv) | ||
383 | { | ||
384 | svc_unregister(serv); | ||
385 | rpcb_put_local(); | ||
386 | } | ||
387 | EXPORT_SYMBOL_GPL(svc_rpcb_cleanup); | ||
388 | |||
389 | static int svc_uses_rpcbind(struct svc_serv *serv) | ||
390 | { | ||
391 | struct svc_program *progp; | ||
392 | unsigned int i; | ||
393 | |||
394 | for (progp = serv->sv_program; progp; progp = progp->pg_next) { | ||
395 | for (i = 0; i < progp->pg_nvers; i++) { | ||
396 | if (progp->pg_vers[i] == NULL) | ||
397 | continue; | ||
398 | if (progp->pg_vers[i]->vs_hidden == 0) | ||
399 | return 1; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
369 | 405 | ||
370 | /* | 406 | /* |
371 | * Create an RPC service | 407 | * Create an RPC service |
@@ -431,8 +467,15 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | |||
431 | spin_lock_init(&pool->sp_lock); | 467 | spin_lock_init(&pool->sp_lock); |
432 | } | 468 | } |
433 | 469 | ||
434 | /* Remove any stale portmap registrations */ | 470 | if (svc_uses_rpcbind(serv)) { |
435 | svc_unregister(serv); | 471 | if (svc_rpcb_setup(serv) < 0) { |
472 | kfree(serv->sv_pools); | ||
473 | kfree(serv); | ||
474 | return NULL; | ||
475 | } | ||
476 | if (!serv->sv_shutdown) | ||
477 | serv->sv_shutdown = svc_rpcb_cleanup; | ||
478 | } | ||
436 | 479 | ||
437 | return serv; | 480 | return serv; |
438 | } | 481 | } |
@@ -500,7 +543,6 @@ svc_destroy(struct svc_serv *serv) | |||
500 | if (svc_serv_is_pooled(serv)) | 543 | if (svc_serv_is_pooled(serv)) |
501 | svc_pool_map_put(); | 544 | svc_pool_map_put(); |
502 | 545 | ||
503 | svc_unregister(serv); | ||
504 | kfree(serv->sv_pools); | 546 | kfree(serv->sv_pools); |
505 | kfree(serv); | 547 | kfree(serv); |
506 | } | 548 | } |
@@ -971,9 +1013,8 @@ static void svc_unregister(const struct svc_serv *serv) | |||
971 | /* | 1013 | /* |
972 | * Printk the given error with the address of the client that caused it. | 1014 | * Printk the given error with the address of the client that caused it. |
973 | */ | 1015 | */ |
974 | static int | 1016 | static __printf(2, 3) |
975 | __attribute__ ((format (printf, 2, 3))) | 1017 | int svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) |
976 | svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) | ||
977 | { | 1018 | { |
978 | va_list args; | 1019 | va_list args; |
979 | int r; | 1020 | int r; |