All of lore.kernel.org
 help / color / mirror / Atom feed
* 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

* [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: [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: 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

* 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 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.