]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jun 2014 23:49:23 +0000 (16:49 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jun 2014 23:49:23 +0000 (16:49 -0700)
added patches:
nfsd-check-passed-socket-s-net-matches-nfsd-superblock-s-one.patch
nfsd-containerize-nfsd-filesystem.patch
nfsd-pass-net-to-__write_ports-and-down.patch
nfsd-pass-net-to-nfsd_create_serv.patch
nfsd-pass-net-to-nfsd_init_socks.patch
nfsd-pass-net-to-nfsd_set_nrthreads.patch
nfsd-pass-net-to-nfsd_startup-and-nfsd_shutdown.patch
nfsd-pass-net-to-nfsd_svc.patch
nfsd-pass-proper-net-to-nfsd_destroy-from-nfsd-kthreads.patch

queue-3.4/nfsd-check-passed-socket-s-net-matches-nfsd-superblock-s-one.patch [new file with mode: 0644]
queue-3.4/nfsd-containerize-nfsd-filesystem.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-net-to-__write_ports-and-down.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-net-to-nfsd_create_serv.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-net-to-nfsd_init_socks.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-net-to-nfsd_set_nrthreads.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-net-to-nfsd_startup-and-nfsd_shutdown.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-net-to-nfsd_svc.patch [new file with mode: 0644]
queue-3.4/nfsd-pass-proper-net-to-nfsd_destroy-from-nfsd-kthreads.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/nfsd-check-passed-socket-s-net-matches-nfsd-superblock-s-one.patch b/queue-3.4/nfsd-check-passed-socket-s-net-matches-nfsd-superblock-s-one.patch
new file mode 100644 (file)
index 0000000..af029af
--- /dev/null
@@ -0,0 +1,89 @@
+From 3064639423c48d6e0eb9ecc27c512a58e38c6c57 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Wed, 26 Feb 2014 16:50:01 +0300
+Subject: nfsd: check passed socket's net matches NFSd superblock's one
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 3064639423c48d6e0eb9ecc27c512a58e38c6c57 upstream.
+
+There could be a case, when NFSd file system is mounted in network, different
+to socket's one, like below:
+
+"ip netns exec" creates new network and mount namespace, which duplicates NFSd
+mount point, created in init_net context. And thus NFS server stop in nested
+network context leads to RPCBIND client destruction in init_net.
+Then, on NFSd start in nested network context, rpc.nfsd process creates socket
+in nested net and passes it into "write_ports", which leads to RPCBIND sockets
+creation in init_net context because of the same reason (NFSd monut point was
+created in init_net context). An attempt to register passed socket in nested
+net leads to panic, because no RPCBIND client present in nexted network
+namespace.
+
+This patch add check that passed socket's net matches NFSd superblock's one.
+And returns -EINVAL error to user psace otherwise.
+
+v2: Put socket on exit.
+
+Reported-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4: adjust context]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfsctl.c               |    5 +++++
+ include/linux/sunrpc/svcsock.h |    1 +
+ net/sunrpc/svcsock.c           |   16 ++++++++++++++++
+ 3 files changed, 22 insertions(+)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -660,6 +660,11 @@ static ssize_t __write_ports_addfd(char
+       if (err != 0 || fd < 0)
+               return -EINVAL;
++      if (svc_alien_sock(net, fd)) {
++              printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
++              return -EINVAL;
++      }
++
+       err = nfsd_create_serv(net);
+       if (err != 0)
+               return err;
+--- a/include/linux/sunrpc/svcsock.h
++++ b/include/linux/sunrpc/svcsock.h
+@@ -42,6 +42,7 @@ void         svc_sock_update_bufs(struct svc_se
+ int           svc_sock_names(struct svc_serv *serv, char *buf,
+                                       const size_t buflen,
+                                       const char *toclose);
++bool          svc_alien_sock(struct net *net, int fd);
+ int           svc_addsock(struct svc_serv *serv, const int fd,
+                                       char *name_return, const size_t len);
+ void          svc_init_xprt_sock(void);
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -1441,6 +1441,22 @@ static struct svc_sock *svc_setup_socket
+       return svsk;
+ }
++bool svc_alien_sock(struct net *net, int fd)
++{
++      int err;
++      struct socket *sock = sockfd_lookup(fd, &err);
++      bool ret = false;
++
++      if (!sock)
++              goto out;
++      if (sock_net(sock->sk) != net)
++              ret = true;
++      sockfd_put(sock);
++out:
++      return ret;
++}
++EXPORT_SYMBOL_GPL(svc_alien_sock);
++
+ /**
+  * svc_addsock - add a listener socket to an RPC service
+  * @serv: pointer to RPC service to which to add a new listener
diff --git a/queue-3.4/nfsd-containerize-nfsd-filesystem.patch b/queue-3.4/nfsd-containerize-nfsd-filesystem.patch
new file mode 100644 (file)
index 0000000..eb04c36
--- /dev/null
@@ -0,0 +1,130 @@
+From 11f779421a39b86da8a523d97e5fd3477878d44f Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Fri, 1 Feb 2013 15:56:12 +0300
+Subject: nfsd: containerize NFSd filesystem
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+note: this backport is just for the null pointer problem when
+start nfsd in none init netns. The nfsd is still not containerized.
+
+commit 11f779421a39b86da8a523d97e5fd3477878d44f upstream.
+
+This patch makes NFSD file system superblock to be created per net.
+This makes possible to get proper network namespace from superblock instead of
+using hard-coded "init_net".
+
+Note: NFSd fs super-block holds network namespace. This garantees, that
+network namespace won't disappear from underneath of it.
+This, obviously, means, that in case of kill of a container's "init" (which is not a mount
+namespace, but network namespace creator) netowrk namespace won't be
+destroyed.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4:
+ - export cache not per netns
+ - NFSD service structure not per netns]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfsctl.c |   30 +++++++++++++++++++++++-------
+ fs/nfsd/nfssvc.c |    2 +-
+ 2 files changed, 24 insertions(+), 8 deletions(-)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -213,6 +213,7 @@ static ssize_t write_unlock_ip(struct fi
+       struct sockaddr *sap = (struct sockaddr *)&address;
+       size_t salen = sizeof(address);
+       char *fo_path;
++      struct net *net = file->f_dentry->d_sb->s_fs_info;
+       /* sanity check */
+       if (size == 0)
+@@ -225,7 +226,7 @@ static ssize_t write_unlock_ip(struct fi
+       if (qword_get(&buf, fo_path, size) < 0)
+               return -EINVAL;
+-      if (rpc_pton(&init_net, fo_path, size, sap, salen) == 0)
++      if (rpc_pton(net, fo_path, size, sap, salen) == 0)
+               return -EINVAL;
+       return nlmsvc_unlock_all_by_ip(sap);
+@@ -389,7 +390,7 @@ static ssize_t write_threads(struct file
+ {
+       char *mesg = buf;
+       int rv;
+-      struct net *net = &init_net;
++      struct net *net = file->f_dentry->d_sb->s_fs_info;
+       if (size > 0) {
+               int newthreads;
+@@ -440,7 +441,7 @@ static ssize_t write_pool_threads(struct
+       int len;
+       int npools;
+       int *nthreads;
+-      struct net *net = &init_net;
++      struct net *net = file->f_dentry->d_sb->s_fs_info;
+       mutex_lock(&nfsd_mutex);
+       npools = nfsd_nrpools();
+@@ -857,7 +858,7 @@ static ssize_t __write_ports(struct file
+ static ssize_t write_ports(struct file *file, char *buf, size_t size)
+ {
+       ssize_t rv;
+-      struct net *net = &init_net;
++      struct net *net = file->f_dentry->d_sb->s_fs_info;
+       mutex_lock(&nfsd_mutex);
+       rv = __write_ports(file, buf, size, net);
+@@ -1095,20 +1096,35 @@ static int nfsd_fill_super(struct super_
+ #endif
+               /* last one */ {""}
+       };
+-      return simple_fill_super(sb, 0x6e667364, nfsd_files);
++      struct net *net = data;
++      int ret;
++
++      ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
++      if (ret)
++              return ret;
++      sb->s_fs_info = get_net(net);
++      return 0;
+ }
+ static struct dentry *nfsd_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
+ {
+-      return mount_single(fs_type, flags, data, nfsd_fill_super);
++      return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
++}
++
++static void nfsd_umount(struct super_block *sb)
++{
++      struct net *net = sb->s_fs_info;
++
++      kill_litter_super(sb);
++      put_net(net);
+ }
+ static struct file_system_type nfsd_fs_type = {
+       .owner          = THIS_MODULE,
+       .name           = "nfsd",
+       .mount          = nfsd_mount,
+-      .kill_sb        = kill_litter_super,
++      .kill_sb        = nfsd_umount,
+ };
+ #ifdef CONFIG_PROC_FS
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -670,7 +670,7 @@ int nfsd_pool_stats_open(struct inode *i
+ int nfsd_pool_stats_release(struct inode *inode, struct file *file)
+ {
+       int ret = seq_release(inode, file);
+-      struct net *net = &init_net;
++      struct net *net = inode->i_sb->s_fs_info;
+       mutex_lock(&nfsd_mutex);
+       /* this function really, really should have been called svc_put() */
diff --git a/queue-3.4/nfsd-pass-net-to-__write_ports-and-down.patch b/queue-3.4/nfsd-pass-net-to-__write_ports-and-down.patch
new file mode 100644 (file)
index 0000000..cb028cf
--- /dev/null
@@ -0,0 +1,110 @@
+From 081603520b25f7b35ef63a363376a17c36ef74ed Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Mon, 10 Dec 2012 12:19:35 +0300
+Subject: nfsd: pass net to __write_ports() and down
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 081603520b25f7b35ef63a363376a17c36ef74ed upstream.
+
+Precursor patch. Hard-coded "init_net" will be replaced by proper one in
+future.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4:
+ - adjust context
+ - add net_ns parameter to __write_ports_delxprt()]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfsctl.c |   22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -650,11 +650,10 @@ static ssize_t __write_ports_names(char
+  * a socket of a supported family/protocol, and we use it as an
+  * nfsd listener.
+  */
+-static ssize_t __write_ports_addfd(char *buf)
++static ssize_t __write_ports_addfd(char *buf, struct net *net)
+ {
+       char *mesg = buf;
+       int fd, err;
+-      struct net *net = &init_net;
+       err = get_int(&mesg, &fd);
+       if (err != 0 || fd < 0)
+@@ -698,12 +697,11 @@ static ssize_t __write_ports_delfd(char
+  * A transport listener is added by writing it's transport name and
+  * a port number.
+  */
+-static ssize_t __write_ports_addxprt(char *buf)
++static ssize_t __write_ports_addxprt(char *buf, struct net *net)
+ {
+       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;
+@@ -743,7 +741,7 @@ out_err:
+  * A transport listener is removed by writing a "-", it's transport
+  * name, and it's port number.
+  */
+-static ssize_t __write_ports_delxprt(char *buf)
++static ssize_t __write_ports_delxprt(char *buf, struct net *net)
+ {
+       struct svc_xprt *xprt;
+       char transport[16];
+@@ -755,7 +753,7 @@ static ssize_t __write_ports_delxprt(cha
+       if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL)
+               return -EINVAL;
+-      xprt = svc_find_xprt(nfsd_serv, transport, &init_net, AF_UNSPEC, port);
++      xprt = svc_find_xprt(nfsd_serv, transport, net, AF_UNSPEC, port);
+       if (xprt == NULL)
+               return -ENOTCONN;
+@@ -764,22 +762,23 @@ static ssize_t __write_ports_delxprt(cha
+       return 0;
+ }
+-static ssize_t __write_ports(struct file *file, char *buf, size_t size)
++static ssize_t __write_ports(struct file *file, char *buf, size_t size,
++                              struct net *net)
+ {
+       if (size == 0)
+               return __write_ports_names(buf);
+       if (isdigit(buf[0]))
+-              return __write_ports_addfd(buf);
++              return __write_ports_addfd(buf, net);
+       if (buf[0] == '-' && isdigit(buf[1]))
+               return __write_ports_delfd(buf);
+       if (isalpha(buf[0]))
+-              return __write_ports_addxprt(buf);
++              return __write_ports_addxprt(buf, net);
+       if (buf[0] == '-' && isalpha(buf[1]))
+-              return __write_ports_delxprt(buf);
++              return __write_ports_delxprt(buf, net);
+       return -EINVAL;
+ }
+@@ -858,9 +857,10 @@ static ssize_t __write_ports(struct file
+ static ssize_t write_ports(struct file *file, char *buf, size_t size)
+ {
+       ssize_t rv;
++      struct net *net = &init_net;
+       mutex_lock(&nfsd_mutex);
+-      rv = __write_ports(file, buf, size);
++      rv = __write_ports(file, buf, size, net);
+       mutex_unlock(&nfsd_mutex);
+       return rv;
+ }
diff --git a/queue-3.4/nfsd-pass-net-to-nfsd_create_serv.patch b/queue-3.4/nfsd-pass-net-to-nfsd_create_serv.patch
new file mode 100644 (file)
index 0000000..1698e67
--- /dev/null
@@ -0,0 +1,77 @@
+From 6777436b0f072fb20a025a73e9b67a35ad8a5451 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Mon, 10 Dec 2012 12:19:20 +0300
+Subject: nfsd: pass net to nfsd_create_serv()
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 6777436b0f072fb20a025a73e9b67a35ad8a5451 upstream.
+
+Precursor patch. Hard-coded "init_net" will be replaced by proper one in
+future.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4: adjust context]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfsctl.c |    4 ++--
+ fs/nfsd/nfsd.h   |    2 +-
+ fs/nfsd/nfssvc.c |    5 ++---
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -657,7 +657,7 @@ static ssize_t __write_ports_addfd(char
+       if (err != 0 || fd < 0)
+               return -EINVAL;
+-      err = nfsd_create_serv();
++      err = nfsd_create_serv(net);
+       if (err != 0)
+               return err;
+@@ -708,7 +708,7 @@ static ssize_t __write_ports_addxprt(cha
+       if (port < 1 || port > USHRT_MAX)
+               return -EINVAL;
+-      err = nfsd_create_serv();
++      err = nfsd_create_serv(net);
+       if (err != 0)
+               return err;
+--- a/fs/nfsd/nfsd.h
++++ b/fs/nfsd/nfsd.h
+@@ -101,7 +101,7 @@ enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD
+ int nfsd_vers(int vers, enum vers_op change);
+ int nfsd_minorversion(u32 minorversion, enum vers_op change);
+ void nfsd_reset_versions(void);
+-int nfsd_create_serv(void);
++int nfsd_create_serv(struct net *net);
+ extern int nfsd_max_blksize;
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -326,10 +326,9 @@ static int nfsd_get_default_max_blksize(
+       return ret;
+ }
+-int nfsd_create_serv(void)
++int nfsd_create_serv(struct net *net)
+ {
+       int error;
+-      struct net *net = &init_net;
+       WARN_ON(!mutex_is_locked(&nfsd_mutex));
+       if (nfsd_serv) {
+@@ -451,7 +450,7 @@ nfsd_svc(unsigned short port, int nrserv
+       if (nrservs == 0 && nfsd_serv == NULL)
+               goto out;
+-      error = nfsd_create_serv();
++      error = nfsd_create_serv(net);
+       if (error)
+               goto out;
diff --git a/queue-3.4/nfsd-pass-net-to-nfsd_init_socks.patch b/queue-3.4/nfsd-pass-net-to-nfsd_init_socks.patch
new file mode 100644 (file)
index 0000000..6893b2f
--- /dev/null
@@ -0,0 +1,65 @@
+From db6e182c17cb1a7069f7f8924721ce58ac05d9a3 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Mon, 10 Dec 2012 12:19:09 +0300
+Subject: nfsd: pass net to nfsd_init_socks()
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit db6e182c17cb1a7069f7f8924721ce58ac05d9a3 upstream.
+
+Precursor patch. Hard-coded "init_net" will be replaced by proper one in
+future.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4:
+ - adjust context
+ - one more parameter(int port) for nfsd_init_socks()
+ - net initialization in nfsd_startup()]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfssvc.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -182,18 +182,18 @@ int nfsd_nrthreads(void)
+       return rv;
+ }
+-static int nfsd_init_socks(int port)
++static int nfsd_init_socks(int port, struct net *net)
+ {
+       int error;
+       if (!list_empty(&nfsd_serv->sv_permsocks))
+               return 0;
+-      error = svc_create_xprt(nfsd_serv, "udp", &init_net, PF_INET, port,
++      error = svc_create_xprt(nfsd_serv, "udp", net, PF_INET, port,
+                                       SVC_SOCK_DEFAULTS);
+       if (error < 0)
+               return error;
+-      error = svc_create_xprt(nfsd_serv, "tcp", &init_net, PF_INET, port,
++      error = svc_create_xprt(nfsd_serv, "tcp", net, PF_INET, port,
+                                       SVC_SOCK_DEFAULTS);
+       if (error < 0)
+               return error;
+@@ -206,6 +206,7 @@ static bool nfsd_up = false;
+ static int nfsd_startup(unsigned short port, int nrservs)
+ {
+       int ret;
++      struct net *net = &init_net;
+       if (nfsd_up)
+               return 0;
+@@ -217,7 +218,7 @@ static int nfsd_startup(unsigned short p
+       ret = nfsd_racache_init(2*nrservs);
+       if (ret)
+               return ret;
+-      ret = nfsd_init_socks(port);
++      ret = nfsd_init_socks(port, net);
+       if (ret)
+               goto out_racache;
+       ret = lockd_up(&init_net);
diff --git a/queue-3.4/nfsd-pass-net-to-nfsd_set_nrthreads.patch b/queue-3.4/nfsd-pass-net-to-nfsd_set_nrthreads.patch
new file mode 100644 (file)
index 0000000..cd2c3b3
--- /dev/null
@@ -0,0 +1,69 @@
+From 3938a0d5eb5effcc89c6909741403f4e6a37252d Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Mon, 10 Dec 2012 12:19:30 +0300
+Subject: nfsd: pass net to nfsd_set_nrthreads()
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 3938a0d5eb5effcc89c6909741403f4e6a37252d upstream.
+
+Precursor patch. Hard-coded "init_net" will be replaced by proper one in
+future.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4: adjust context]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfsctl.c |    3 ++-
+ fs/nfsd/nfsd.h   |    2 +-
+ fs/nfsd/nfssvc.c |    3 +--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -440,6 +440,7 @@ static ssize_t write_pool_threads(struct
+       int len;
+       int npools;
+       int *nthreads;
++      struct net *net = &init_net;
+       mutex_lock(&nfsd_mutex);
+       npools = nfsd_nrpools();
+@@ -470,7 +471,7 @@ static ssize_t write_pool_threads(struct
+                       if (nthreads[i] < 0)
+                               goto out_free;
+               }
+-              rv = nfsd_set_nrthreads(i, nthreads);
++              rv = nfsd_set_nrthreads(i, nthreads, net);
+               if (rv)
+                       goto out_free;
+       }
+--- a/fs/nfsd/nfsd.h
++++ b/fs/nfsd/nfsd.h
+@@ -71,7 +71,7 @@ int          nfsd_dispatch(struct svc_rqst *rqst
+ int           nfsd_nrthreads(void);
+ int           nfsd_nrpools(void);
+ int           nfsd_get_nrthreads(int n, int *);
+-int           nfsd_set_nrthreads(int n, int *);
++int           nfsd_set_nrthreads(int n, int *, struct net *);
+ static inline void nfsd_destroy(struct net *net)
+ {
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -374,12 +374,11 @@ int nfsd_get_nrthreads(int n, int *nthre
+       return 0;
+ }
+-int nfsd_set_nrthreads(int n, int *nthreads)
++int nfsd_set_nrthreads(int n, int *nthreads, struct net *net)
+ {
+       int i = 0;
+       int tot = 0;
+       int err = 0;
+-      struct net *net = &init_net;
+       WARN_ON(!mutex_is_locked(&nfsd_mutex));
diff --git a/queue-3.4/nfsd-pass-net-to-nfsd_startup-and-nfsd_shutdown.patch b/queue-3.4/nfsd-pass-net-to-nfsd_startup-and-nfsd_shutdown.patch
new file mode 100644 (file)
index 0000000..b38b45f
--- /dev/null
@@ -0,0 +1,100 @@
+From db42d1a76a8dfcaba7a2dc9c591fa4e231db22b3 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Mon, 10 Dec 2012 12:19:14 +0300
+Subject: nfsd: pass net to nfsd_startup() and nfsd_shutdown()
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit db42d1a76a8dfcaba7a2dc9c591fa4e231db22b3 upstream.
+
+Precursor patch. Hard-coded "init_net" will be replaced by proper one in
+future.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4:
+ - adjust context
+ - one more parameter(int port) for nfsd_startup()
+ - no net ns initialization in nfsd_shutdown()
+ - pass @net to lockd_up() in nfsd_startup()
+ - pass @net to lockd_down() in nfsd_shutdown()]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfssvc.c |   17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -203,10 +203,9 @@ static int nfsd_init_socks(int port, str
+ static bool nfsd_up = false;
+-static int nfsd_startup(unsigned short port, int nrservs)
++static int nfsd_startup(unsigned short port, int nrservs, struct net *net)
+ {
+       int ret;
+-      struct net *net = &init_net;
+       if (nfsd_up)
+               return 0;
+@@ -221,7 +220,7 @@ static int nfsd_startup(unsigned short p
+       ret = nfsd_init_socks(port, net);
+       if (ret)
+               goto out_racache;
+-      ret = lockd_up(&init_net);
++      ret = lockd_up(net);
+       if (ret)
+               goto out_racache;
+       ret = nfs4_state_start();
+@@ -230,13 +229,13 @@ static int nfsd_startup(unsigned short p
+       nfsd_up = true;
+       return 0;
+ out_lockd:
+-      lockd_down(&init_net);
++      lockd_down(net);
+ out_racache:
+       nfsd_racache_shutdown();
+       return ret;
+ }
+-static void nfsd_shutdown(void)
++static void nfsd_shutdown(struct net *net)
+ {
+       /*
+        * write_ports can create the server without actually starting
+@@ -247,14 +246,14 @@ static void nfsd_shutdown(void)
+       if (!nfsd_up)
+               return;
+       nfs4_state_shutdown();
+-      lockd_down(&init_net);
++      lockd_down(net);
+       nfsd_racache_shutdown();
+       nfsd_up = false;
+ }
+ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
+ {
+-      nfsd_shutdown();
++      nfsd_shutdown(net);
+       svc_rpcb_cleanup(serv, net);
+@@ -458,7 +457,7 @@ nfsd_svc(unsigned short port, int nrserv
+       nfsd_up_before = nfsd_up;
+-      error = nfsd_startup(port, nrservs);
++      error = nfsd_startup(port, nrservs, net);
+       if (error)
+               goto out_destroy;
+       error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
+@@ -471,7 +470,7 @@ nfsd_svc(unsigned short port, int nrserv
+       error = nfsd_serv->sv_nrthreads - 1;
+ out_shutdown:
+       if (error < 0 && !nfsd_up_before)
+-              nfsd_shutdown();
++              nfsd_shutdown(net);
+ out_destroy:
+       nfsd_destroy(net);              /* Release server */
+ out:
diff --git a/queue-3.4/nfsd-pass-net-to-nfsd_svc.patch b/queue-3.4/nfsd-pass-net-to-nfsd_svc.patch
new file mode 100644 (file)
index 0000000..ce32407
--- /dev/null
@@ -0,0 +1,71 @@
+From d41a9417cd89a69f58a26935034b4264a2d882d6 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Mon, 10 Dec 2012 12:19:25 +0300
+Subject: nfsd: pass net to nfsd_svc()
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit d41a9417cd89a69f58a26935034b4264a2d882d6 upstream.
+
+Precursor patch. Hard-coded "init_net" will be replaced by proper one in
+future.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4:
+ - adjust context
+ - one more parameter(int port) for nfsd_svc()]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfsctl.c |    4 +++-
+ fs/nfsd/nfsd.h   |    2 +-
+ fs/nfsd/nfssvc.c |    3 +--
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -389,6 +389,8 @@ static ssize_t write_threads(struct file
+ {
+       char *mesg = buf;
+       int rv;
++      struct net *net = &init_net;
++
+       if (size > 0) {
+               int newthreads;
+               rv = get_int(&mesg, &newthreads);
+@@ -396,7 +398,7 @@ static ssize_t write_threads(struct file
+                       return rv;
+               if (newthreads < 0)
+                       return -EINVAL;
+-              rv = nfsd_svc(NFS_PORT, newthreads);
++              rv = nfsd_svc(NFS_PORT, newthreads, net);
+               if (rv < 0)
+                       return rv;
+       } else
+--- a/fs/nfsd/nfsd.h
++++ b/fs/nfsd/nfsd.h
+@@ -65,7 +65,7 @@ extern const struct seq_operations nfs_e
+ /*
+  * Function prototypes.
+  */
+-int           nfsd_svc(unsigned short port, int nrservs);
++int           nfsd_svc(unsigned short port, int nrservs, struct net *net);
+ int           nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
+ int           nfsd_nrthreads(void);
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -434,11 +434,10 @@ int nfsd_set_nrthreads(int n, int *nthre
+  * this is the first time nrservs is nonzero.
+  */
+ int
+-nfsd_svc(unsigned short port, int nrservs)
++nfsd_svc(unsigned short port, int nrservs, struct net *net)
+ {
+       int     error;
+       bool    nfsd_up_before;
+-      struct net *net = &init_net;
+       mutex_lock(&nfsd_mutex);
+       dprintk("nfsd: creating service\n");
diff --git a/queue-3.4/nfsd-pass-proper-net-to-nfsd_destroy-from-nfsd-kthreads.patch b/queue-3.4/nfsd-pass-proper-net-to-nfsd_destroy-from-nfsd-kthreads.patch
new file mode 100644 (file)
index 0000000..c5a548a
--- /dev/null
@@ -0,0 +1,44 @@
+From 88c47666171989ed4c5b1a5687df09511e8c5e35 Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Thu, 6 Dec 2012 18:34:42 +0300
+Subject: nfsd: pass proper net to nfsd_destroy() from NFSd kthreads
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 88c47666171989ed4c5b1a5687df09511e8c5e35 upstream.
+
+Since NFSd service is per-net now, we have to pass proper network
+context in nfsd_shutdown() from NFSd kthreads.
+
+The simplest way I found is to get proper net from one of transports
+with permanent sockets.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+[wengmeiling: backport to 3.4: adjust context]
+Signed-off-by: Weng Meiling <wengmeiling.weng@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfsd/nfssvc.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -483,6 +483,8 @@ static int
+ nfsd(void *vrqstp)
+ {
+       struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
++      struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list);
++      struct net *net = perm_sock->xpt_net;
+       int err, preverr = 0;
+       /* Lock module and set up kernel thread */
+@@ -557,7 +559,7 @@ out:
+       /* Release the thread */
+       svc_exit_thread(rqstp);
+-      nfsd_destroy(&init_net);
++      nfsd_destroy(net);
+       /* Release module */
+       mutex_unlock(&nfsd_mutex);
index 56e67883d288c542a4439da4dff488aab411401f..7ca9fd43f8b7320af4c6c6af75400b2c62181f51 100644 (file)
@@ -51,3 +51,12 @@ virtio-blk-don-t-free-ida-when-disk-is-in-use.patch
 virtio_console-fix-uapi-header.patch
 virtio-console-rename-cvq_lock-to-c_ivq_lock.patch
 virtio-console-add-locking-around-c_ovq-operations.patch
+nfsd-pass-net-to-nfsd_init_socks.patch
+nfsd-pass-net-to-nfsd_startup-and-nfsd_shutdown.patch
+nfsd-pass-net-to-nfsd_create_serv.patch
+nfsd-pass-net-to-nfsd_svc.patch
+nfsd-pass-net-to-nfsd_set_nrthreads.patch
+nfsd-pass-net-to-__write_ports-and-down.patch
+nfsd-pass-proper-net-to-nfsd_destroy-from-nfsd-kthreads.patch
+nfsd-containerize-nfsd-filesystem.patch
+nfsd-check-passed-socket-s-net-matches-nfsd-superblock-s-one.patch