diff options
| author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2013-02-01 15:56:12 +0300 | 
|---|---|---|
| committer | J. Bruce Fields <bfields@redhat.com> | 2013-02-15 11:21:00 -0500 | 
| commit | 11f779421a39b86da8a523d97e5fd3477878d44f (patch) | |
| tree | 5a2c01f75d57a1ff23dd0ecec56a378e2b34bb8d /fs/nfsd/nfsctl.c | |
| parent | 1ac8362977b9ec75779170ac3074c7b36ab19b82 (diff) | |
| download | olio-linux-3.10-11f779421a39b86da8a523d97e5fd3477878d44f.tar.xz olio-linux-3.10-11f779421a39b86da8a523d97e5fd3477878d44f.zip  | |
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>
Diffstat (limited to 'fs/nfsd/nfsctl.c')
| -rw-r--r-- | fs/nfsd/nfsctl.c | 46 | 
1 files changed, 33 insertions, 13 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 29c3f0d2546..f6d448e6eb2 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)  	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) @@ -232,7 +233,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)  	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); @@ -317,6 +318,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)  	int len;  	struct auth_domain *dom;  	struct knfsd_fh fh; +	struct net *net = file->f_dentry->d_sb->s_fs_info;  	if (size == 0)  		return -EINVAL; @@ -352,7 +354,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)  	if (!dom)  		return -ENOMEM; -	len = exp_rootfh(&init_net, dom, path, &fh,  maxsize); +	len = exp_rootfh(net, dom, path, &fh,  maxsize);  	auth_domain_put(dom);  	if (len)  		return len; @@ -396,7 +398,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)  {  	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; @@ -447,7 +449,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)  	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(net); @@ -510,7 +512,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)  	unsigned minor;  	ssize_t tlen = 0;  	char *sep; -	struct net *net = &init_net; +	struct net *net = file->f_dentry->d_sb->s_fs_info;  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);  	if (size>0) { @@ -792,7 +794,7 @@ 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)  {  	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); @@ -827,7 +829,7 @@ int nfsd_max_blksize;  static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)  {  	char *mesg = buf; -	struct net *net = &init_net; +	struct net *net = file->f_dentry->d_sb->s_fs_info;  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);  	if (size > 0) { @@ -923,7 +925,8 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,   */  static ssize_t write_leasetime(struct file *file, char *buf, size_t size)  { -	struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); +	struct net *net = file->f_dentry->d_sb->s_fs_info; +	struct nfsd_net *nn = net_generic(net, nfsd_net_id);  	return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);  } @@ -939,7 +942,8 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)   */  static ssize_t write_gracetime(struct file *file, char *buf, size_t size)  { -	struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); +	struct net *net = file->f_dentry->d_sb->s_fs_info; +	struct nfsd_net *nn = net_generic(net, nfsd_net_id);  	return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);  } @@ -995,7 +999,8 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,  static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)  {  	ssize_t rv; -	struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); +	struct net *net = file->f_dentry->d_sb->s_fs_info; +	struct nfsd_net *nn = net_generic(net, nfsd_net_id);  	mutex_lock(&nfsd_mutex);  	rv = __write_recoverydir(file, buf, size, nn); @@ -1037,20 +1042,35 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)  #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  |