diff options
Diffstat (limited to 'fs/nfs/dns_resolve.c')
| -rw-r--r-- | fs/nfs/dns_resolve.c | 96 | 
1 files changed, 63 insertions, 33 deletions
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c index 3cbf4b88f82..9aea78ab86a 100644 --- a/fs/nfs/dns_resolve.c +++ b/fs/nfs/dns_resolve.c @@ -11,7 +11,7 @@  #include <linux/sunrpc/clnt.h>  #include <linux/dns_resolver.h> -ssize_t nfs_dns_resolve_name(char *name, size_t namelen, +ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,  		struct sockaddr *sa, size_t salen)  {  	ssize_t ret; @@ -43,12 +43,11 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen,  #include "dns_resolve.h"  #include "cache_lib.h" +#include "netns.h"  #define NFS_DNS_HASHBITS 4  #define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS) -static struct cache_head *nfs_dns_table[NFS_DNS_HASHTBL_SIZE]; -  struct nfs_dns_ent {  	struct cache_head h; @@ -259,21 +258,6 @@ out:  	return ret;  } -static struct cache_detail nfs_dns_resolve = { -	.owner = THIS_MODULE, -	.hash_size = NFS_DNS_HASHTBL_SIZE, -	.hash_table = nfs_dns_table, -	.name = "dns_resolve", -	.cache_put = nfs_dns_ent_put, -	.cache_upcall = nfs_dns_upcall, -	.cache_parse = nfs_dns_parse, -	.cache_show = nfs_dns_show, -	.match = nfs_dns_match, -	.init = nfs_dns_ent_init, -	.update = nfs_dns_ent_update, -	.alloc = nfs_dns_ent_alloc, -}; -  static int do_cache_lookup(struct cache_detail *cd,  		struct nfs_dns_ent *key,  		struct nfs_dns_ent **item, @@ -336,8 +320,8 @@ out:  	return ret;  } -ssize_t nfs_dns_resolve_name(char *name, size_t namelen, -		struct sockaddr *sa, size_t salen) +ssize_t nfs_dns_resolve_name(struct net *net, char *name, +		size_t namelen, struct sockaddr *sa, size_t salen)  {  	struct nfs_dns_ent key = {  		.hostname = name, @@ -345,37 +329,83 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen,  	};  	struct nfs_dns_ent *item = NULL;  	ssize_t ret; +	struct nfs_net *nn = net_generic(net, nfs_net_id); -	ret = do_cache_lookup_wait(&nfs_dns_resolve, &key, &item); +	ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item);  	if (ret == 0) {  		if (salen >= item->addrlen) {  			memcpy(sa, &item->addr, item->addrlen);  			ret = item->addrlen;  		} else  			ret = -EOVERFLOW; -		cache_put(&item->h, &nfs_dns_resolve); +		cache_put(&item->h, nn->nfs_dns_resolve);  	} else if (ret == -ENOENT)  		ret = -ESRCH;  	return ret;  } -int nfs_dns_resolver_init(void) +int nfs_dns_resolver_cache_init(struct net *net)  { -	int err; +	int err = -ENOMEM; +	struct nfs_net *nn = net_generic(net, nfs_net_id); +	struct cache_detail *cd; +	struct cache_head **tbl; -	nfs_cache_init(&nfs_dns_resolve); -	err = nfs_cache_register_net(&init_net, &nfs_dns_resolve); -	if (err) { -		nfs_cache_destroy(&nfs_dns_resolve); -		return err; -	} +	cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL); +	if (cd == NULL) +		goto err_cd; + +	tbl = kzalloc(NFS_DNS_HASHTBL_SIZE * sizeof(struct cache_head *), +			GFP_KERNEL); +	if (tbl == NULL) +		goto err_tbl; + +	cd->owner = THIS_MODULE, +	cd->hash_size = NFS_DNS_HASHTBL_SIZE, +	cd->hash_table = tbl, +	cd->name = "dns_resolve", +	cd->cache_put = nfs_dns_ent_put, +	cd->cache_upcall = nfs_dns_upcall, +	cd->cache_parse = nfs_dns_parse, +	cd->cache_show = nfs_dns_show, +	cd->match = nfs_dns_match, +	cd->init = nfs_dns_ent_init, +	cd->update = nfs_dns_ent_update, +	cd->alloc = nfs_dns_ent_alloc, + +	nfs_cache_init(cd); +	err = nfs_cache_register_net(net, cd); +	if (err) +		goto err_reg; +	nn->nfs_dns_resolve = cd; +	return 0; + +err_reg: +	nfs_cache_destroy(cd); +	kfree(cd->hash_table); +err_tbl: +	kfree(cd); +err_cd: +	return err; +} + +void nfs_dns_resolver_cache_destroy(struct net *net) +{ +	struct nfs_net *nn = net_generic(net, nfs_net_id); +	struct cache_detail *cd = nn->nfs_dns_resolve; + +	nfs_cache_unregister_net(net, cd); +	nfs_cache_destroy(cd); +	kfree(cd->hash_table); +	kfree(cd); +} + +int nfs_dns_resolver_init(void) +{  	return 0;  }  void nfs_dns_resolver_destroy(void)  { -	nfs_cache_unregister_net(&init_net, &nfs_dns_resolve); -	nfs_cache_destroy(&nfs_dns_resolve);  } -  #endif  |