static int lockd_up_net(struct svc_serv *serv, struct net *net) { struct lockd_net *ln = net_generic(net, lockd_net_id); int error; if (ln->nlmsvc_users++) return 0; error = svc_bind(serv, net); if (error) goto err_bind; error = make_socks(serv, net); if (error < 0) goto err_socks; set_grace_period(net); dprintk("lockd_up_net: per-net data created; net=%p\n", net); return 0; err_socks: svc_rpcb_cleanup(serv, net); err_bind: ln->nlmsvc_users--; return error; }
static int lockd_up_net(struct svc_serv *serv, struct net *net) { struct lockd_net *ln = net_generic(net, lockd_net_id); int error; if (ln->nlmsvc_users++) return 0; error = svc_bind(serv, net); if (error) goto err_bind; error = make_socks(serv, net); if (error < 0) goto err_bind; set_grace_period(net); dprintk("%s: per-net data created; net=%x\n", __func__, net->ns.inum); return 0; err_bind: ln->nlmsvc_users--; return error; }
int lockd_up(struct net *net) { struct svc_serv *serv; int error = 0; struct lockd_net *ln = net_generic(net, lockd_net_id); mutex_lock(&nlmsvc_mutex); if (nlmsvc_rqst) { error = lockd_up_net(nlmsvc_rqst->rq_server, net); goto out; } if (nlmsvc_users) printk(KERN_WARNING "lockd_up: no pid, %d users??\n", nlmsvc_users); error = -ENOMEM; serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); if (!serv) { printk(KERN_WARNING "lockd_up: create service failed\n"); goto out; } error = svc_bind(serv, net); if (error < 0) { printk(KERN_WARNING "lockd_up: bind service failed\n"); goto destroy_and_out; } ln->nlmsvc_users++; error = make_socks(serv, net); if (error < 0) goto err_start; nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); if (IS_ERR(nlmsvc_rqst)) { error = PTR_ERR(nlmsvc_rqst); nlmsvc_rqst = NULL; printk(KERN_WARNING "lockd_up: svc_rqst allocation failed, error=%d\n", error); goto err_start; } svc_sock_update_bufs(serv); serv->sv_maxconn = nlm_max_connections; nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); if (IS_ERR(nlmsvc_task)) { error = PTR_ERR(nlmsvc_task); svc_exit_thread(nlmsvc_rqst); nlmsvc_task = NULL; nlmsvc_rqst = NULL; printk(KERN_WARNING "lockd_up: kthread_run failed, error=%d\n", error); goto err_start; } destroy_and_out: svc_destroy(serv); out: if (!error) nlmsvc_users++; mutex_unlock(&nlmsvc_mutex); return error; err_start: lockd_down_net(serv, net); goto destroy_and_out; }
/* * Bring up the lockd process if it's not already up. */ int lockd_up(struct net *net) { struct svc_serv *serv; int error = 0; struct lockd_net *ln = net_generic(net, lockd_net_id); mutex_lock(&nlmsvc_mutex); /* * Check whether we're already up and running. */ if (nlmsvc_rqst) { error = lockd_up_net(net); goto out; } /* * Sanity check: if there's no pid, * we should be the first user ... */ if (nlmsvc_users) printk(KERN_WARNING "lockd_up: no pid, %d users??\n", nlmsvc_users); error = -ENOMEM; serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); if (!serv) { printk(KERN_WARNING "lockd_up: create service failed\n"); goto out; } error = svc_bind(serv, net); if (error < 0) { printk(KERN_WARNING "lockd_up: bind service failed\n"); goto destroy_and_out; } ln->nlmsvc_users++; error = make_socks(serv, net); if (error < 0) goto err_start; /* * Create the kernel thread and wait for it to start. */ nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); if (IS_ERR(nlmsvc_rqst)) { error = PTR_ERR(nlmsvc_rqst); nlmsvc_rqst = NULL; printk(KERN_WARNING "lockd_up: svc_rqst allocation failed, error=%d\n", error); goto err_start; } svc_sock_update_bufs(serv); serv->sv_maxconn = nlm_max_connections; nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); if (IS_ERR(nlmsvc_task)) { error = PTR_ERR(nlmsvc_task); svc_exit_thread(nlmsvc_rqst); nlmsvc_task = NULL; nlmsvc_rqst = NULL; printk(KERN_WARNING "lockd_up: kthread_run failed, error=%d\n", error); goto err_start; } /* * Note: svc_serv structures have an initial use count of 1, * so we exit through here on both success and failure. */ destroy_and_out: svc_destroy(serv); out: if (!error) nlmsvc_users++; mutex_unlock(&nlmsvc_mutex); return error; err_start: lockd_down_net(net); goto destroy_and_out; }