From: Greg Kroah-Hartman Date: Mon, 9 Jun 2014 23:49:23 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.14.7~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5797e841236692a316c1fb2ff25d87acb75f2cc4;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches 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 --- 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 index 00000000000..af029af7477 --- /dev/null +++ b/queue-3.4/nfsd-check-passed-socket-s-net-matches-nfsd-superblock-s-one.patch @@ -0,0 +1,89 @@ +From 3064639423c48d6e0eb9ecc27c512a58e38c6c57 Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Wed, 26 Feb 2014 16:50:01 +0300 +Subject: nfsd: check passed socket's net matches NFSd superblock's one + +From: Stanislav Kinsbursky + +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 +Signed-off-by: Stanislav Kinsbursky +Cc: stable@vger.kernel.org +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: adjust context] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..eb04c3644f4 --- /dev/null +++ b/queue-3.4/nfsd-containerize-nfsd-filesystem.patch @@ -0,0 +1,130 @@ +From 11f779421a39b86da8a523d97e5fd3477878d44f Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Fri, 1 Feb 2013 15:56:12 +0300 +Subject: nfsd: containerize NFSd filesystem + +From: Stanislav Kinsbursky + +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 +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: + - export cache not per netns + - NFSD service structure not per netns] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..cb028cf1251 --- /dev/null +++ b/queue-3.4/nfsd-pass-net-to-__write_ports-and-down.patch @@ -0,0 +1,110 @@ +From 081603520b25f7b35ef63a363376a17c36ef74ed Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Mon, 10 Dec 2012 12:19:35 +0300 +Subject: nfsd: pass net to __write_ports() and down + +From: Stanislav Kinsbursky + +commit 081603520b25f7b35ef63a363376a17c36ef74ed upstream. + +Precursor patch. Hard-coded "init_net" will be replaced by proper one in +future. + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: + - adjust context + - add net_ns parameter to __write_ports_delxprt()] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..1698e6781fa --- /dev/null +++ b/queue-3.4/nfsd-pass-net-to-nfsd_create_serv.patch @@ -0,0 +1,77 @@ +From 6777436b0f072fb20a025a73e9b67a35ad8a5451 Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Mon, 10 Dec 2012 12:19:20 +0300 +Subject: nfsd: pass net to nfsd_create_serv() + +From: Stanislav Kinsbursky + +commit 6777436b0f072fb20a025a73e9b67a35ad8a5451 upstream. + +Precursor patch. Hard-coded "init_net" will be replaced by proper one in +future. + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: adjust context] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..6893b2f88d1 --- /dev/null +++ b/queue-3.4/nfsd-pass-net-to-nfsd_init_socks.patch @@ -0,0 +1,65 @@ +From db6e182c17cb1a7069f7f8924721ce58ac05d9a3 Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Mon, 10 Dec 2012 12:19:09 +0300 +Subject: nfsd: pass net to nfsd_init_socks() + +From: Stanislav Kinsbursky + +commit db6e182c17cb1a7069f7f8924721ce58ac05d9a3 upstream. + +Precursor patch. Hard-coded "init_net" will be replaced by proper one in +future. + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +[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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..cd2c3b3bec1 --- /dev/null +++ b/queue-3.4/nfsd-pass-net-to-nfsd_set_nrthreads.patch @@ -0,0 +1,69 @@ +From 3938a0d5eb5effcc89c6909741403f4e6a37252d Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Mon, 10 Dec 2012 12:19:30 +0300 +Subject: nfsd: pass net to nfsd_set_nrthreads() + +From: Stanislav Kinsbursky + +commit 3938a0d5eb5effcc89c6909741403f4e6a37252d upstream. + +Precursor patch. Hard-coded "init_net" will be replaced by proper one in +future. + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: adjust context] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b38b45febac --- /dev/null +++ b/queue-3.4/nfsd-pass-net-to-nfsd_startup-and-nfsd_shutdown.patch @@ -0,0 +1,100 @@ +From db42d1a76a8dfcaba7a2dc9c591fa4e231db22b3 Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Mon, 10 Dec 2012 12:19:14 +0300 +Subject: nfsd: pass net to nfsd_startup() and nfsd_shutdown() + +From: Stanislav Kinsbursky + +commit db42d1a76a8dfcaba7a2dc9c591fa4e231db22b3 upstream. + +Precursor patch. Hard-coded "init_net" will be replaced by proper one in +future. + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +[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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ce324077b50 --- /dev/null +++ b/queue-3.4/nfsd-pass-net-to-nfsd_svc.patch @@ -0,0 +1,71 @@ +From d41a9417cd89a69f58a26935034b4264a2d882d6 Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Mon, 10 Dec 2012 12:19:25 +0300 +Subject: nfsd: pass net to nfsd_svc() + +From: Stanislav Kinsbursky + +commit d41a9417cd89a69f58a26935034b4264a2d882d6 upstream. + +Precursor patch. Hard-coded "init_net" will be replaced by proper one in +future. + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: + - adjust context + - one more parameter(int port) for nfsd_svc()] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..c5a548ab8f5 --- /dev/null +++ b/queue-3.4/nfsd-pass-proper-net-to-nfsd_destroy-from-nfsd-kthreads.patch @@ -0,0 +1,44 @@ +From 88c47666171989ed4c5b1a5687df09511e8c5e35 Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Thu, 6 Dec 2012 18:34:42 +0300 +Subject: nfsd: pass proper net to nfsd_destroy() from NFSd kthreads + +From: Stanislav Kinsbursky + +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 +Signed-off-by: J. Bruce Fields +[wengmeiling: backport to 3.4: adjust context] +Signed-off-by: Weng Meiling +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-3.4/series b/queue-3.4/series index 56e67883d28..7ca9fd43f8b 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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