aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2013-02-01 07:56:12 -0500
committerJ. Bruce Fields <bfields@redhat.com>2013-02-15 11:21:00 -0500
commit11f779421a39b86da8a523d97e5fd3477878d44f (patch)
tree5a2c01f75d57a1ff23dd0ecec56a378e2b34bb8d
parent1ac8362977b9ec75779170ac3074c7b36ab19b82 (diff)
nfsd: containerize NFSd filesystem
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>
-rw-r--r--fs/nfsd/nfsctl.c46
-rw-r--r--fs/nfsd/nfssvc.c5
2 files changed, 35 insertions, 16 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 29c3f0d25469..f6d448e6eb28 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -220,6 +220,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
220 struct sockaddr *sap = (struct sockaddr *)&address; 220 struct sockaddr *sap = (struct sockaddr *)&address;
221 size_t salen = sizeof(address); 221 size_t salen = sizeof(address);
222 char *fo_path; 222 char *fo_path;
223 struct net *net = file->f_dentry->d_sb->s_fs_info;
223 224
224 /* sanity check */ 225 /* sanity check */
225 if (size == 0) 226 if (size == 0)
@@ -232,7 +233,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
232 if (qword_get(&buf, fo_path, size) < 0) 233 if (qword_get(&buf, fo_path, size) < 0)
233 return -EINVAL; 234 return -EINVAL;
234 235
235 if (rpc_pton(&init_net, fo_path, size, sap, salen) == 0) 236 if (rpc_pton(net, fo_path, size, sap, salen) == 0)
236 return -EINVAL; 237 return -EINVAL;
237 238
238 return nlmsvc_unlock_all_by_ip(sap); 239 return nlmsvc_unlock_all_by_ip(sap);
@@ -317,6 +318,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
317 int len; 318 int len;
318 struct auth_domain *dom; 319 struct auth_domain *dom;
319 struct knfsd_fh fh; 320 struct knfsd_fh fh;
321 struct net *net = file->f_dentry->d_sb->s_fs_info;
320 322
321 if (size == 0) 323 if (size == 0)
322 return -EINVAL; 324 return -EINVAL;
@@ -352,7 +354,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
352 if (!dom) 354 if (!dom)
353 return -ENOMEM; 355 return -ENOMEM;
354 356
355 len = exp_rootfh(&init_net, dom, path, &fh, maxsize); 357 len = exp_rootfh(net, dom, path, &fh, maxsize);
356 auth_domain_put(dom); 358 auth_domain_put(dom);
357 if (len) 359 if (len)
358 return len; 360 return len;
@@ -396,7 +398,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
396{ 398{
397 char *mesg = buf; 399 char *mesg = buf;
398 int rv; 400 int rv;
399 struct net *net = &init_net; 401 struct net *net = file->f_dentry->d_sb->s_fs_info;
400 402
401 if (size > 0) { 403 if (size > 0) {
402 int newthreads; 404 int newthreads;
@@ -447,7 +449,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
447 int len; 449 int len;
448 int npools; 450 int npools;
449 int *nthreads; 451 int *nthreads;
450 struct net *net = &init_net; 452 struct net *net = file->f_dentry->d_sb->s_fs_info;
451 453
452 mutex_lock(&nfsd_mutex); 454 mutex_lock(&nfsd_mutex);
453 npools = nfsd_nrpools(net); 455 npools = nfsd_nrpools(net);
@@ -510,7 +512,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
510 unsigned minor; 512 unsigned minor;
511 ssize_t tlen = 0; 513 ssize_t tlen = 0;
512 char *sep; 514 char *sep;
513 struct net *net = &init_net; 515 struct net *net = file->f_dentry->d_sb->s_fs_info;
514 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 516 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
515 517
516 if (size>0) { 518 if (size>0) {
@@ -792,7 +794,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size,
792static ssize_t write_ports(struct file *file, char *buf, size_t size) 794static ssize_t write_ports(struct file *file, char *buf, size_t size)
793{ 795{
794 ssize_t rv; 796 ssize_t rv;
795 struct net *net = &init_net; 797 struct net *net = file->f_dentry->d_sb->s_fs_info;
796 798
797 mutex_lock(&nfsd_mutex); 799 mutex_lock(&nfsd_mutex);
798 rv = __write_ports(file, buf, size, net); 800 rv = __write_ports(file, buf, size, net);
@@ -827,7 +829,7 @@ int nfsd_max_blksize;
827static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 829static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
828{ 830{
829 char *mesg = buf; 831 char *mesg = buf;
830 struct net *net = &init_net; 832 struct net *net = file->f_dentry->d_sb->s_fs_info;
831 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 833 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
832 834
833 if (size > 0) { 835 if (size > 0) {
@@ -923,7 +925,8 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
923 */ 925 */
924static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 926static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
925{ 927{
926 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 928 struct net *net = file->f_dentry->d_sb->s_fs_info;
929 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
927 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn); 930 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
928} 931}
929 932
@@ -939,7 +942,8 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
939 */ 942 */
940static ssize_t write_gracetime(struct file *file, char *buf, size_t size) 943static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
941{ 944{
942 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 945 struct net *net = file->f_dentry->d_sb->s_fs_info;
946 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
943 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn); 947 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
944} 948}
945 949
@@ -995,7 +999,8 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
995static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 999static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
996{ 1000{
997 ssize_t rv; 1001 ssize_t rv;
998 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 1002 struct net *net = file->f_dentry->d_sb->s_fs_info;
1003 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
999 1004
1000 mutex_lock(&nfsd_mutex); 1005 mutex_lock(&nfsd_mutex);
1001 rv = __write_recoverydir(file, buf, size, nn); 1006 rv = __write_recoverydir(file, buf, size, nn);
@@ -1037,20 +1042,35 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1037#endif 1042#endif
1038 /* last one */ {""} 1043 /* last one */ {""}
1039 }; 1044 };
1040 return simple_fill_super(sb, 0x6e667364, nfsd_files); 1045 struct net *net = data;
1046 int ret;
1047
1048 ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1049 if (ret)
1050 return ret;
1051 sb->s_fs_info = get_net(net);
1052 return 0;
1041} 1053}
1042 1054
1043static struct dentry *nfsd_mount(struct file_system_type *fs_type, 1055static struct dentry *nfsd_mount(struct file_system_type *fs_type,
1044 int flags, const char *dev_name, void *data) 1056 int flags, const char *dev_name, void *data)
1045{ 1057{
1046 return mount_single(fs_type, flags, data, nfsd_fill_super); 1058 return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
1059}
1060
1061static void nfsd_umount(struct super_block *sb)
1062{
1063 struct net *net = sb->s_fs_info;
1064
1065 kill_litter_super(sb);
1066 put_net(net);
1047} 1067}
1048 1068
1049static struct file_system_type nfsd_fs_type = { 1069static struct file_system_type nfsd_fs_type = {
1050 .owner = THIS_MODULE, 1070 .owner = THIS_MODULE,
1051 .name = "nfsd", 1071 .name = "nfsd",
1052 .mount = nfsd_mount, 1072 .mount = nfsd_mount,
1053 .kill_sb = kill_litter_super, 1073 .kill_sb = nfsd_umount,
1054}; 1074};
1055 1075
1056#ifdef CONFIG_PROC_FS 1076#ifdef CONFIG_PROC_FS
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 40cb1cbaba4e..6cee5db72047 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -702,8 +702,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
702int nfsd_pool_stats_open(struct inode *inode, struct file *file) 702int nfsd_pool_stats_open(struct inode *inode, struct file *file)
703{ 703{
704 int ret; 704 int ret;
705 struct net *net = &init_net; 705 struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
706 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
707 706
708 mutex_lock(&nfsd_mutex); 707 mutex_lock(&nfsd_mutex);
709 if (nn->nfsd_serv == NULL) { 708 if (nn->nfsd_serv == NULL) {
@@ -720,7 +719,7 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file)
720int nfsd_pool_stats_release(struct inode *inode, struct file *file) 719int nfsd_pool_stats_release(struct inode *inode, struct file *file)
721{ 720{
722 int ret = seq_release(inode, file); 721 int ret = seq_release(inode, file);
723 struct net *net = &init_net; 722 struct net *net = inode->i_sb->s_fs_info;
724 723
725 mutex_lock(&nfsd_mutex); 724 mutex_lock(&nfsd_mutex);
726 /* this function really, really should have been called svc_put() */ 725 /* this function really, really should have been called svc_put() */