/* * Destroy an RPC service. Should be called with appropriate locking to * protect the sv_nrthreads, sv_permsocks and sv_tempsocks. */ void svc_destroy(struct svc_serv *serv) { dprintk("svc: svc_destroy(%s, %d)\n", serv->sv_program->pg_name, serv->sv_nrthreads); if (serv->sv_nrthreads) { if (--(serv->sv_nrthreads) != 0) { svc_sock_update_bufs(serv); return; } } else printk("svc_destroy: no threads for serv=%p!\n", serv); del_timer_sync(&serv->sv_temptimer); /* * The last user is gone and thus all sockets have to be destroyed to * the point. Check this. */ BUG_ON(!list_empty(&serv->sv_permsocks)); BUG_ON(!list_empty(&serv->sv_tempsocks)); cache_clean_deferred(serv); if (svc_serv_is_pooled(serv)) svc_pool_map_put(); kfree(serv->sv_pools); kfree(serv); }
/* * Destroy an RPC service */ void svc_destroy(struct svc_serv *serv) { struct svc_sock *svsk; dprintk("RPC: svc_destroy(%s, %d)\n", serv->sv_program->pg_name, serv->sv_nrthreads); if (serv->sv_nrthreads) { if (--(serv->sv_nrthreads) != 0) { svc_sock_update_bufs(serv); return; } } else printk("svc_destroy: no threads for serv=%p!\n", serv); while (!list_empty(&serv->sv_tempsocks)) { svsk = list_entry(serv->sv_tempsocks.next, struct svc_sock, sk_list); svc_delete_socket(svsk); } if (serv->sv_shutdown) serv->sv_shutdown(serv); while (!list_empty(&serv->sv_permsocks)) { svsk = list_entry(serv->sv_permsocks.next, struct svc_sock, sk_list); svc_delete_socket(svsk); } cache_clean_deferred(serv); /* Unregister service with the portmapper */ svc_register(serv, 0, 0); kfree(serv); }