|
@@ -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;
|
|
|
+
|
|
|
+ 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;
|
|
|
|
|
|
- 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;
|
|
|
- }
|
|
|
+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
|