* 3.4.z nfsd backports @ 2012-06-18 20:07 J. Bruce Fields 2012-06-18 20:07 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced J. Bruce Fields ` (3 more replies) 0 siblings, 4 replies; 13+ messages in thread From: J. Bruce Fields @ 2012-06-18 20:07 UTC (permalink / raw) To: stable; +Cc: linux-nfs These three patches are all upstream, but required some conflict resolution to backport, so I'm sending backported versions. --b. ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-06-18 20:07 3.4.z nfsd backports J. Bruce Fields @ 2012-06-18 20:07 ` J. Bruce Fields 2012-06-20 16:34 ` Greg KH 2012-06-18 20:07 ` [PATCH 2/3] SUNRPC: move per-net operations from svc_destroy() J. Bruce Fields ` (2 subsequent siblings) 3 siblings, 1 reply; 13+ messages in thread From: J. Bruce Fields @ 2012-06-18 20:07 UTC (permalink / raw) To: stable; +Cc: linux-nfs, Stanislav Kinsbursky, J. Bruce Fields From: Stanislav Kinsbursky <skinsbursky@parallels.com> commit cd96891d48a945ca2011fbeceda73813d6286195 upstream. This new routine is responsible for service registration in a specified network context. The idea is to separate service creation from per-net operations. Note also: since registering service with svc_bind() can fail, the service will be destroyed and during destruction it will try to unregister itself from rpcbind. In this case unregistration has to be skipped. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/lockd/svc.c | 6 ++++++ fs/nfs/callback.c | 8 ++++++++ fs/nfsd/nfssvc.c | 9 +++++++++ include/linux/sunrpc/svc.h | 1 + net/sunrpc/rpcb_clnt.c | 12 +++++++----- net/sunrpc/svc.c | 19 ++++++++++--------- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index f49b9af..b1d0708 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -325,6 +325,12 @@ int lockd_up(void) goto out; } + error = svc_bind(serv, net); + if (error < 0) { + printk(KERN_WARNING "lockd_up: bind service failed\n"); + goto destroy_and_out; + } + error = make_socks(serv, net); if (error < 0) goto destroy_and_out; diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index eb95f50..26b38fb 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -17,6 +17,7 @@ #include <linux/kthread.h> #include <linux/sunrpc/svcauth_gss.h> #include <linux/sunrpc/bc_xprt.h> +#include <linux/nsproxy.h> #include <net/inet_sock.h> @@ -253,6 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) char svc_name[12]; int ret = 0; int minorversion_setup; + struct net *net = current->nsproxy->net_ns; mutex_lock(&nfs_callback_mutex); if (cb_info->users++ || cb_info->task != NULL) { @@ -265,6 +267,12 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) goto out_err; } + ret = svc_bind(serv, net); + if (ret < 0) { + printk(KERN_WARNING "NFS: bind callback service failed\n"); + goto out_err; + } + minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion, serv, xprt, &rqstp, &callback_svc); if (!minorversion_setup) { diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 28dfad3..a6461f3 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/fs_struct.h> #include <linux/swap.h> +#include <linux/nsproxy.h> #include <linux/sunrpc/stats.h> #include <linux/sunrpc/svcsock.h> @@ -330,6 +331,8 @@ static int nfsd_get_default_max_blksize(void) int nfsd_create_serv(void) { + int error; + WARN_ON(!mutex_is_locked(&nfsd_mutex)); if (nfsd_serv) { svc_get(nfsd_serv); @@ -343,6 +346,12 @@ int nfsd_create_serv(void) if (nfsd_serv == NULL) return -ENOMEM; + error = svc_bind(nfsd_serv, current->nsproxy->net_ns); + if (error < 0) { + svc_destroy(nfsd_serv); + return error; + } + set_max_drc(); do_gettimeofday(&nfssvc_boot); /* record boot time */ return 0; diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 51b29ac..2b43e02 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -416,6 +416,7 @@ struct svc_procedure { */ int svc_rpcb_setup(struct svc_serv *serv, struct net *net); void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); +int svc_bind(struct svc_serv *serv, struct net *net); struct svc_serv *svc_create(struct svc_program *, unsigned int, void (*shutdown)(struct svc_serv *, struct net *net)); struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 78ac39f..4c38b33 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -180,14 +180,16 @@ void rpcb_put_local(struct net *net) struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); struct rpc_clnt *clnt = sn->rpcb_local_clnt; struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4; - int shutdown; + int shutdown = 0; spin_lock(&sn->rpcb_clnt_lock); - if (--sn->rpcb_users == 0) { - sn->rpcb_local_clnt = NULL; - sn->rpcb_local_clnt4 = NULL; + if (sn->rpcb_users) { + if (--sn->rpcb_users == 0) { + sn->rpcb_local_clnt = NULL; + sn->rpcb_local_clnt4 = NULL; + } + shutdown = !sn->rpcb_users; } - shutdown = !sn->rpcb_users; spin_unlock(&sn->rpcb_clnt_lock); if (shutdown) { diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 4153846..e6d542c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -407,6 +407,14 @@ static int svc_uses_rpcbind(struct svc_serv *serv) return 0; } +int svc_bind(struct svc_serv *serv, struct net *net) +{ + if (!svc_uses_rpcbind(serv)) + return 0; + return svc_rpcb_setup(serv, net); +} +EXPORT_SYMBOL_GPL(svc_bind); + /* * Create an RPC service */ @@ -471,15 +479,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, spin_lock_init(&pool->sp_lock); } - if (svc_uses_rpcbind(serv)) { - if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) { - kfree(serv->sv_pools); - kfree(serv); - return NULL; - } - if (!serv->sv_shutdown) - serv->sv_shutdown = svc_rpcb_cleanup; - } + if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown)) + serv->sv_shutdown = svc_rpcb_cleanup; return serv; } -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-06-18 20:07 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced J. Bruce Fields @ 2012-06-20 16:34 ` Greg KH 2012-06-20 18:09 ` J. Bruce Fields 0 siblings, 1 reply; 13+ messages in thread From: Greg KH @ 2012-06-20 16:34 UTC (permalink / raw) To: J. Bruce Fields; +Cc: stable, linux-nfs, Stanislav Kinsbursky On Mon, Jun 18, 2012 at 04:07:27PM -0400, J. Bruce Fields wrote: > From: Stanislav Kinsbursky <skinsbursky@parallels.com> > > commit cd96891d48a945ca2011fbeceda73813d6286195 upstream. Um, no, that's not what this commit id is at all. Where did you get that from? I kind of don't trust this series now, care to fix these up with the correct git commit ids and resend them? thanks, greg k-h ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-06-20 16:34 ` Greg KH @ 2012-06-20 18:09 ` J. Bruce Fields 2012-06-20 18:18 ` Greg KH 0 siblings, 1 reply; 13+ messages in thread From: J. Bruce Fields @ 2012-06-20 18:09 UTC (permalink / raw) To: Greg KH; +Cc: stable, linux-nfs, Stanislav Kinsbursky On Wed, Jun 20, 2012 at 09:34:27AM -0700, Greg KH wrote: > On Mon, Jun 18, 2012 at 04:07:27PM -0400, J. Bruce Fields wrote: > > From: Stanislav Kinsbursky <skinsbursky@parallels.com> > > > > commit cd96891d48a945ca2011fbeceda73813d6286195 upstream. > > Um, no, that's not what this commit id is at all. Whoops, sorry! Should have been 9793f7c88. Upstream commits on #2 and #3 are correct. > Where did you get that from? I kind of don't trust this series now, > care to fix these up with the correct git commit ids and resend them? Sure, I'll resend once I get the "4/3" patch sorted out. (That got a form rejection--I assume it was the missing upstream commit ID? That's because there isn't one--3.4 requires a different fix. But I can point to where the bug got fixed upstream even if it isn't the same.) --b. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-06-20 18:09 ` J. Bruce Fields @ 2012-06-20 18:18 ` Greg KH 2012-06-25 20:33 ` J. Bruce Fields 0 siblings, 1 reply; 13+ messages in thread From: Greg KH @ 2012-06-20 18:18 UTC (permalink / raw) To: J. Bruce Fields; +Cc: stable, linux-nfs, Stanislav Kinsbursky On Wed, Jun 20, 2012 at 02:09:29PM -0400, J. Bruce Fields wrote: > On Wed, Jun 20, 2012 at 09:34:27AM -0700, Greg KH wrote: > > On Mon, Jun 18, 2012 at 04:07:27PM -0400, J. Bruce Fields wrote: > > > From: Stanislav Kinsbursky <skinsbursky@parallels.com> > > > > > > commit cd96891d48a945ca2011fbeceda73813d6286195 upstream. > > > > Um, no, that's not what this commit id is at all. > > Whoops, sorry! Should have been 9793f7c88. Upstream commits on #2 and > #3 are correct. > > > Where did you get that from? I kind of don't trust this series now, > > care to fix these up with the correct git commit ids and resend them? > > Sure, I'll resend once I get the "4/3" patch sorted out. > > (That got a form rejection--I assume it was the missing upstream commit > ID? That's because there isn't one--3.4 requires a different fix. But > I can point to where the bug got fixed upstream even if it isn't the > same.) You need to be really specific when sending a patch that is not upstream, detailing why it isn't, and what different fix went in upstream, if possible. thanks, greg k-h ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-06-20 18:18 ` Greg KH @ 2012-06-25 20:33 ` J. Bruce Fields 2012-06-25 20:44 ` J. Bruce Fields 0 siblings, 1 reply; 13+ messages in thread From: J. Bruce Fields @ 2012-06-25 20:33 UTC (permalink / raw) To: Greg KH; +Cc: J. Bruce Fields, stable, linux-nfs, Stanislav Kinsbursky On Wed, Jun 20, 2012 at 11:18:35AM -0700, Greg KH wrote: > On Wed, Jun 20, 2012 at 02:09:29PM -0400, J. Bruce Fields wrote: > > On Wed, Jun 20, 2012 at 09:34:27AM -0700, Greg KH wrote: > > > On Mon, Jun 18, 2012 at 04:07:27PM -0400, J. Bruce Fields wrote: > > > > From: Stanislav Kinsbursky <skinsbursky@parallels.com> > > > > > > > > commit cd96891d48a945ca2011fbeceda73813d6286195 upstream. > > > > > > Um, no, that's not what this commit id is at all. > > > > Whoops, sorry! Should have been 9793f7c88. Upstream commits on #2 and > > #3 are correct. > > > > > Where did you get that from? I kind of don't trust this series now, > > > care to fix these up with the correct git commit ids and resend them? > > > > Sure, I'll resend once I get the "4/3" patch sorted out. > > > > (That got a form rejection--I assume it was the missing upstream commit > > ID? That's because there isn't one--3.4 requires a different fix. But > > I can point to where the bug got fixed upstream even if it isn't the > > same.) > > You need to be really specific when sending a patch that is not > upstream, detailing why it isn't, and what different fix went in > upstream, if possible. OK, looking at it closer I notice we can actually just take a different fix directly from upstream, and then there's no problem. But it took me a few days to get around to setting up a test-case to make sure that still did the job.... I'll pass along the revised series in a moment.--b. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-06-25 20:33 ` J. Bruce Fields @ 2012-06-25 20:44 ` J. Bruce Fields 0 siblings, 0 replies; 13+ messages in thread From: J. Bruce Fields @ 2012-06-25 20:44 UTC (permalink / raw) To: Greg KH; +Cc: J. Bruce Fields, stable, linux-nfs, Stanislav Kinsbursky On Mon, Jun 25, 2012 at 04:33:32PM -0400, bfields wrote: > On Wed, Jun 20, 2012 at 11:18:35AM -0700, Greg KH wrote: > > On Wed, Jun 20, 2012 at 02:09:29PM -0400, J. Bruce Fields wrote: > > > On Wed, Jun 20, 2012 at 09:34:27AM -0700, Greg KH wrote: > > > > On Mon, Jun 18, 2012 at 04:07:27PM -0400, J. Bruce Fields wrote: > > > > > From: Stanislav Kinsbursky <skinsbursky@parallels.com> > > > > > > > > > > commit cd96891d48a945ca2011fbeceda73813d6286195 upstream. > > > > > > > > Um, no, that's not what this commit id is at all. > > > > > > Whoops, sorry! Should have been 9793f7c88. Upstream commits on #2 and > > > #3 are correct. > > > > > > > Where did you get that from? I kind of don't trust this series now, > > > > care to fix these up with the correct git commit ids and resend them? > > > > > > Sure, I'll resend once I get the "4/3" patch sorted out. > > > > > > (That got a form rejection--I assume it was the missing upstream commit > > > ID? That's because there isn't one--3.4 requires a different fix. But > > > I can point to where the bug got fixed upstream even if it isn't the > > > same.) > > > > You need to be really specific when sending a patch that is not > > upstream, detailing why it isn't, and what different fix went in > > upstream, if possible. > > OK, looking at it closer I notice we can actually just take a different > fix directly from upstream, and then there's no problem. But it took me > a few days to get around to setting up a test-case to make sure that > still did the job.... (Oh, and my reproducer in case anyone wonders: build the following, run ./namespace-exec /bin/bash and mount -tproc proc /proc ps ax just to verify you're in a new pid/mount namespace, then mount -tnfs yourserver:/somepath /mnt then ^D out of the shell, and it should crash.) --b. #define _GNU_SOURCE #include <unistd.h> #include <signal.h> #include <sched.h> #include <sys/syscall.h> #include <err.h> int main(int argc, char *argv[]) { int pid; int flags = SIGCHLD; if (argc < 2) errx(1, "usage: %s command arg1 arg2 ...", argv[0]); flags |= CLONE_NEWNS|CLONE_NEWPID; pid = syscall(__NR_clone, flags, NULL); if (pid < 0) err(1, "clone failed"); if (pid == 0) { /* child */ int ret; ret = execv(argv[1], argv+1); if (ret) err(1,"failed to exec %s", argv[1]); } wait(); } ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3] SUNRPC: move per-net operations from svc_destroy() 2012-06-18 20:07 3.4.z nfsd backports J. Bruce Fields 2012-06-18 20:07 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced J. Bruce Fields @ 2012-06-18 20:07 ` J. Bruce Fields 2012-06-18 20:07 ` [PATCH 3/3] NFS: hard-code init_net for NFS callback transports J. Bruce Fields 2012-06-20 16:35 ` 3.4.z nfsd backports Greg KH 3 siblings, 0 replies; 13+ messages in thread From: J. Bruce Fields @ 2012-06-18 20:07 UTC (permalink / raw) To: stable; +Cc: linux-nfs, Stanislav Kinsbursky, J. Bruce Fields From: Stanislav Kinsbursky <skinsbursky@parallels.com> commit 786185b5f8abefa6a8a16695bb4a59c164d5a071 upstream. The idea is to separate service destruction and per-net operations, because these are two different things and the mix looks ugly. Notes: 1) For NFS server this patch looks ugly (sorry for that). But these place will be rewritten soon during NFSd containerization. 2) LockD per-net counter increase int lockd_up() was moved prior to make_socks() to make lockd_down_net() call safe in case of error. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/lockd/svc.c | 27 +++++++++++++++------------ fs/nfs/callback.c | 3 +++ fs/nfsd/nfsctl.c | 12 +++++++++--- fs/nfsd/nfssvc.c | 14 ++++++++++++++ net/sunrpc/svc.c | 4 ---- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index b1d0708..f1b3cce 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -257,7 +257,7 @@ static int lockd_up_net(struct net *net) struct svc_serv *serv = nlmsvc_rqst->rq_server; int error; - if (ln->nlmsvc_users) + if (ln->nlmsvc_users++) return 0; error = svc_rpcb_setup(serv, net); @@ -272,6 +272,7 @@ static int lockd_up_net(struct net *net) err_socks: svc_rpcb_cleanup(serv, net); err_rpcb: + ln->nlmsvc_users--; return error; } @@ -300,6 +301,7 @@ int lockd_up(void) struct svc_serv *serv; int error = 0; struct net *net = current->nsproxy->net_ns; + struct lockd_net *ln = net_generic(net, lockd_net_id); mutex_lock(&nlmsvc_mutex); /* @@ -331,9 +333,11 @@ int lockd_up(void) goto destroy_and_out; } + ln->nlmsvc_users++; + error = make_socks(serv, net); if (error < 0) - goto destroy_and_out; + goto err_start; /* * Create the kernel thread and wait for it to start. @@ -345,7 +349,7 @@ int lockd_up(void) printk(KERN_WARNING "lockd_up: svc_rqst allocation failed, error=%d\n", error); - goto destroy_and_out; + goto err_start; } svc_sock_update_bufs(serv); @@ -359,7 +363,7 @@ int lockd_up(void) nlmsvc_rqst = NULL; printk(KERN_WARNING "lockd_up: kthread_run failed, error=%d\n", error); - goto destroy_and_out; + goto err_start; } /* @@ -369,14 +373,14 @@ int lockd_up(void) destroy_and_out: svc_destroy(serv); out: - if (!error) { - struct lockd_net *ln = net_generic(net, lockd_net_id); - - ln->nlmsvc_users++; + if (!error) nlmsvc_users++; - } mutex_unlock(&nlmsvc_mutex); return error; + +err_start: + lockd_down_net(net); + goto destroy_and_out; } EXPORT_SYMBOL_GPL(lockd_up); @@ -387,11 +391,10 @@ void lockd_down(void) { mutex_lock(&nlmsvc_mutex); + lockd_down_net(current->nsproxy->net_ns); if (nlmsvc_users) { - if (--nlmsvc_users) { - lockd_down_net(current->nsproxy->net_ns); + if (--nlmsvc_users) goto out; - } } else { printk(KERN_ERR "lockd_down: no users! task=%p\n", nlmsvc_task); diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 26b38fb..cff3940 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -314,6 +314,8 @@ out_err: dprintk("NFS: Couldn't create callback socket or server thread; " "err = %d\n", ret); cb_info->users--; + if (serv) + svc_shutdown_net(serv, net); goto out; } @@ -328,6 +330,7 @@ void nfs_callback_down(int minorversion) cb_info->users--; if (cb_info->users == 0 && cb_info->task != NULL) { kthread_stop(cb_info->task); + svc_shutdown_net(cb_info->serv, current->nsproxy->net_ns); svc_exit_thread(cb_info->rqst); cb_info->serv = NULL; cb_info->rqst = NULL; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 2c53be6..3ab12eb 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -651,6 +651,7 @@ static ssize_t __write_ports_addfd(char *buf) { char *mesg = buf; int fd, err; + struct net *net = &init_net; err = get_int(&mesg, &fd); if (err != 0 || fd < 0) @@ -662,6 +663,8 @@ static ssize_t __write_ports_addfd(char *buf) err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); if (err < 0) { + if (nfsd_serv->sv_nrthreads == 1) + svc_shutdown_net(nfsd_serv, net); svc_destroy(nfsd_serv); return err; } @@ -699,6 +702,7 @@ static ssize_t __write_ports_addxprt(char *buf) char transport[16]; struct svc_xprt *xprt; int port, err; + struct net *net = &init_net; if (sscanf(buf, "%15s %4u", transport, &port) != 2) return -EINVAL; @@ -710,12 +714,12 @@ static ssize_t __write_ports_addxprt(char *buf) if (err != 0) return err; - err = svc_create_xprt(nfsd_serv, transport, &init_net, + err = svc_create_xprt(nfsd_serv, transport, net, PF_INET, port, SVC_SOCK_ANONYMOUS); if (err < 0) goto out_err; - err = svc_create_xprt(nfsd_serv, transport, &init_net, + err = svc_create_xprt(nfsd_serv, transport, net, PF_INET6, port, SVC_SOCK_ANONYMOUS); if (err < 0 && err != -EAFNOSUPPORT) goto out_close; @@ -724,12 +728,14 @@ static ssize_t __write_ports_addxprt(char *buf) nfsd_serv->sv_nrthreads--; return 0; out_close: - xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port); + xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port); if (xprt != NULL) { svc_close_xprt(xprt); svc_xprt_put(xprt); } out_err: + if (nfsd_serv->sv_nrthreads == 1) + svc_shutdown_net(nfsd_serv, net); svc_destroy(nfsd_serv); return err; } diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index a6461f3..da50e1c 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -382,6 +382,7 @@ int nfsd_set_nrthreads(int n, int *nthreads) int i = 0; int tot = 0; int err = 0; + struct net *net = &init_net; WARN_ON(!mutex_is_locked(&nfsd_mutex)); @@ -426,6 +427,9 @@ int nfsd_set_nrthreads(int n, int *nthreads) if (err) break; } + + if (nfsd_serv->sv_nrthreads == 1) + svc_shutdown_net(nfsd_serv, net); svc_destroy(nfsd_serv); return err; @@ -441,6 +445,7 @@ nfsd_svc(unsigned short port, int nrservs) { int error; bool nfsd_up_before; + struct net *net = &init_net; mutex_lock(&nfsd_mutex); dprintk("nfsd: creating service\n"); @@ -473,6 +478,8 @@ out_shutdown: if (error < 0 && !nfsd_up_before) nfsd_shutdown(); out_destroy: + if (nfsd_serv->sv_nrthreads == 1) + svc_shutdown_net(nfsd_serv, net); svc_destroy(nfsd_serv); /* Release server */ out: mutex_unlock(&nfsd_mutex); @@ -556,6 +563,9 @@ nfsd(void *vrqstp) nfsdstats.th_cnt --; out: + if (rqstp->rq_server->sv_nrthreads == 1) + svc_shutdown_net(rqstp->rq_server, &init_net); + /* Release the thread */ svc_exit_thread(rqstp); @@ -668,8 +678,12 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file) int nfsd_pool_stats_release(struct inode *inode, struct file *file) { int ret = seq_release(inode, file); + struct net *net = &init_net; + mutex_lock(&nfsd_mutex); /* this function really, really should have been called svc_put() */ + if (nfsd_serv->sv_nrthreads == 1) + svc_shutdown_net(nfsd_serv, net); svc_destroy(nfsd_serv); mutex_unlock(&nfsd_mutex); return ret; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index e6d542c..b7210f5 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -537,8 +537,6 @@ EXPORT_SYMBOL_GPL(svc_shutdown_net); void svc_destroy(struct svc_serv *serv) { - struct net *net = current->nsproxy->net_ns; - dprintk("svc: svc_destroy(%s, %d)\n", serv->sv_program->pg_name, serv->sv_nrthreads); @@ -553,8 +551,6 @@ svc_destroy(struct svc_serv *serv) del_timer_sync(&serv->sv_temptimer); - svc_shutdown_net(serv, net); - /* * The last user is gone and thus all sockets have to be destroyed to * the point. Check this. -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/3] NFS: hard-code init_net for NFS callback transports 2012-06-18 20:07 3.4.z nfsd backports J. Bruce Fields 2012-06-18 20:07 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced J. Bruce Fields 2012-06-18 20:07 ` [PATCH 2/3] SUNRPC: move per-net operations from svc_destroy() J. Bruce Fields @ 2012-06-18 20:07 ` J. Bruce Fields 2012-06-20 13:27 ` [PATCH 4/3] lockd: hard-code init_net in lockd case as well J. Bruce Fields 2012-06-20 16:35 ` 3.4.z nfsd backports Greg KH 3 siblings, 1 reply; 13+ messages in thread From: J. Bruce Fields @ 2012-06-18 20:07 UTC (permalink / raw) To: stable; +Cc: linux-nfs, Stanislav Kinsbursky, J. Bruce Fields From: Stanislav Kinsbursky <skinsbursky@parallels.com> commit 12918b10d59e975fd5241eef03ef9e6d5ea3dcfe upstream. In case of destroying mount namespace on child reaper exit, nsproxy is zeroed to the point already. So, dereferencing of it is invalid. This patch hard-code "init_net" for all network namespace references for NFS callback services. This will be fixed with proper NFS callback containerization. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/nfs/callback.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index cff3940..38a44c6 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -17,7 +17,6 @@ #include <linux/kthread.h> #include <linux/sunrpc/svcauth_gss.h> #include <linux/sunrpc/bc_xprt.h> -#include <linux/nsproxy.h> #include <net/inet_sock.h> @@ -107,7 +106,7 @@ nfs4_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt) { int ret; - ret = svc_create_xprt(serv, "tcp", xprt->xprt_net, PF_INET, + ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET, nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); if (ret <= 0) goto out_err; @@ -115,7 +114,7 @@ nfs4_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt) dprintk("NFS: Callback listener port = %u (af %u)\n", nfs_callback_tcpport, PF_INET); - ret = svc_create_xprt(serv, "tcp", xprt->xprt_net, PF_INET6, + ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET6, nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); if (ret > 0) { nfs_callback_tcpport6 = ret; @@ -184,7 +183,7 @@ nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt) * fore channel connection. * Returns the input port (0) and sets the svc_serv bc_xprt on success */ - ret = svc_create_xprt(serv, "tcp-bc", xprt->xprt_net, PF_INET, 0, + ret = svc_create_xprt(serv, "tcp-bc", &init_net, PF_INET, 0, SVC_SOCK_ANONYMOUS); if (ret < 0) { rqstp = ERR_PTR(ret); @@ -254,7 +253,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) char svc_name[12]; int ret = 0; int minorversion_setup; - struct net *net = current->nsproxy->net_ns; + struct net *net = &init_net; mutex_lock(&nfs_callback_mutex); if (cb_info->users++ || cb_info->task != NULL) { @@ -330,7 +329,7 @@ void nfs_callback_down(int minorversion) cb_info->users--; if (cb_info->users == 0 && cb_info->task != NULL) { kthread_stop(cb_info->task); - svc_shutdown_net(cb_info->serv, current->nsproxy->net_ns); + svc_shutdown_net(cb_info->serv, &init_net); svc_exit_thread(cb_info->rqst); cb_info->serv = NULL; cb_info->rqst = NULL; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/3] lockd: hard-code init_net in lockd case as well 2012-06-18 20:07 ` [PATCH 3/3] NFS: hard-code init_net for NFS callback transports J. Bruce Fields @ 2012-06-20 13:27 ` J. Bruce Fields 2012-06-20 14:54 ` Greg KH 0 siblings, 1 reply; 13+ messages in thread From: J. Bruce Fields @ 2012-06-20 13:27 UTC (permalink / raw) To: J. Bruce Fields; +Cc: stable, linux-nfs, Stanislav Kinsbursky From: "J. Bruce Fields" <bfields@redhat.com> The previous patch missed lockd_down, which has the same problem. Symptoms were crashes on unmount or reboot. Note this was fixed in a different way upstream. Acked-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> --- fs/lockd/svc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index f1b3cce..c933df4 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -300,7 +300,7 @@ int lockd_up(void) { struct svc_serv *serv; int error = 0; - struct net *net = current->nsproxy->net_ns; + struct net *net = &init_net; struct lockd_net *ln = net_generic(net, lockd_net_id); mutex_lock(&nlmsvc_mutex); @@ -391,7 +391,7 @@ void lockd_down(void) { mutex_lock(&nlmsvc_mutex); - lockd_down_net(current->nsproxy->net_ns); + lockd_down_net(&init_net); if (nlmsvc_users) { if (--nlmsvc_users) goto out; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 4/3] lockd: hard-code init_net in lockd case as well 2012-06-20 13:27 ` [PATCH 4/3] lockd: hard-code init_net in lockd case as well J. Bruce Fields @ 2012-06-20 14:54 ` Greg KH 0 siblings, 0 replies; 13+ messages in thread From: Greg KH @ 2012-06-20 14:54 UTC (permalink / raw) To: J. Bruce Fields; +Cc: J. Bruce Fields, stable, linux-nfs, Stanislav Kinsbursky On Wed, Jun 20, 2012 at 09:27:38AM -0400, J. Bruce Fields wrote: > From: "J. Bruce Fields" <bfields@redhat.com> > > The previous patch missed lockd_down, which has the same problem. > Symptoms were crashes on unmount or reboot. > > Note this was fixed in a different way upstream. > > Acked-by: Stanislav Kinsbursky <skinsbursky@parallels.com> > Signed-off-by: J. Bruce Fields <bfields@redhat.com> > --- > fs/lockd/svc.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) <formletter> This is not the correct way to submit patches for inclusion in the stable kernel tree. Please read Documentation/stable_kernel_rules.txt for how to do this properly. </formletter> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 3.4.z nfsd backports 2012-06-18 20:07 3.4.z nfsd backports J. Bruce Fields ` (2 preceding siblings ...) 2012-06-18 20:07 ` [PATCH 3/3] NFS: hard-code init_net for NFS callback transports J. Bruce Fields @ 2012-06-20 16:35 ` Greg KH 3 siblings, 0 replies; 13+ messages in thread From: Greg KH @ 2012-06-20 16:35 UTC (permalink / raw) To: J. Bruce Fields; +Cc: stable, linux-nfs On Mon, Jun 18, 2012 at 04:07:26PM -0400, J. Bruce Fields wrote: > These three patches are all upstream, but required some conflict > resolution to backport, so I'm sending backported versions. Please resend all of these, with the correct git commit ids. ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 0/3] SUNRPC: separate per-net data creation from service creation @ 2012-04-25 13:37 Stanislav Kinsbursky 2012-04-25 13:37 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced Stanislav Kinsbursky 0 siblings, 1 reply; 13+ messages in thread From: Stanislav Kinsbursky @ 2012-04-25 13:37 UTC (permalink / raw) To: bfields, Trond.Myklebust; +Cc: linux-nfs, linux-kernel, devel This is a cleanup patch set. It will be followed my LockD start/stop cleanup patch set and NFS callback service containerization patch set (yes, I forgot to implement it). Today per-net data is created with service, and then is service is starting in other network namespace. And thus it's destroyed with service too. Moreover, network context for destroying of per-net data is taken from current process. This is correct, but code looks ugly. This patch set separates per-net data allocation from service allocation and destruction. IOW, per-net data have to be destroyed by service users - not service itself. BTW, NFSd code become uglier with this patch set. Sorry. But I assume, that these new ugly parts will be replaced later by NFSd service containerization code. The following series consists of: --- Stanislav Kinsbursky (3): SUNRPC: new svc_bind() routine introduced SUNRPC: check rpcbind clients usage counter before decrement SUNRPC: move per-net operations from svc_destroy() fs/lockd/svc.c | 30 +++++++++++++++++++----------- fs/nfs/callback.c | 11 +++++++++++ fs/nfsd/nfsctl.c | 4 ++++ fs/nfsd/nfssvc.c | 16 ++++++++++++++++ include/linux/sunrpc/svc.h | 1 + net/sunrpc/rpcb_clnt.c | 12 +++++++----- net/sunrpc/svc.c | 23 ++++++++++------------- 7 files changed, 68 insertions(+), 29 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/3] SUNRPC: new svc_bind() routine introduced 2012-04-25 13:37 [PATCH 0/3] SUNRPC: separate per-net data creation from service creation Stanislav Kinsbursky @ 2012-04-25 13:37 ` Stanislav Kinsbursky 0 siblings, 0 replies; 13+ messages in thread From: Stanislav Kinsbursky @ 2012-04-25 13:37 UTC (permalink / raw) To: bfields, Trond.Myklebust; +Cc: linux-nfs, linux-kernel, devel New routine is responsible for service registration in specified network context. The idea is to separate service creation from per-net operations. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> --- fs/lockd/svc.c | 6 ++++++ fs/nfs/callback.c | 8 ++++++++ fs/nfsd/nfssvc.c | 9 +++++++++ include/linux/sunrpc/svc.h | 1 + net/sunrpc/svc.c | 19 ++++++++++--------- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 1ead075..b7e92ed 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -324,6 +324,12 @@ int lockd_up(struct net *net) goto out; } + error = svc_bind(serv, net); + if (error < 0) { + printk(KERN_WARNING "lockd_up: bind service failed\n"); + goto destroy_and_out; + } + error = make_socks(serv, net); if (error < 0) goto destroy_and_out; diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index eb95f50..26b38fb 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -17,6 +17,7 @@ #include <linux/kthread.h> #include <linux/sunrpc/svcauth_gss.h> #include <linux/sunrpc/bc_xprt.h> +#include <linux/nsproxy.h> #include <net/inet_sock.h> @@ -253,6 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) char svc_name[12]; int ret = 0; int minorversion_setup; + struct net *net = current->nsproxy->net_ns; mutex_lock(&nfs_callback_mutex); if (cb_info->users++ || cb_info->task != NULL) { @@ -265,6 +267,12 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) goto out_err; } + ret = svc_bind(serv, net); + if (ret < 0) { + printk(KERN_WARNING "NFS: bind callback service failed\n"); + goto out_err; + } + minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion, serv, xprt, &rqstp, &callback_svc); if (!minorversion_setup) { diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index cb4d51d..0762f3c 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/fs_struct.h> #include <linux/swap.h> +#include <linux/nsproxy.h> #include <linux/sunrpc/stats.h> #include <linux/sunrpc/svcsock.h> @@ -330,6 +331,8 @@ static int nfsd_get_default_max_blksize(void) int nfsd_create_serv(void) { + int error; + WARN_ON(!mutex_is_locked(&nfsd_mutex)); if (nfsd_serv) { svc_get(nfsd_serv); @@ -343,6 +346,12 @@ int nfsd_create_serv(void) if (nfsd_serv == NULL) return -ENOMEM; + error = svc_bind(nfsd_serv, current->nsproxy->net_ns); + if (error < 0) { + svc_destroy(nfsd_serv); + return error; + } + set_max_drc(); do_gettimeofday(&nfssvc_boot); /* record boot time */ return 0; diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 51b29ac..2b43e02 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -416,6 +416,7 @@ struct svc_procedure { */ int svc_rpcb_setup(struct svc_serv *serv, struct net *net); void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); +int svc_bind(struct svc_serv *serv, struct net *net); struct svc_serv *svc_create(struct svc_program *, unsigned int, void (*shutdown)(struct svc_serv *, struct net *net)); struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 4153846..e6d542c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -407,6 +407,14 @@ static int svc_uses_rpcbind(struct svc_serv *serv) return 0; } +int svc_bind(struct svc_serv *serv, struct net *net) +{ + if (!svc_uses_rpcbind(serv)) + return 0; + return svc_rpcb_setup(serv, net); +} +EXPORT_SYMBOL_GPL(svc_bind); + /* * Create an RPC service */ @@ -471,15 +479,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, spin_lock_init(&pool->sp_lock); } - if (svc_uses_rpcbind(serv)) { - if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) { - kfree(serv->sv_pools); - kfree(serv); - return NULL; - } - if (!serv->sv_shutdown) - serv->sv_shutdown = svc_rpcb_cleanup; - } + if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown)) + serv->sv_shutdown = svc_rpcb_cleanup; return serv; } ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-06-25 20:44 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-06-18 20:07 3.4.z nfsd backports J. Bruce Fields 2012-06-18 20:07 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced J. Bruce Fields 2012-06-20 16:34 ` Greg KH 2012-06-20 18:09 ` J. Bruce Fields 2012-06-20 18:18 ` Greg KH 2012-06-25 20:33 ` J. Bruce Fields 2012-06-25 20:44 ` J. Bruce Fields 2012-06-18 20:07 ` [PATCH 2/3] SUNRPC: move per-net operations from svc_destroy() J. Bruce Fields 2012-06-18 20:07 ` [PATCH 3/3] NFS: hard-code init_net for NFS callback transports J. Bruce Fields 2012-06-20 13:27 ` [PATCH 4/3] lockd: hard-code init_net in lockd case as well J. Bruce Fields 2012-06-20 14:54 ` Greg KH 2012-06-20 16:35 ` 3.4.z nfsd backports Greg KH -- strict thread matches above, loose matches on Subject: below -- 2012-04-25 13:37 [PATCH 0/3] SUNRPC: separate per-net data creation from service creation Stanislav Kinsbursky 2012-04-25 13:37 ` [PATCH 1/3] SUNRPC: new svc_bind() routine introduced Stanislav Kinsbursky
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).